diff --git a/CompressionEntity/src/IfswConversions.c b/CompressionEntity/src/IfswConversions.c new file mode 120000 index 0000000000000000000000000000000000000000..b61b15f15dacbf2d12fa035977840b6ceb4ca08c --- /dev/null +++ b/CompressionEntity/src/IfswConversions.c @@ -0,0 +1 @@ +../../CrIa/src/IfswConversions.c \ No newline at end of file diff --git a/CompressionEntity/src/IfswConversions.h b/CompressionEntity/src/IfswConversions.h new file mode 120000 index 0000000000000000000000000000000000000000..a2674b8bb1759871048b6c7458b5a46875777abe --- /dev/null +++ b/CompressionEntity/src/IfswConversions.h @@ -0,0 +1 @@ +../../CrIa/src/IfswConversions.h \ No newline at end of file diff --git a/CompressionEntity/src/IfswMath.c b/CompressionEntity/src/IfswMath.c new file mode 120000 index 0000000000000000000000000000000000000000..3225fdc563f7e7c337cc3e844c93915792bde4a8 --- /dev/null +++ b/CompressionEntity/src/IfswMath.c @@ -0,0 +1 @@ +../../CrIa/src/IfswMath.c \ No newline at end of file diff --git a/CompressionEntity/src/IfswMath.h b/CompressionEntity/src/IfswMath.h new file mode 120000 index 0000000000000000000000000000000000000000..444c33767129a3d9cade3ab61f9db56a1f498b59 --- /dev/null +++ b/CompressionEntity/src/IfswMath.h @@ -0,0 +1 @@ +../../CrIa/src/IfswMath.h \ No newline at end of file diff --git a/CompressionEntity/src/SdpAlgorithmsImplementation.c b/CompressionEntity/src/SdpAlgorithmsImplementation.c new file mode 100644 index 0000000000000000000000000000000000000000..4cc97bcc61f06f6dffd6ffbfef25c6da016f8439 --- /dev/null +++ b/CompressionEntity/src/SdpAlgorithmsImplementation.c @@ -0,0 +1,3005 @@ +/** + * @file SdpAlgorithmsImplementation.c + * @ingroup Compression + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup Compression Science Data Compression + * @ingroup Sdp + * + * @brief The big @ref Compress function together with its many auxiliary functions and algorithms. + * + * ## Overview + * + * This group contains the @ref Compress function, which is called once for each product during the science compression. + * + * ### @anchor ping-pong Playing ping-pong with buffers + * + * The data processing chain consists of six consecutive steps, which are user-configurable. + * There are several scenarios in which such a step operates: + * 1. it processes data from an input buffer and generates data in an output buffer + * 2. it works in place, i.e. the input data are overwritten with the output data + * 3. there are no input data, but output data (e.g. @ref PRODUCT_DUMMY data generation) + * 4. the input data will not be modified, but are needed by the next processing step + * + * Other cases have been removed from CHEOPS (e.g. dumping data or centroid calculation inside + * the data processing chain). + * + * For all these cases, a memory-saving buffering scheme had to be found, which at the same time + * reduces the number of memcopy operations. This is achieved by the following paradigms: + * - the information about datatype and dimensions are carried along the steps + * in the source @ref ScienceBuf structure and only updated after a lossy step + * - one step always starts with the data in the source @ScienceBuf + * - the compressed data are tracked through a @ref CompressedBuf structure + * - in each step, the output buffer (compressed->data) is __not__ copied back into the input + * buffer (source->data), instead + * their pointers are exchanged in the @ref ScienceBuf and @ref CompressedBuf. The metadata + * are __not__ exchanged. + * - the actual input and output buffers (source->data and compressed->data) must both have the + * biggest size that a product can take on during an allowed processing step. + * - a step must not assume that useful data are in the compressed->data at the beginning + * (i.e. it has to assume that the original source was overwritten) + * - after the lossy steps are completed and before the lossless compression steps, a checksum + * is taken. This goes into the downlink as part of the @ref CompressionEntity for each product. + * - after lossless compression, the size is stored in the compressed->llcsize variable. + * - at the end of the processing chain the actual buffer may or may not need to be copied to the + * desired output buffer (given by the location parameter), depending on the number of times + * the buffers were exchanged. + * + * ### Fetching the Products + * + * The steps of the data processing chain are very similar in how they are applied, but the first step + * is very different. In this step, the data for the product are acquired from the @ref SIBs and + * copied into the source buffer. Note that no way was found to avoid this initial memcopy step, + * because the data for the products in the SIBs are structured, whereas the data processing steps + * need uninterrupted data cubes. + * + * The fetching itself is quite similar for each product. The general flow is: + * - for each frame, + * - pull the @ref SIB structure on the sibOut slot using @ref CrIaSetupSibWin (or full) + * - copy the relevant data from the SIB into the source->data + * - increment the sibOut (only locally, do not write back to data pool) + * ... and we are ready for the next step. + * + * Some of the products directly acquire the data from the SIBs to the source->data that way. + * Some, i.e. those which already carry out a lossy step such as cropping (imagettes) or + * the margins, first acquire the data into the swapped buffer and get the reduced data back in the + * source to save memory. The swapped buffer at the beginning is the ProcBuf, which was dimensioned + * for the largest product, so this is always fine. Otherwise we would need to reserve 4 MiB for the + * compressed imagettes buffer, which are cropped in the PRODUCT step. Clearly, this would be unwise. + * + * Please also read the section about buffer preparations in @ref SdpCompress. + */ + +#include "SdpAlgorithmsImplementation.h" +#include "SdpAlgorithmsImplementationLlc.h" +#include "SdpCeDefinitions.h" /* for CeKey defines, TYPESIZE */ +#include "CrIaDataPoolId.h" +#include "CrIaDataPool.h" +#include "SdpCompressionEntityStructure.h" +#include "SdpNlcPhot.h" +#include "EngineeringAlgorithms.h" + +#include <stdio.h> /* for SDPRINT */ +#include <string.h> /* for memcpy, strncopy */ +#include <stdlib.h> /* for qsort */ + +#include "IfswMath.h" + +#ifndef ISOLATED +#include "Services/General/CrIaConstants.h" +#include "CrIaIasw.h" /* for SdpEvtRaise */ +#endif + +#ifdef DEBUGFILES +#include <fitsio.h> /* used to save the intermediate debug images on PC */ +#endif + +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_RESET "\x1b[0m" + +#ifdef DEBUGFILES +#include <fitsio.h> /* used to save the intermediate debug images on PC */ +#endif + +#ifdef DEBUGFILES +char debugfilename[256]; + +void saveFitsImage (char *filename, struct ScienceBuf *imgdata) +{ + fitsfile *outfptr; + int status = 0; + int bitpix, naxis; + long naxes[2]; + + /* create output file */ + if (fits_create_file(&outfptr, filename, &status)) + SDPRINT("error %d creating fits file\n", status); + + /* create image HDU for BW image */ + bitpix = 32; + naxis = 2; + naxes[0] = imgdata->xelements; + naxes[1] = imgdata->yelements * imgdata->zelements; + fits_create_img(outfptr, bitpix, naxis, naxes, &status); + + /* save image data */ + fits_write_2d_int (outfptr, 0, naxes[0], naxes[0], naxes[1], (int *)(imgdata->data), &status); + + /* close file */ + if (fits_close_file(outfptr, &status)) + SDPRINT("error %d closing fits file\n", status); + + return; +} +#endif + + +/** + * @brief very slow but very safe memcpy replacement for the SRAM2 + * Makes a byte-wise copy through @ref GETBYTE and @ref PUTBYTE + * @param dest address where to copy data to + * @param src address where to take the data from + * @param n number of bytes to be copied + * @returns destination address, because we want to be compatible with memcpy and are never supposed to fail here + * @note here, the address does not need to be aligned! + * @note wherever you can, use the faster aligned version instead + * @todo this is really painfully slow, but it can't be helped much because this one is alignment safe. + */ + +void *sram2memcpy(void *dest, const void *src, unsigned long int n) +{ + unsigned char value; + unsigned int i; + unsigned int *src_aligned, *dest_aligned; + unsigned long int srcoff, destoff; + + src_aligned = (unsigned int *)((unsigned long int)src & ~0x3L); + srcoff = ((unsigned long int)src - (unsigned long int)src_aligned) * 8; + + dest_aligned = (unsigned int *)((unsigned long int)dest & ~0x3L); + destoff = ((unsigned long int)dest - (unsigned long int)dest_aligned) * 8; + + for (i=0; i < n; i++) + { + value = GetByte32 (i + srcoff, (unsigned int *)src_aligned); + PutByte32 (value, i + destoff, (unsigned int *)dest_aligned); + } + + return dest; +} + + +/** + * @brief function to copy shorts from SRAM1 to SRAM2, taking care of the alignment in SRAM2. + * In SRAM1 short access is OK, whereas in SRAM2 it will yield wrong results. This function + * takes care of this and still tries to copy the bulk of the data as integers which are assembled + * from the source short array. + * @param dest address where to copy data to, must be 2-byte aligned, does not need to be 4-byte aligned + * @param src address where to take the data from, must be 2-byte aligned, does not need to be 4-byte aligned + * @param n number of shorts to be copied + * @returns destination address, can be 2-byte aligned. In case of an error, NULL is returned. + * @warning once more, alignment matters here! + */ + +unsigned short *sram1tosram2_shorts (unsigned short *p_src, unsigned int nshorts, unsigned short *p_dest_short) +{ + unsigned int i; + unsigned int destval; + unsigned int *p_dest; + + /* check the requirements on the alignment of the buffers */ + if ((unsigned long int)p_src & 0x1) + return NULL; + if ((unsigned long int)p_dest_short & 0x1) + return NULL; + + /* bring the destination to 4-byte alignment by copying the first short */ + if ((unsigned long int)p_dest_short & 0x2) + { + p_dest = (unsigned int *)((unsigned long int)p_dest_short & ~0x3L); /* NOTE: round off the short pointer to align to next lowest int */ +#if (__sparc__) + destval = (p_dest[0] & 0xffff0000) | (unsigned int) p_src[0]; /* NOTE: big endian */ +#else + destval = (p_dest[0] & 0x0000ffff) | ((unsigned int) p_src[0] << 16); /* NOTE: little endian */ +#endif + p_dest[0] = destval; + nshorts--; + p_src++; + p_dest++; + } + else + { + p_dest = (unsigned int *) p_dest_short; + } + + /* aligned copy nshorts/2 pairs of shorts */ + for (i=0; i < (nshorts >> 1); i++) + { +#if (__sparc__) + destval = p_src[2*i] << 16; /* NOTE: big endian */ + destval |= p_src[2*i+1]; +#else + destval = p_src[2*i]; /* NOTE: little endian */ + destval |= p_src[2*i+1] << 16; +#endif + p_dest[i] = destval; + } + + p_dest_short = (unsigned short *)&p_dest[i]; + + /* care for a remaining odd short */ + if (nshorts & 0x1) + { +#if (__sparc__) + destval = (p_dest[i] & 0x0000ffff) | ((unsigned int) p_src[nshorts - 1] << 16); /* NOTE: big endian */ +#else + destval = (p_dest[i] & 0xffff0000) | (unsigned int) p_src[nshorts - 1]; /* NOTE: little endian */ +#endif + p_dest[i] = destval; + p_dest_short++; + } + + return p_dest_short; +} + + + +/** + * @brief safe (but slow) way to put the value of a single bit into a bitstream accessed as 32-bit RAM + * in big endian + * @param value the value to put, either 0 or 1 + * @param bitOffset index of the bit as seen from the very beginning of the bitstream + * @param destAddr this is the pointer to the beginning of the bitstream + * @note Do not use values like 23 and assume that the LSB will be set. It won't. + * @note works in SRAM2 + */ + +void PutBit32 (unsigned int value, unsigned int bitOffset, unsigned int *destAddr) +{ + unsigned int wordpos, bitpos; + unsigned int destval, mask; + + wordpos = bitOffset >> 5; /* division by 32 */ + /* bitpos = bitOffset - 32*wordpos; */ + bitpos = bitOffset & 0x1f; /* 5 bits */ + + /* shape a mask with the required bit set true */ + mask = 1 << (31-bitpos); + + /* get the destination word and clear the bit */ + destval = destAddr[wordpos]; + destval &= ~mask; + + /* set bit if the value was true */ + if (value == 1) + destval |= mask; + + /* write it back */ + destAddr[wordpos] = destval; + + return; +} + + +/** + * @brief safe (but slow) way to get the value of a single bit from a bitstream accessed as 32-bit RAM + * in big endian + * @returns value the value, either 0 or 1, as an unsigned int + * @param bitOffset index of the bit as seen from the very beginning of the bitstream + * @param src this is the pointer to the beginning of the bitstream + * @note works in SRAM2 + */ + +unsigned int GetBit32 (unsigned int bitOffset, unsigned int *src) +{ + unsigned int wordpos, bitpos; + unsigned int destval, mask; + + wordpos = bitOffset >> 5; /* division by 32 */ + /* bitpos = bitOffset - 32*wordpos; */ + bitpos = bitOffset & 0x1f; /* 5 bits */ + + /* shape a mask with the required bit set true */ + mask = 1 << (31-bitpos); + + /* get the destination word and mask all other bits */ + destval = src[wordpos]; + destval &= mask; + + if (destval != 0) + return 1; + + return 0; +} + + +/** + * @brief safe (but slow) way to put the value of up to 32 bits into a bitstream accessed as 32-bit RAM + * in big endian + * @param value the value to put, it will be masked + * @param bitOffset bit index where the bits will be put, seen from the very beginning of the bitstream + * @param nBits number of bits to put + * @param destAddr this is the pointer to the beginning of the bitstream + * @returns number of bits written or 0 if the number was too big + * @note works in SRAM2 + */ + +unsigned int PutNBits32 (unsigned int value, unsigned int bitOffset, unsigned int nBits, unsigned int *destAddr) +{ + unsigned int *localAddr; + unsigned int bitsLeft, shiftRight, shiftLeft, localEndPos; + unsigned int mask, n2; + + /* leave in case of erroneous input */ + if (nBits == 0) + return 0; + if (nBits > 32) + return 0; + + /* separate the bitOffset into word offset (set localAddr pointer) and local bit offset (bitsLeft) */ + localAddr = destAddr + (bitOffset >> 5); + bitsLeft = bitOffset & 0x1f; + + /* (M) we mask the value first to match its size in nBits */ + /* the calculations can be re-used in the unsegmented code, so we have no overhead */ + shiftRight = 32 - nBits; + mask = 0xffffffff >> shiftRight; + value &= mask; + + /* to see if we need to split the value over two words we need the right end position */ + localEndPos = bitsLeft + nBits; + + if (localEndPos <= 32) + { + /* UNSEGMENTED + + |-----------|XXXXX|----------------| + bitsLeft n bitsRight + + -> to get the mask: + shiftRight = bitsLeft + bitsRight = 32 - n + shiftLeft = bitsRight + + */ + + /* shiftRight = 32 - nBits; */ /* see (M) above! */ + shiftLeft = shiftRight - bitsLeft; + + /* generate the mask, the bits for the values will be true */ + /* mask = (0xffffffff >> shiftRight) << shiftLeft; */ /* see (M) above! */ + mask <<= shiftLeft; + + /* clear the destination with inverse mask */ + *(localAddr) &= ~mask; + + /* assign the value */ + *(localAddr) |= (value << (32-localEndPos)); /* NOTE: 32-localEndPos = shiftLeft can be simplified */ + } + + else + { + /* SEGMENTED + + |-----------------------------|XXX| |XX|------------------------------| + bitsLeft n1 n2 bitsRight + + -> to get the mask part 1: + shiftright = bitsleft + n1 = n - (bitsleft + n - 32) = 32 - bitsleft + + -> to get the mask part 2: + n2 = bitsleft + n - 32 + shiftleft = 32 - n2 = 32 - (bitsleft + n - 32) = 64 - bitsleft - n + + */ + + n2 = bitsLeft + nBits - 32; + + /* part 1: */ + shiftRight = bitsLeft; + mask = 0xffffffff >> shiftRight; + + /* clear the destination with inverse mask */ + *(localAddr) &= ~mask; + + /* assign the value part 1 */ + *(localAddr) |= (value >> n2); + + /* part 2: */ + /* adjust address */ + localAddr += 1; + shiftLeft = 64 - bitsLeft - nBits; + mask = 0xffffffff << shiftLeft; + + /* clear the destination with inverse mask */ + *(localAddr) &= ~mask; + + /* assign the value part 2 */ + *(localAddr) |= (value << (32-n2)); + } + + return nBits; +} + + +/** + * @brief safe (but slow) way to get the value of several bits from a bitstream accessed as 32-bit RAM + * @param[out] p_value pointer to the output value, where the retrieved bit will be stored on the LSB end + * @param[in] bitOffset the current stream offset in bits + * @param[in] nBits number of bits to be acquired (0-32) + * @param[in] srcAddr pointer to a bitstream array + * @returns number of bits retrieved or 0 if too many bits were asked + * @note works in SRAM2 + */ + +unsigned int GetNBits32 (unsigned int *p_value, unsigned int bitOffset, unsigned int nBits, unsigned int *srcAddr) +{ + unsigned int *localAddr; + unsigned int bitsLeft, bitsRight, shiftRight, localEndPos; + unsigned int mask, n1, n2; + + /* leave in case of erroneous input */ + if (nBits == 0) + return 0; + if (nBits > 32) + return 0; + + /* separate the bitOffset into word offset (set localAddr pointer) and local bit offset (bitsLeft) */ + localAddr = srcAddr + (bitOffset >> 5); + bitsLeft = bitOffset & 0x1f; + + /* to see if we need to split the value over two words we need the right end position */ + localEndPos = bitsLeft + nBits; + + if (localEndPos <= 32) + { + /* UNSEGMENTED */ + + shiftRight = 32 - nBits; + bitsRight = shiftRight - bitsLeft; + + /* shift the value to the right */ + *(p_value) = *(localAddr) >> bitsRight; /* bitsRight is the same as shiftLeft */ + + /* generate the mask, the bits for the values will be true */ + mask = (0xffffffff >> shiftRight); + + /* extract the value using the mask */ + *(p_value) &= mask; + } + + else + { + /* SEGMENTED - see PutNbits32 for details */ + + n1 = 32 - bitsLeft; + n2 = nBits - n1; + + /* part 1: */ + mask = 0xffffffff >> bitsLeft; + *(p_value) = (*localAddr) & mask; + *(p_value) <<= n2; + + /* part 2: */ + /* adjust address */ + localAddr += 1; + + bitsRight = 32 - n2; + *(p_value) |= *(localAddr) >> bitsRight; + } + + return nBits; +} + + +/** + * @brief safe (but slow) way to put the value of a byte into a byte array accessed as 32-bit RAM + * in big endian + * @param value the value to put + * @param byteOffset index of the byte as seen from the very beginning of the byte array + * @param destAddr this is the pointer to the beginning of the byte array + * @note works in SRAM2, but array address must be word aligned! + */ + +void PutByte32 (unsigned char value, unsigned int byteOffset, unsigned int *destAddr) +{ + unsigned int *localAddr; + unsigned int bytesLeft, bitsRight; + unsigned int mask; + unsigned int uivalue; + + /* separate the byteOffset into word offset (set localAddr pointer) and local byte offset (bytesLeft) */ + localAddr = destAddr + (byteOffset >> 2); + + /* calculate the destination byte position within the dest word expressed as a left shift (24 for MSB, 0 for LSB) */ + bytesLeft = byteOffset & 0x3; + bitsRight = (3 - bytesLeft) << 3; + + /* create mask and shift the dest value */ + mask = 0xff << bitsRight; + uivalue = ((unsigned int) value) << bitsRight; + + /* clear the destination with inverse mask */ + *(localAddr) &= ~mask; + + /* assign the value */ + *(localAddr) |= uivalue; + + return; +} + + +/** + * @brief safe (but slow) way to read the value of a byte from a byte array accessed as 32-bit RAM + * in big endian + * @returns the value of the byte in question + * @param byteOffset index of the byte as seen from the very beginning of the byte array + * @param srcAddr this is the pointer to the beginning of the byte array + * @note works in SRAM2, but array address must be word aligned! + */ + +unsigned char GetByte32 (unsigned int byteOffset, unsigned int *srcAddr) +{ + unsigned int *localAddr; + unsigned int bytesLeft, bitsRight; + + /* separate the byteOffset into word offset (set localAddr pointer) and local byte offset (bytesLeft) */ + localAddr = srcAddr + (byteOffset >> 2); + + /* calculate the destination byte position within the dest word expressed as a left shift (24 for MSB, 0 for LSB) */ + bytesLeft = byteOffset & 0x3; + bitsRight = (3 - bytesLeft) << 3; + + /* get and shift the word */ + return (unsigned char) ((*(localAddr) >> bitsRight) & 0xff); +} + + +/** + * @brief coaddition of N frames to a stacked frame + * @returns the number of frames that were stacked or 0 if one of the dimensions was 0 + * @param source address where the image cube starts + * @param Xdim length of first axis, e.g. 200 + * @param Ydim length of second axis, e.g. 200 + * @param N stack depth + * @note also works in place (i.e. if source and dest are identical) + * @warning There is no saturation, i.e. values can over- or underflow. For CHEOPS this can become a problem if you + * stack more than 32767 images. Fortunately, we don't have RAM for so many images. + */ + +int CoAdd32s (int *source, unsigned short Xdim, unsigned short Ydim, unsigned short N, int *dest) +{ + int x, y, n; + + if (N*Xdim*Ydim == 0) + return 0; + + /* copy first frame to dest if the two buffers are not identical; */ + if ((unsigned long int) source != (unsigned long int)dest) + for (x=0; x < Xdim*Ydim; x++) + dest[x] = source[x]; + + /* stack up remaining frames */ + for (n=1; n < N; n++) + for (y=0; y < Ydim; y++) + for (x=0; x < Xdim; x++) + dest[y*Xdim + x] += source[n*Xdim*Ydim + y*Xdim + x]; + + return n; +} + +/** + * @brief averaging of N frames to a stacked frame in integer (using rounding) + * @returns the number of frames that were stacked or 0 if one of the dimensions was 0 + * @param source address where the image cube starts + * @param Xdim length of first axis, e.g. 200 + * @param Ydim length of second axis, e.g. 200 + * @param N stack depth + * @note also works in place (i.e. if source and dest are identical) + * @warning This uses the @ref CoAdd32s function, so we are restricted to average stacks of less than 32767 frames. + */ + +int Average32s (int *source, unsigned short Xdim, unsigned short Ydim, unsigned short N, int *dest) +{ + int i, status; + + float reciprocal; + + if (N == 0) + return 0; + if (Xdim == 0) + return 0; + if (Ydim == 0) + return 0; + + /* stack up */ + status = CoAdd32s (source, Xdim, Ydim, N, dest); + + /* divide by N and round */ + reciprocal = 1.f/(float)N; + + for (i=0; i < Xdim*Ydim; i++) + dest[i] = (int) roundf(reciprocal * (float)dest[i]); + + return status; +} + +/** + * @brief averaging of N frames per group (using truncation) + * @returns the number of groups that result + * @param source address where the image cube starts + * @param Xdim length of first axis, e.g. 200 + * @param Ydim length of second axis, e.g. 200 + * @param Zdim number of input frames, e.g. 6 + * @param N number of frames to stack per group, e.g. 3 + * @param operation 0 for averaging, otherwise coaddition + * @note also works in place (i.e. if source and dest are identical) + * @warning This uses the @ref CoAdd32s function, so we are restricted to average stacks of less than 32767 frames. + */ + +int ProcessGroups32s (int *source, unsigned short Xdim, unsigned short Ydim, unsigned short Zdim, unsigned char N, unsigned char operation, int *dest) +{ + unsigned int i, groups, remaining; + + int *indata; + int *outdata; + + if (N == 0) + return 0; + if (Xdim == 0) + return 0; + if (Ydim == 0) + return 0; + if (Zdim == 0) + return 0; + + groups = (unsigned int)Zdim / (unsigned int)N; + remaining = (unsigned int)Zdim - groups*(unsigned int)N; + + for (i=0; i < groups; i++) + { + indata = source + i * N * Xdim * Ydim; + outdata = dest + i * Xdim * Ydim; + + if (operation == 0) + { + Average32s (indata, Xdim, Ydim, N, outdata); + } + else + { + CoAdd32s (indata, Xdim, Ydim, N, outdata); + } + } + + if (remaining > 0) + { + /* average the remaining frames */ + indata = source + groups * N * Xdim * Ydim; + outdata = dest + groups * Xdim * Ydim; + + if (operation == 0) + { + Average32s (indata, Xdim, Ydim, remaining, outdata); + } + else + { + CoAdd32s (indata, Xdim, Ydim, remaining, outdata); + } + + return groups + 1; + } + + return groups; +} + + +/** + * @brief apply bit rounding for unsigned integers in place + * @param source pointer to the input data + * @param nbits number of bits to round + * @param n number of samples to process + * + * @note the result is right-shifted by nbits, but we round in float + */ + +void BitRounding32u (unsigned int *source, unsigned int nbits, unsigned int n) +{ + unsigned int i; + unsigned int cellwidth; + float reciprocal; + + if (nbits >= 32) + return; + + cellwidth = 1u << nbits; + reciprocal = 1.0f / (float)cellwidth; + + for (i=0; i < n; i++) + source[i] = (unsigned int)roundf((float)source[i] * reciprocal); + + return; +} + + + + +/** + * @brief safe (but slow) way to read the value of a short from a packed array accessed as 32-bit RAM + * in big endian + * @returns the value of the short in question + * @param shortOffset index of the short as seen from the very beginning of the short array + * @param srcAddr this is the pointer to the beginning of the array (4B aligned) + * @note works in SRAM2 + */ + +unsigned int GetUShort32 (unsigned int shortOffset, unsigned int *srcAddr) +{ + /* determine if it is the upper (most significant) halfword or the lower one */ +#if (__sparc__) + if ((shortOffset & 1) == 0) +#else + if ((shortOffset & 1) == 1) +#endif + { + /* left halfword */ + return srcAddr[shortOffset >> 1] >> 16; + } + else + { + /* right halfword */ + return srcAddr[shortOffset >> 1] & 0xffff; + } +} + + +/** + * @brief copy a 2d sub-image from an image in SIB. + * @param source + * @param Xdim length of the X dimension + * @param Ydim length of the Y dimension + * @param XcDim length of the X dimension for the cropped image + * @param YcDim length of the Y dimension for the cropped image + * @param XcStart offset of the crop in X + * @param YcStart offset of the crop in Y + * @param dest pointer to the destination + * @returns 0 on success, or -1 if the crop extends over the window + * @note works in place (input and output can be identical) + */ + +int CropCopyFromSibAndUnpack (unsigned int *source, unsigned short Xdim, unsigned short Ydim, unsigned short XcDim, unsigned short YcDim, unsigned short XcStart, unsigned short YcStart, unsigned int *dest) +{ + unsigned int i, j; + + /* if the imagette extends over the window, we return an error */ + if (((XcStart + XcDim) > Xdim) || ((YcStart + YcDim) > Ydim)) + return -1; + + for (j=0; j < YcDim; j++) + for (i=0; i < XcDim; i++) + dest[i + j*XcDim] = GetUShort32(XcStart+i + YcStart*Xdim + Xdim*j, source); + + return 0; +} + + +/** + * @brief this is a popcount, a sideway sum, it counts the number of ones that are set in a short + * @param value the input value we are interested in + * @returns the number of bits set to 1 + */ + +unsigned int CountOnes16 (unsigned short value) +{ + int i, ones; + + for (i=0, ones=0; i<16; i++) + ones += (value >> i) & 0x1; + + return ones; +} + + +/** + * @brief copy columns selected in the mask to the output + * @param data pointer to the input data + * @param y length of the y dimension + * @param mask 0xffff means all 16 columns, 0 means none, bit patterns inbetween work as switches + * @param output pointer to the destination + * @note works in place (input and output can be identical) + */ + +void ColSelect16_32 (unsigned int *data, unsigned int y, unsigned short mask, unsigned int *output) +{ + unsigned int i, j, iout; + unsigned int outwidth = CountOnes16(mask); + + for (i=0, iout=0; i < 16; i++) + if ((mask << i) & 0x8000) + { + for (j=0; j < y; j++) + { + output[iout+j*outwidth] = data[i+j*16]; + } + iout++; + } + + return; +} + + +/** + * @brief overwrite values outside a circular mask with a given value + * @param source pointer to the image data + * @param Xdim length of first image axis + * @param Ydim length of second image axis + * @param xoff offset of the centre in the first image axis (negaitve shifts left) + * @param yoff offset of the centre in the second image axis (negaitve shifts up) + * @param radius radius (in fractional pixels) of the aperture + * @param maskval replacement value. all pixels outside the aperture will be set to that value + * @param dest pointer to destination data + * @returns number of processed values + * @note works in place (input and output can be identical) + */ + +int CircMask32 (unsigned int *source, unsigned int Xdim, unsigned int Ydim, int xoff, int yoff, float radius, unsigned int maskval, unsigned int *dest) +{ + unsigned int cenX, cenY; + unsigned int n = 0; + unsigned int x, y; + unsigned int rsquare = 0; + int vecX, vecY; + + if (radius > 0.0f) + rsquare = (unsigned int) (radius*radius + 1.0); + + /* for even number, it will be the left pixel */ + cenX = ((Xdim - 1) >> 1) + xoff; + cenY = ((Ydim - 1) >> 1) + yoff; + + for (y=0; y < Ydim; y++) + for (x=0; x < Xdim; x++) + { + vecX = cenX - x; + vecY = cenY - y; + if ((unsigned int)(vecX*vecX + vecY*vecY) < rsquare) + { + /* inside circle */ + dest[n] = source[x + y*Xdim]; + n++; + } + else + { + /* outside circle */ + dest[n] = maskval; + n++; + } + } + + return n; +} + +/** + * @brief discard values inside an inner ring and outside an outer ring. This will create a 1d vector out of a 2d image + * @param source pointer to the image data + * @param Xdim length of first image axis + * @param Ydim length of second image axis + * @param xoff offset of the centre in the first image axis (negaitve shifts left) + * @param yoff offset of the centre in the second image axis (negaitve shifts up) + * @param iradius radius (in fractional pixels) of the inner circle + * @param oradius radius (in fractional pixels) of the outer circle + * @param dest pointer to destination data + * @returns length of the resulting vector, or number of remaining pixels if that is more understandable + * @note works in place (input and output can be identical) + */ + +int RingExtract32 (unsigned int *source, unsigned int Xdim, unsigned int Ydim, int xoff, int yoff, float iradius, float oradius, unsigned int *dest) +{ + unsigned int cenX, cenY; + unsigned int n = 0; + unsigned int x, y; + unsigned int irsquare = 0; + unsigned int orsquare = 0; + int vecX, vecY, vrad; + + if (iradius > 0.0f) + { + irsquare = (unsigned int) (iradius*iradius + 1.0); + } + + if (oradius > 0.0f) + { + orsquare = (unsigned int) (oradius*oradius + 1.0); + } + + /* for even number, it will be the left pixel */ + cenX = ((Xdim - 1) >> 1) + xoff; + cenY = ((Ydim - 1) >> 1) + yoff; + + for (y=0; y < Ydim; y++) + { + for (x=0; x < Xdim; x++) + { + vecX = cenX - x; + vecY = cenY - y; + vrad = vecX*vecX + vecY*vecY; + + if ((unsigned int)vrad < orsquare) + { + /* inside the outer circle */ + + if ((unsigned int)vrad < irsquare) + { + /* inside the inner circle */ + /* do nothing */ + } + else + { + /* the ring */ + dest[n] = source[x + y*Xdim]; + n++; + } + } + else + { + /* outside the outer circle */ + /* do nothing */ + } + } + } + + return n; +} + + +/** + * @brief checksum function used in the compression. It is the usual CRC16 (big endian). + * @param data pointer to the image data + * @param N size of the data + * @returns the crc + * @note works in SRAM2 + */ + +unsigned short Checksum_CRC16_32 (unsigned int *data, unsigned int N) +{ + unsigned int i; + int j; + + unsigned int Syndrome = 0xffff; + unsigned char dataBits; + + for (i=0; i < N; i++) + { + dataBits = GetByte32(i, data); + + for (j=0; j<8; j++) + { + if ((dataBits & 0x80) ^ ((Syndrome & 0x8000) >> 8)) + { + Syndrome = ((Syndrome << 1) ^ 0x1021) & 0xFFFF; + } + else + { + Syndrome = (Syndrome << 1) & 0xFFFF; + } + dataBits = dataBits << 1; + } + } + return (unsigned short)(Syndrome & 0xffff); +} + + +/** + * @brief calculates mean and standard deviation for a given dataset + * @param[in] data pointer to the input data (integer) + * @param[in] len number of values to process + * @param[out] pointer to the mean (float) to store the result + * @param[out] pointer to the stdev (float) to store the result + * @note considers Bessel correction + */ + +void MeanSigma (int *data, int len, float *m, float *sig) +{ + int i; + double sum = 0; + double sumq = 0; + double mean, var, sigma; + + /* avoid division by zero */ + if (len == 0) + { + /* m and sig will be undefined */ + return; + } + else if (len == 1) + { + *m = data[0]; + *sig = 0.0f; + return; + } + + for (i=0; i<len; i++) + sum += data[i]; + + mean = (double)sum/len; + + for (i=0; i<len; i++) + sumq += (data[i]-mean) * (data[i]-mean); + + var = 1./(len-1.) * sumq; /* with Bessel corr. */ + sigma = fsqrtd(var); + + *m = (float) mean; + *sig = (float) sigma; + + return; +} + + +/** + * @brief calculates mean and standard deviation for a given dataset + * @param[in] data pointer to the input data (integer) + * @param[in] len number of values to process + * @param[out] pointer to the mean (float) to store the result + * @param[out] pointer to the stdev (float) to store the result + * @note considers Bessel correction + */ + +float Mean32 (int *data, int len) +{ + int i; + double sum = 0; + float mean; + + for (i=0; i<len; i++) + sum += (double)data[i]; + + mean = (float)(sum/(double)len); + + return mean; +} + + +/** + * @brief Median calculation using the Algorithm by Torben Mogensen. + * Based on a public domain implementation by N. Devillard. + * @param data place where the data are stored + * @param len number of values to process + * @returns median of the given values + * @note for an even number of elements, it returns the smaller one + * @note The Torben mehtod does not need a separate buffer and it does not mix the input + */ + +int Median (int *data, int len) +{ + int i, less, greater, equal; + int min, max, guess, maxltguess, mingtguess; + + min = max = data[0] ; + + /* find min and max */ + for (i=1 ; i < len ; i++) + { + if (data[i] < min) + min=data[i]; + + if (data[i] > max) + max=data[i]; + } + + while (1) + { + /* update guesses */ + guess = (min + max) >> 1; + less = 0; + greater = 0; + equal = 0; + maxltguess = min; + mingtguess = max; + + /* find number of smaller and larger elements than guess */ + for (i=0; i < len; i++) + { + if (data[i] < guess) + { + less++; + if (data[i] > maxltguess) + maxltguess = data[i]; + } + else if (data[i] > guess) + { + greater++; + if (data[i] < mingtguess) + mingtguess = data[i]; + } + else + equal++; + } + + /* half the elements are less and half are greater, we hav found the median */ + if ((less <= (len+1)>>1) && (greater <= (len+1)/2)) + break; + + else if (less > greater) + max = maxltguess ; + else + min = mingtguess; + } + + if (less >= (len+1)>>1) + return maxltguess; + else if (less+equal >= (len+1)>>1) + return guess; + + return mingtguess; +} + + +/** + * @brief Median Absolute Deviation calculation + * MAD = median(abs(x-median(x))) + * @param data place where the data are stored + * @param len number of values to process + * @param median pre-calculated median + * @returns MAD of the given values + * @note it used the @ref Median function + */ + +int MedAbsDev (int *data, int len, int median, int *swap) +{ + int mad, i; + + for (i=0; i < len; i++) + swap[i] = abs(data[i] - median); + + mad = Median (swap, len); + + return mad; +} + + +#ifdef GROUNDSW +int compint (const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} +#endif + + + +/** + * @brief core function of the IWT + * transforms one line, one scale + * Implementation is based on D. Solomon, Data Compression, 4th ed, 2007, Springer + * @param Input pointer to the input data + * @param Output pointer to the output data + * @param n number of values to transform + * @returns 0 + */ + +int IntegerWaveletTransform_Core (int *Input, int *Output, unsigned int n) +{ + int exception = 0; + + unsigned int i; + unsigned int odd = n % 2; + unsigned int k = n/2 + odd; + + /* + * In case of an odd number of coefficients, + * we have 1 additional LP coeff, which is the last input value. + */ + + /* + * HP coefficients + * even case: n/2 (no truncation) consisting of n/2-1 normal coeff + 1 half coeff + * odd case: only the n/2 (truncated number) normal coeff + */ + + for (i=0; i < n/2 - 1 + odd ; i++) /* normal coefficients (+odd) */ + Output[k+i] = Input[2*i+1] - FLOORSH((Input[2*i] + Input[2*i+2]),1); /* was: floor((Input[2*i] + Input[2*i+2])/2.); */ + + if (odd == 0) /* in the even case the last one is a "half" HP coefficient */ + Output[n-1] = Input[n-1] - Input[n-2]; + + /* + * LP coefficients + * even case: n/2 (no truncation) + * odd case: n/2 (truncated) + 1 + */ + + Output[0] = Input[0] + FLOORSH(Output[k],1); /* was: floor(Output[k]/2.); */ /* the first one is a "half" coefficient */ + + for (i=1; i < k - odd; i++) /* normal coefficients */ + Output[i] = Input[2*i] + FLOORSH((Output[k+i-1] + Output[k+i]),2); /* was: floor((Output[k+i-1] + Output[k+i])/4.); */ /* integer truncation */ + + if (odd) /* in the odd case the last one is a "half" LP coefficient */ + Output[k-1] = Input[n-1] + FLOORSH(Output[n-1],1); /* was: floor(Output[n-1]/2.); */ + + return exception; +} + + +/** + * @brief top-level function applying the 1D IWT + * applies standard decomposition + * @param Input pointer to the input data + * @param Output pointer to the output data + * @param n number of values to transform + * @returns 0 + * @warning overwrites the input data + */ + +int IntegerWaveletTransform_Decompose (int *Input, int *Output, unsigned int n) +{ + int exception = 0; + + int i, size; + + for (size = n; size > 1; ) + { + IntegerWaveletTransform_Core (Input, Output, size); /* transform */ + + for (i=0; i < size; i++) Input[i] = Output[i]; /* copy back */ + + size = (size % 2 ? size/2 + 1 : size/2); /* adjust size */ + } + + for (i=0; i < size; i++) Output[i] = Input[i]; /* copy out */ + + return exception; +} + + +/** + * @brief reversible differencing of a buffer + * @param buf an integer pointer to a buffer + * @param words number of values to process + * + * Differences are made in place, from bottom to top + * @note Is applied in place. + */ + +void Delta32 (int *buf, int words) +{ + int i; + + for (i=words-1; i>0; i--) + { + buf[i] = (buf[i] - buf[i-1]); + } + + return; +} + + +/** + * @brief fold negative values into positive, interleaving the positive ones + * @param buffer an integer pointer to a buffer + * @param N number of values to process + * + * @note Is applied in place. + */ + +void Map2Pos32 (int *buffer, unsigned int N) +{ + unsigned int i; + + for (i=0; i < N; i++) + { + if (buffer[i] < 0) + buffer[i] = ((0xFFFFFFFF - buffer[i]) << 1) + 1; /* NOTE: the integer overflow is intended */ + else + buffer[i] = buffer[i] << 1; + } + + return; +} + + +/** + * @brief Transpose a 2D array (matrix) + * @param src an integer pointer to a buffer + * @param src_xdim length of first axis + * @param src_ydim length of second axis + * @param dest pointer to the output buffer + */ + +void Transpose2Di (int *src, unsigned int src_xdim, unsigned int src_ydim, int *dest) +{ + unsigned int i,j; + + for (j=0; j < src_ydim; j++) + { + for (i=0; i < src_xdim; i++) + { + dest[j+i*src_ydim] = src[i+j*src_xdim]; + } + } + return; +} + + +/** + * @brief differentiate a data cube from end to start, leaving the first frame as keyframe + * @param fdata pointer to the @ref ScienceBuf structure holding the buffer to be processed and carrying the correct dimensions + * @returns number of difference frames or 0 if the input dimensions were wrong + * + * @note this is not a difference of each frame to the keyframe, but a differentiation + * @note only works on integer datatype + */ + +int FrameSubtract(struct ScienceBuf *fdata) +{ + unsigned int p, f, framelen; + + framelen = fdata->xelements * fdata->yelements; + + if (fdata->xelements * fdata->yelements * fdata->zelements == 0) + return 0; + + if (fdata->zelements == 1) + return 0; + + /* differentiate in place from end to start of file */ + for (f=fdata->zelements-1; f > 0; f--) + for (p=0; p < framelen; p++) + ((int *)fdata->data)[f*framelen + p] = ((int *)fdata->data)[f*framelen + p] - ((int *)fdata->data)[(f-1)*framelen + p]; + + return fdata->zelements - f; /* should return frames - 1 */ +} + +/** + * @brief run the data processing chain once for a given product + * @param source pointer to the @ref ScienceBuf structure holding a buffer with sufficient size and carrying the correct dimensions + * @param cestruct pointer to the @ref ComprEntStructure which has all the required settings and buffers properly initialized + * @param CeKey the compression entity key, the processing recipe. Take from CHEOPS-UVIE-INST-ICD-003 + * @param compressed pointer to the @ref CompressedBuf structure holding a buffer with sufficient size + * @param location decide whether you want the result back in the source buffer @ref SRCBUF (=0) or in the compressed buffer @ref DESTBUF (=1) + * @param compressed pointer to a @ref ScienceBuf structure holding a buffer that will be used as a swap buffer + * + * @returns 0 + * + * @note + */ + +int Compress(struct ScienceBuf *source, struct ComprEntStructure *cestruct, unsigned int CeKey, struct CompressedBuf *compressed, int location, struct ScienceBuf *swapbuffer) +{ + int status = 0; + unsigned int i, j, w; + unsigned int product, preproc, lossy1, lossy2, lossy3, decorr, llc; + + struct CrIaSib sib; + struct SibPhotometry *sibPhotometry; + struct ScienceBuf photData; + unsigned short sibOut, newSibOut, sibIn, sibSizeWin, sibNWin, sibSizeFull, sibNFull; + unsigned short colmask; /* for column selection in LDK and RDK */ + unsigned short sdbstate; + unsigned long int xibOffset; + + unsigned int local_start_x, local_start_y; + float productRadius = 0.0f; + float ampl; + + void *comprdata = compressed->data; + + /* local handle of frame elements */ + unsigned int FrameElements; + + struct StatValues stat; + struct Coordinates Coord; + struct SibHeader *sibHeader; + struct SibCentroid *sibCentroid; + unsigned short follow; + unsigned char stackGroup = 1; /* Mantis 1909 */ + + unsigned short ccProduct, ccStep; + unsigned short evt_data[2]; + unsigned char sdpCrc; + + CrIaCopy(CCPRODUCT_ID, &ccProduct); + + ccStep = ccProduct | CC_COMPR_STARTED; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* prepare compressed metadata, may be overwritten during lossy steps */ + compressed->datatype = source->datatype; + compressed->xelements = source->xelements; + compressed->yelements = source->yelements; + compressed->zelements = source->zelements; + compressed->nelements = source->nelements; + compressed->lossyCrc = 0; + compressed->llcsize = 0; + + /* disentangle the CeKey */ + product = CeKey & SDP_PRODUCT; + preproc = CeKey & SDP_PREPROC; + lossy1 = CeKey & SDP_LOSSY1; + lossy2 = CeKey & SDP_LOSSY2; + lossy3 = CeKey & SDP_LOSSY3; + decorr = CeKey & SDP_DECORR; + llc = CeKey & SDP_LLC; + + SDPRINT("+--------------+\n"); + SDPRINT("| Compression: |\n"); + SDPRINT("+--------------+\n"); + SDPRINT(" CeKey: Product=%01x PP=%01x L1=%01x L2=%01x D=%01x LL=%01x\n", product >> 28, preproc >> 24, lossy1 >> 20, lossy2 >> 16, decorr >> 8, llc); + SDPRINT(" Datatype: %x Elem=%d X=%d Y=%d Z=%d\n", source->datatype, source->nelements, \ + source->xelements, source->yelements, source->zelements); + + /*********************/ + /* Product */ + /*********************/ + + /* carry out product-specific setup stuff */ + + /* get state of SDB (WIN or FULL) */ + CrIaCopy (SDBSTATE_ID, &sdbstate); + + /* get SibOut */ + CrIaCopy(SIBOUT_ID, &sibOut); + CrIaCopy(SIBIN_ID, &sibIn); + CrIaCopy(SIBSIZEWIN_ID, &sibSizeWin); + CrIaCopy(SIBNWIN_ID, &sibNWin); + CrIaCopy(SIBSIZEFULL_ID, &sibSizeFull); + CrIaCopy(SIBNFULL_ID, &sibNFull); + + SDPRINT("*** Compress: SIBOUT = %d\n", sibOut); + + /* Mantis 2212: We need to estimate the bias before we enter the chain + for the case of NLC2. This is done by reading each LOS frame and writing + the bias back to the SIB phot->annulus2. + Note that NLC2 is only available in window mode */ + + if ((preproc == PREPROC_NLC2) && (sdbstate == CrIaSdb_CONFIG_WIN)) + { + /* for each frame get LOS, calc median and write to the SIB */ + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + sibHeader = (struct SibHeader *) sib.Header; + sibPhotometry = (struct SibPhotometry *) sib.Photometry; + + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LOS_W, sib.Ydim, IMGMRG_LDK_W + IMGMRG_LBLK_W, 0, (unsigned int *)source->data); + } + else + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LOS_W, sib.Ydim, 0, 0, (unsigned int *)source->data); + } + + if (status == -1) /* could not crop */ + sibPhotometry->annulus2 = 0.0f; + + /* calculate the bias here */ + sibPhotometry->annulus2 = (float) Median ((int *)source->data, IMGMRG_LOS_W * source->yelements); + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* sibOut has been altered and needs to be reloaded */ + CrIaCopy(SIBOUT_ID, &sibOut); + } + + + /* + Here the data processing chain starts + */ + + switch (product) + { + case PRODUCT_HEADERS : + + ccStep = ccProduct | CC_PRODUCT_HEADERS; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* get state of SDB (WIN or FULL) */ + CrIaCopy (SDBSTATE_ID, &sdbstate); + + /* as input, we need SEM window sizes and stacking order to calculate SIB structure layout */ + SibToFlatHeaders (source, cestruct); + + /* from here on, headers are treated as X x Z array */ + source->datatype = DATATYPE_UINT32; + source->xelements = FLAT_HEADER_VALUES; + source->yelements = 1; + source->nelements = source->xelements * source->yelements * source->zelements; + compressed->datatype = source->datatype; + compressed->xelements = source->xelements; + compressed->yelements = source->yelements; + compressed->nelements = source->nelements; + + SDPRINT("source Input data are: %d %d .. %d\n", ((unsigned int *)source->data)[0], ((unsigned int *)source->data)[1], ((unsigned int *)source->data)[source->nelements-1]); + break; + + case PRODUCT_STACKED : + + ccStep = ccProduct | CC_PRODUCT_STACKED; + CrIaPaste(CCSTEP_ID, &ccStep); + + productRadius = cestruct->SemWindowSizeX / 2; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure using current sibOut (the compression is the SIB consumer, thus it reads from "out") */ + status = 0; + if (sdbstate == CrIaSdb_CONFIG_WIN) + status = CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + status = CrIaSetupSibFull (&sib, sibOut); + + if (status == 0) + { + /* error gets reported by setup function */ + break; + } + + /* we need to initialize the SibPhotometry values in all cases, but we must not in NLC2 */ + if (preproc != PREPROC_NLC2) + { + sibPhotometry = (struct SibPhotometry *) sib.Photometry; + sibPhotometry->centrum = 0.0f; + sibPhotometry->annulus1 = 0.0f; + sibPhotometry->annulus2 = 0.0f; + } + + /* get the expos data into the local source buffer */ + FrameElements = source->xelements * source->yelements; +#if (__sparc__) + UnpackU16ToU32 ((uint32_t *)sib.Expos, FrameElements, &(((uint32_t *)source->data)[i*FrameElements]), UNPACK_NOSWAP); +#else + UnpackU16ToU32 ((uint32_t *)sib.Expos, FrameElements, &(((uint32_t *)source->data)[i*FrameElements]), UNPACK_SWAP); +#endif + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + } + else + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressFull); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeFull, (unsigned int)sibNFull, SIBOUT_FULL_XIB); + } + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + SDPRINT("source Input data are at %lx: %d %d .. %d\n", (unsigned long int)source->data, ((unsigned int *)source->data)[0], ((unsigned int *)source->data)[1], ((unsigned int *)source->data)[source->nelements-1]); + + break; + + + case PRODUCT_IMAGETTES : + + ccStep = ccProduct | CC_PRODUCT_IMAGETTES; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPIMGTTSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + productRadius = cestruct->Imagettes_ApertureSizeX / 2; + + /* get state of SDB (WIN or FULL) */ + CrIaCopy (SDBSTATE_ID, &sdbstate); + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure using current sibOut (the compression is the SIB consumer, thus it reads from "out") */ + status = 0; + if (sdbstate == CrIaSdb_CONFIG_WIN) + status = CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + status = CrIaSetupSibFull (&sib, sibOut); + + if (status == 0) + { + /* error gets reported by setup function */ + break; + } + + /* use target location and sem offsets to calculate the ROI + the SEM window size is taken from the SIB, the POS is taken from the DP */ + + sibCentroid = (struct SibCentroid *) sib.Centroid; + + Coord.TargetLocX_I = sibCentroid->targetLocX; + Coord.TargetLocY_I = sibCentroid->targetLocY; + Coord.SemWinSizeX_L = sib.Xdim; + Coord.SemWinSizeY_L = sib.Ydim; + Coord.SemWinPosX_L = (unsigned int) cestruct->SemWindowPosX; + Coord.SemWinPosY_L = (unsigned int) cestruct->SemWindowPosY; + Coord.SubWinSizeX_L = cestruct->Imagettes_ApertureSizeX; + Coord.SubWinSizeY_L = cestruct->Imagettes_ApertureSizeY; + Coord.StartLocationX_L = 0; + Coord.StartLocationY_L = 0; + + getStartCoord (&Coord); + + local_start_x = Coord.StartLocationX_L; + local_start_y = Coord.StartLocationY_L; + + CrIaCopy(SDPIMGTTSTRAT_ID, &follow); + + if (follow == STRAT_MOVING) + { + /* apply offset only if valid */ + if ((sibCentroid->validityStatus == CEN_VAL_WINDOW) || (sibCentroid->validityStatus == CEN_VAL_FULL)) + { + local_start_x -= roundf(sibCentroid->offsetX / 100.0f); + local_start_y -= roundf(sibCentroid->offsetY / 100.0f); + } + } + + status = CropCopyFromSibAndUnpack (sib.Expos, sib.Xdim, sib.Ydim, cestruct->Imagettes_ApertureSizeX, cestruct->Imagettes_ApertureSizeY, local_start_x, local_start_y, &(((unsigned int *)source->data)[i * cestruct->Imagettes_ApertureSizeX * cestruct->Imagettes_ApertureSizeY])); + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + } + else + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressFull); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeFull, (unsigned int)sibNFull, SIBOUT_FULL_XIB); + } + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* adjust product sizes */ + source->xelements = cestruct->Imagettes_ApertureSizeX; + source->yelements = cestruct->Imagettes_ApertureSizeY; + source->nelements = source->xelements * source->yelements * source->zelements; + + SDPRINT("source Input data are: %d %d .. %d\n", ((unsigned int *)source->data)[0], ((unsigned int *)source->data)[1], ((unsigned int *)source->data)[source->nelements-1]); + + break; + + + case PRODUCT_MRGLOS : + + ccStep = ccProduct | CC_PRODUCT_MRGLOS; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPLOSSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + sibHeader = (struct SibHeader *) sib.Header; + + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LOS_W, sib.Ydim, IMGMRG_LDK_W + IMGMRG_LBLK_W, 0, &(((unsigned int *)source->data)[i * IMGMRG_LOS_W * sib.Ydim])); + } + else + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LOS_W, sib.Ydim, 0, 0, &(((unsigned int *)source->data)[i * IMGMRG_LOS_W * sib.Ydim])); + } + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* adjust product sizes */ + source->xelements = IMGMRG_LOS_W; + source->nelements = source->xelements * source->yelements * source->zelements; + + if (source->nelements >= 2) + SDPRINT("source Input data are: %d %d .. %d\n", ((unsigned int *)source->data)[0], ((unsigned int *)source->data)[1], ((unsigned int *)source->data)[source->nelements-1]); + + break; + + case PRODUCT_MRGLDK : + + ccStep = ccProduct | CC_PRODUCT_MRGLDK; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPLDKSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + sibHeader = (struct SibHeader *) sib.Header; + + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LDK_W, sib.Ydim, 0, 0, &(((unsigned int *)source->data)[i * IMGMRG_LDK_W * sib.Ydim])); + } + else + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LDK_W, sib.Ydim, IMGMRG_LOS_W + IMGMRG_LBLK_W, 0, &(((unsigned int *)source->data)[i * IMGMRG_LDK_W * sib.Ydim])); + } + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* and apply the column mask (in place) */ + colmask = cestruct->ImgMrgLDK_ColumnSelectionMask; + ColSelect16_32 ((unsigned int *)source->data, source->yelements * source->zelements, colmask, (unsigned int *)source->data); + + /* adjust product sizes */ + source->xelements = CountOnes16 (colmask); + source->nelements = source->xelements * source->yelements * source->zelements; + + break; + + case PRODUCT_MRGLBLK : + + ccStep = ccProduct | CC_PRODUCT_MRGLBLK; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPLBLKSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + sibHeader = (struct SibHeader *) sib.Header; + + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LBLK_W, sib.Ydim, IMGMRG_LDK_W, 0, &(((unsigned int *)source->data)[i * IMGMRG_LBLK_W * sib.Ydim])); + } + else + { + status = CropCopyFromSibAndUnpack (sib.Lsm, LSM_XDIM, sib.Ydim, IMGMRG_LBLK_W, sib.Ydim, IMGMRG_LOS_W, 0, &(((unsigned int *)source->data)[i * IMGMRG_LBLK_W * sib.Ydim])); + } + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* adjust product sizes */ + source->xelements = IMGMRG_LBLK_W; + source->nelements = source->xelements * source->yelements * source->zelements; + + break; + + case PRODUCT_MRGRDK : + + ccStep = ccProduct | CC_PRODUCT_MRGRDK; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPRDKSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + sibHeader = (struct SibHeader *) sib.Header; + + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + status = CropCopyFromSibAndUnpack (sib.Rsm, RSM_XDIM, sib.Ydim, IMGMRG_RDK_W, sib.Ydim, IMGMRG_RBLK_W, 0, &(((unsigned int *)source->data)[i * IMGMRG_RDK_W * sib.Ydim])); + } + else + { + status = CropCopyFromSibAndUnpack (sib.Rsm, RSM_XDIM, sib.Ydim, IMGMRG_RDK_W, sib.Ydim, 0, 0, &(((unsigned int *)source->data)[i * IMGMRG_RDK_W * sib.Ydim])); + } + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* and apply the column mask (in place) */ + colmask = cestruct->ImgMrgRDK_ColumnSelectionMask; + ColSelect16_32 ((unsigned int *)source->data, source->yelements * source->zelements, colmask, (unsigned int *)source->data); + + /* adjust product sizes */ + source->xelements = CountOnes16 (colmask); + source->nelements = source->xelements * source->yelements * source->zelements; + + break; + + case PRODUCT_MRGRBLK : + + ccStep = ccProduct | CC_PRODUCT_MRGRBLK; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPRBLKSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + sibHeader = (struct SibHeader *) sib.Header; + + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + status = CropCopyFromSibAndUnpack (sib.Rsm, RSM_XDIM, sib.Ydim, IMGMRG_RBLK_W, sib.Ydim, 0, 0, &(((unsigned int *)source->data)[i * IMGMRG_RBLK_W * sib.Ydim])); + } + else + { + status = CropCopyFromSibAndUnpack (sib.Rsm, RSM_XDIM, sib.Ydim, IMGMRG_RBLK_W, sib.Ydim, IMGMRG_RDK_W, 0, &(((unsigned int *)source->data)[i * IMGMRG_RBLK_W * sib.Ydim])); + } + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* adjust product sizes */ + source->xelements = IMGMRG_RBLK_W; + source->nelements = source->xelements * source->yelements * source->zelements; + + break; + + case PRODUCT_MRGTDK : + + ccStep = ccProduct | CC_PRODUCT_MRGTDK; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPTDKSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + /* Mantis 2091: the image is read bottom up, so the TDK comes before the TOS */ + status = CropCopyFromSibAndUnpack (sib.Tm, sib.Xdim, TM_YDIM, sib.Xdim, IMGMRG_TDK_H, 0, 0, &(((unsigned int *)source->data)[i * sib.Xdim * IMGMRG_TDK_H])); + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* adjust product sizes */ + source->yelements = IMGMRG_TDK_H; + source->nelements = source->xelements * source->yelements * source->zelements; + + if (source->nelements >= 2) + SDPRINT("source Input data are: %d %d .. %d\n", ((unsigned int *)source->data)[0], ((unsigned int *)source->data)[1], ((unsigned int *)source->data)[source->nelements-1]); + + break; + + case PRODUCT_MRGTOS : + + ccStep = ccProduct | CC_PRODUCT_MRGTOS; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* Mantis 1909: set group stacking order */ + CrIaCopy (SDPTOSSTCKORDER_ID, &stackGroup); + if (stackGroup > source->zelements) + stackGroup = source->zelements; + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure */ + if (CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY) == 0) + { + /* error gets reported by setup function */ + break; + } + + /* Mantis 2091: the image is read bottom up, so the TOS comes after the TDK */ + status = CropCopyFromSibAndUnpack (sib.Tm, sib.Xdim, TM_YDIM, sib.Xdim, IMGMRG_TOS_H, 0, IMGMRG_TDK_H, &(((unsigned int *)source->data)[i * sib.Xdim * IMGMRG_TOS_H])); + + if (status == -1) /* could not crop */ + return 0; + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + /* adjust product sizes */ + source->yelements = IMGMRG_TOS_H; + source->nelements = source->xelements * source->yelements * source->zelements; + + if (source->nelements >= 2) + SDPRINT("source Input data are: %d %d .. %d\n", ((unsigned int *)source->data)[0], ((unsigned int *)source->data)[1], ((unsigned int *)source->data)[source->nelements-1]); + + break; + + case PRODUCT_DISABLE : + default : + + ccStep = ccProduct | CC_PRODUCT_DISABLE; + CrIaPaste(CCSTEP_ID, &ccStep); + + source->xelements = 0; + source->yelements = 0; + source->zelements = 0; + source->nelements = 0; + + break; + } + + /*************************************************************** + Run through the different steps of the science data processing + Each step assumes to have the input data in the source buffer. + If a step finishes with data in the dest buffer, it needs to + switch the pointers afterwards. The last step, however, shall + leave its output in the location desired by parameter. + Note that all of this assumes, that the source can be + overwritten! + ****************************************************************/ + + /*********************/ + /* Preproc */ + /*********************/ + + switch (preproc) + { + + case PREPROC_NLC : + + ccStep = ccProduct | CC_PREPROC_NLC; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out the old nonlinearity correction\n"); + + NlcSplineCorr28 ((unsigned int *)(source->data), source->nelements); + + break; + + case PREPROC_NLC2 : + + ccStep = ccProduct | CC_PREPROC_NLC2; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out the new nonlinearity correction NLC2\n"); + + if (sdbstate != CrIaSdb_CONFIG_WIN) + { + /* NLC2 is only effective for window mode */ + break; + } + + /* NLC2 block */ + { + float ftemp; + unsigned short utemp16; + unsigned int framelen = source->xelements * source->yelements; + double nlcBias0, nlcBias, nlcGain0, nlcGain; + + union + { + unsigned int ui; + float f; + } VoltFeeVss, VoltFeeVrd, VoltFeeVod, VoltFeeVog, TempFeeCcd; + + unsigned char readoutFreq; + + /* the NLC2 reads the measured bias from the SibPhotometry values, + so we have to again fetch the SIB structure of each frame and loop over the frames, + like it was done in the PRODUCT step (and in the initial NLC2 step) */ + + CrIaCopy(SIBOUT_ID, &sibOut); /* sibOut was modified in the PRODUCT step, we fetch it again */ + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure using current sibOut (the compression is the SIB consumer, thus it reads from "out") */ + status = 0; + if (sdbstate == CrIaSdb_CONFIG_WIN) + status = CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + status = CrIaSetupSibFull (&sib, sibOut); + + if (status == 0) + { + /* error gets reported by setup function */ + break; + } + + sibHeader = (struct SibHeader *) sib.Header; + sibPhotometry = (struct SibPhotometry *) sib.Photometry; + + nlcBias = (double) sibPhotometry->annulus2; + VoltFeeVss.ui = sibHeader->VoltFeeVss; + VoltFeeVrd.ui = sibHeader->VoltFeeVrd; + VoltFeeVod.ui = sibHeader->VoltFeeVod; + VoltFeeVog.ui = sibHeader->VoltFeeVog; + TempFeeCcd.ui = sibHeader->TempFeeCcd; + readoutFreq = GetRf(sibHeader->CcdTimingScriptId & 0xff); + + /* calculate gain from voltages and CCD temp */ + nlcGain = (double) NlcCalcGain (VoltFeeVss.f, VoltFeeVrd.f, VoltFeeVod.f, VoltFeeVog.f, TempFeeCcd.f); + + /* get Bias0 and Gain0 from data pool array D */ + CrIaCopyArrayItem (NLCCOEFF_D_ID, &ftemp, NLCI_Bias0); + nlcBias0 = (double) ftemp; + CrIaCopyArrayItem (NLCCOEFF_D_ID, &ftemp, NLCI_Gain0); + nlcGain0 = (double) ftemp; + + /* carry out the correction */ + NlcSplineCorr16 ((unsigned int *)(source->data) + i * framelen, nlcBias, nlcBias0, nlcGain, nlcGain0, framelen, readoutFreq); + + /* write gain0 and bias0 to the SIB */ + sibPhotometry->centrum = (float) nlcGain0; + sibPhotometry->annulus1 = (float) nlcBias0; + /* NOTE: nlcBias is already in annulus2 */ + + /* write gain0 and bias0 to the DataPool */ + utemp16 = (unsigned short) nlcBias0; + CrIaPaste(SDPGLOBALBIAS_ID, &utemp16); + ftemp = (float) nlcGain0; + CrIaPaste(SDPGLOBALGAIN_ID, &ftemp); + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + } + else + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressFull); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeFull, (unsigned int)sibNFull, SIBOUT_FULL_XIB); + } + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + } /* NLC2 block */ + + break; + + case PREPROC_NLCPHOT : + + ccStep = ccProduct | CC_PREPROC_NLCPHOT; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out the nonlinearity correction + quick photometry\n"); + + NlcSplineCorr28 ((unsigned int *)(source->data), source->nelements); + + /* + no break here + in order to quiet the fallthrough warning, we use a useless goto... + */ + goto SDP_PREPROC_PHOT; + + case PREPROC_PHOT : + +SDP_PREPROC_PHOT: + + ccStep = ccProduct | CC_PREPROC_PHOT; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out quick photometry\n"); + + /* the quick photometry needs to write back the SibPhotometry values to the SIB, + so we have to again fetch the SIB structure of each frame and loop over the frames, + like it was done in the PRODUCT step */ + + CrIaCopy(SIBOUT_ID, &sibOut); /* sibOut was modified in the PRODUCT step, we fetch it again */ + + for (i=0; i < source->zelements; i++) + { + /* setup SIB structure using current sibOut (the compression is the SIB consumer, thus it reads from "out") */ + status = 0; + if (sdbstate == CrIaSdb_CONFIG_WIN) + status = CrIaSetupSibWin (&sib, sibOut, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + status = CrIaSetupSibFull (&sib, sibOut); + + if (status == 0) + { + /* error gets reported by setup function */ + break; + } + + sibPhotometry = (struct SibPhotometry *) sib.Photometry; + + photData.datatype = source->datatype; + photData.xelements = source->xelements; + photData.yelements = source->yelements; + photData.zelements = source->zelements; + photData.nelements = source->nelements; + photData.data = (unsigned int *)source->data + i * source->xelements * source->yelements; + + QuickPhotometry (&photData, (unsigned int *) swapbuffer->data, sibPhotometry); + + if (i < source->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + } + else + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressFull); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeFull, (unsigned int)sibNFull, SIBOUT_FULL_XIB); + } + + /* NOTE: if SIBOUT couldn't be incremented, the last one is cloned */ + + sibOut = newSibOut; + } + } + + break; + + case PREPROC_NONE : + default : + + ccStep = ccProduct | CC_PREPROC_NONE; + CrIaPaste(CCSTEP_ID, &ccStep); + + break; + } + + /*********************/ + /* Lossy 1 */ + /*********************/ + + switch (lossy1) + { + + case LOSSY1_COADD : + + ccStep = ccProduct | CC_LOSSY1_COADD; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- calculate the coadded frame\n"); + + status = CoAdd32s ((int *)(source->data), source->xelements, source->yelements, source->zelements, (int *)(compressed->data)); /* NOTE: this could be done in place */ + + if (status == 0) + source->zelements = 0; + else + source->zelements = 1; + + /* adapt source elements */ + source->nelements = source->xelements * source->yelements * source->zelements; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY1_MEAN : + + SDPRINT("- calculate the average frame\n"); + + status = Average32s ((int *)(source->data), source->xelements, source->yelements, source->zelements, (int *)(compressed->data)); /* NOTE: this could be done in place */ + + if (status == 0) + source->zelements = 0; + else + source->zelements = 1; + + /* adapt source elements */ + source->nelements = source->xelements * source->yelements * source->zelements; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY1_GMEAN : + + ccStep = ccProduct | CC_LOSSY1_GMEAN; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- averaging frames in groups\n"); + + source->zelements = ProcessGroups32s ((int *)(source->data), source->xelements, source->yelements, source->zelements, stackGroup, 0, (int *)(compressed->data)); /* NOTE: this could be done in place */ + + /* adapt source elements */ + source->nelements = source->xelements * source->yelements * source->zelements; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY1_GCOADD : + + ccStep = ccProduct | CC_LOSSY1_GCOADD; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- coadding frames in groups\n"); + + source->zelements = ProcessGroups32s ((int *)(source->data), source->xelements, source->yelements, source->zelements, stackGroup, 1, (int *)(compressed->data)); /* NOTE: this could be done in place */ + + /* adapt source elements */ + source->nelements = source->xelements * source->yelements * source->zelements; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY1_NONE : + default : + + ccStep = ccProduct | CC_LOSSY1_NONE; + CrIaPaste(CCSTEP_ID, &ccStep); + + break; + } + + + /*********************/ + /* Lossy 2 */ + /*********************/ + + switch (lossy2) + { + + case LOSSY2_3STAT : + + ccStep = ccProduct | CC_LOSSY2_3STAT; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- calculate mean, stdev, median\n"); + + FrameElements = source->xelements * source->yelements; + w = 0; /* write counter for output words */ + for (i=0; i < source->zelements; i++) + { + MeanSigma ((int *)source->data + i*FrameElements, FrameElements, &(stat.mean), &(stat.stdev)); + stat.median = (unsigned int) Median ((int *)source->data + i*FrameElements, FrameElements); + + /* enter the values in the output array */ + ((float *)(compressed->data))[w] = stat.mean; + w++; + ((float *)(compressed->data))[w] = stat.stdev; + w++; + ((unsigned int *)(compressed->data))[w] = stat.median; + w++; + } + + /* adjust array metadata */ + source->datatype = DATATYPE_UINT32; + source->xelements = 3; + source->yelements = 1; + source->zelements = i; + source->nelements = w; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY2_3STATUI_ROW : + + ccStep = ccProduct | CC_LOSSY2_3STATUI_ROW; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- calculate mean, stdev, median in uint for every row\n"); + + CrIaCopy(SDP3STATAMPL_ID, &l); + + FrameElements = source->xelements * source->yelements; + w = 0; /* write counter for output words */ + for (i=0, j=0; i < source->zelements; i++) + { + for (j=0; j < source->yelements; j++) + { + MeanSigma ((int *)source->data + i*FrameElements + j*source->xelements, source->xelements, &(stat.mean), &(stat.stdev)); + stat.median = (unsigned int) Median ((int *)source->data + i*FrameElements + j*source->xelements, source->xelements); + + /* enter the values in the output array */ + ((unsigned int *)(compressed->data))[w] = (unsigned int) roundf(stat.mean); + w++; + ((unsigned int *)(compressed->data))[w] = (unsigned int) roundf(ampl * stat.stdev); + w++; + ((unsigned int *)(compressed->data))[w] = stat.median; + w++; + } + } + + /* adjust array metadata */ + source->datatype = DATATYPE_UINT32; + source->xelements = 3; + source->yelements = j; + source->zelements = i; + source->nelements = w; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY2_3STATUI_COL : + + ccStep = ccProduct | CC_LOSSY2_3STATUI_COL; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- calculate mean, stdev, median in uint for every column\n"); + + CrIaCopy(SDP3STATAMPL_ID, &l); + + FrameElements = source->xelements * source->yelements; + w = 0; /* write counter for output words */ + for (i=0; i < source->zelements; i++) + { + /* transpose frame */ + Transpose2Di ((int *)source->data, source->xelements, source->yelements, (int *)swapbuffer->data); + + for (j=0; j < source->xelements; j++) /* x is now the y dimension due to the transpose */ + { + /* calculate statistics */ + MeanSigma ((int *)swapbuffer->data + i*FrameElements + j*source->yelements, source->yelements, &(stat.mean), &(stat.stdev)); + stat.median = (unsigned int) Median ((int *)swapbuffer->data + i*FrameElements + j*source->yelements, source->yelements); + + /* enter the values in the output array */ + ((unsigned int *)(compressed->data))[w] = (unsigned int) roundf(stat.mean); + w++; + ((unsigned int *)(compressed->data))[w] = (unsigned int) roundf(ampl * stat.stdev); + w++; + ((unsigned int *)(compressed->data))[w] = stat.median; + w++; + } + } + + /* adjust array metadata */ + source->datatype = DATATYPE_UINT32; + source->xelements = source->xelements; + source->yelements = 3; + source->zelements = i; + source->nelements = w; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY2_3STATUI : + + ccStep = ccProduct | CC_LOSSY2_3STATUI; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- calculate mean, stdev, median in uint\n"); + + CrIaCopy(SDP3STATAMPL_ID, &l); + + FrameElements = source->xelements * source->yelements; + + w = 0; /* write counter for output words */ + for (i=0; i < source->zelements; i++) + { + MeanSigma ((int *)source->data + i*FrameElements, FrameElements, &(stat.mean), &(stat.stdev)); + stat.median = (unsigned int) Median ((int *)source->data + i*FrameElements, FrameElements); + + /* enter the values in the output array */ + ((unsigned int *)(compressed->data))[w] = (unsigned int) roundf(stat.mean); + w++; + ((unsigned int *)(compressed->data))[w] = (unsigned int) roundf(ampl * stat.stdev); + w++; + ((unsigned int *)(compressed->data))[w] = stat.median; + w++; + } + + /* adjust array metadata */ + source->datatype = DATATYPE_UINT32; + source->xelements = 3; + source->yelements = i; + source->zelements = 1; + source->nelements = w; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY2_4STAT : + + ccStep = ccProduct | CC_LOSSY2_4STAT; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- calculate mean, stdev, median and MAD for every frame\n"); + + FrameElements = source->xelements * source->yelements; + + w = 0; /* write counter for output words */ + for (i=0; i < source->zelements; i++) + { + MeanSigma ((int *)source->data + i*FrameElements, FrameElements, &(stat.mean), &(stat.stdev)); + stat.median = (unsigned short) Median ((int *)source->data + i*FrameElements, FrameElements); + stat.mad = (unsigned short) MedAbsDev ((int *)source->data + i*FrameElements, FrameElements, stat.median, (int *)swapbuffer->data); /* use swapbuf as workbuffer */ + + /* enter the values in the output array */ + ((float *)(compressed->data))[w] = stat.mean; + w++; + ((float *)(compressed->data))[w] = stat.stdev; + w++; + ((unsigned int *)(compressed->data))[w] = stat.median; + w++; + ((unsigned int *)(compressed->data))[w] = stat.mad; + w++; + } + + /* adjust array metadata */ + source->datatype = DATATYPE_UINT32; + source->xelements = 4; + source->yelements = i; + source->zelements = 1; + source->nelements = w; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + + case LOSSY2_CIRCMASK : + + { + unsigned int maskvalue; + unsigned int xoff, yoff; + + ccStep = ccProduct | CC_LOSSY2_CIRCMASK; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying circular mask for every frame\n"); + + FrameElements = source->xelements * source->yelements; + + for (i=0; i < source->zelements; i++) + { + /* use average of image as mask value */ + maskvalue = (unsigned int) roundf (Mean32((int *)source->data + i*FrameElements, FrameElements)); + + xoff = RINGEXTRACT_XOFF; + yoff = RINGEXTRACT_YOFF; + + /* mask in place */ + CircMask32 ((unsigned int *)source->data + i*FrameElements, source->xelements, source->yelements, xoff, yoff, productRadius, maskvalue, (unsigned int *)source->data + i*FrameElements); + } + + /* no change of source dimensions or type */ + + break; + } + + case LOSSY2_CIRCEXTRACT : + + { + int extracted = 0; + unsigned int xoff, yoff; + + ccStep = ccProduct | CC_LOSSY2_CIRCEXTRACT; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying circular extraction for frames: %d\n", source->zelements); + + FrameElements = source->xelements * source->yelements; + + /* apply for the other frames */ + for (i=0; i < source->zelements; i++) + { + xoff = RINGEXTRACT_XOFF; + yoff = RINGEXTRACT_YOFF; + + extracted = RingExtract32 ((unsigned int *)source->data + i*FrameElements, source->xelements, source->yelements, xoff, yoff, 0.0f, productRadius, (unsigned int *)compressed->data + i*extracted); + } + + /* adjust array metadata */ + source->datatype = DATATYPE_UINT32; + source->xelements = extracted; + source->yelements = 1; + source->nelements = source->xelements * source->yelements * source->zelements; + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + + break; + } + + case LOSSY2_NONE : + default : + + ccStep = ccProduct | CC_LOSSY2_NONE; + CrIaPaste(CCSTEP_ID, &ccStep); + + break; + } + + + /*********************/ + /* Lossy 3 */ + /*********************/ + + switch (lossy3) + { + + case LOSSY3_ROUND1 : + + ccStep = ccProduct | CC_LOSSY3_ROUND1; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying 1-bit rounding for %d elements\n", source->zelements); + + BitRounding32u((unsigned int *)(source->data), 1, source->nelements); + + break; + + case LOSSY3_ROUND2 : + + ccStep = ccProduct | CC_LOSSY3_ROUND2; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying 2-bit rounding for %d elements\n", source->zelements); + + BitRounding32u((unsigned int *)(source->data), 2, source->nelements); + + break; + + case LOSSY3_ROUND3 : + + ccStep = ccProduct | CC_LOSSY3_ROUND3; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying 3-bit rounding for %d elements\n", source->zelements); + + BitRounding32u((unsigned int *)(source->data), 3, source->nelements); + + break; + + case LOSSY3_ROUND4 : + + ccStep = ccProduct | CC_LOSSY3_ROUND4; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying 4-bit rounding for %d elements\n", source->zelements); + + BitRounding32u((unsigned int *)(source->data), 4, source->nelements); + + break; + + case LOSSY3_ROUND5 : + + ccStep = ccProduct | CC_LOSSY3_ROUND5; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying 5-bit rounding for %d elements\n", source->zelements); + + BitRounding32u((unsigned int *)(source->data), 5, source->nelements); + + break; + + case LOSSY3_ROUND6 : + + ccStep = ccProduct | CC_LOSSY3_ROUND6; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- applying 6-bit rounding for %d elements\n", source->zelements); + + BitRounding32u((unsigned int *)(source->data), 6, source->nelements); + + break; + + case LOSSY3_NONE : + default : + + ccStep = ccProduct | CC_LOSSY3_NONE; + CrIaPaste(CCSTEP_ID, &ccStep); + + break; + } + + + /*********************/ + /* lossy CRC */ + /*********************/ + + /* after the lossy steps the CRC is calculated */ + compressed->lossyCrc = 0xffff; + CrIaCopy(SDPCRC_ID, &sdpCrc); + if (sdpCrc == 1) + { + compressed->lossyCrc = (unsigned int) Checksum_CRC16_32 ((unsigned int *)(source->data), source->nelements * TYPESIZE(source->datatype)); + } + + /* also paste dimensions now */ + compressed->datatype = source->datatype; + compressed->xelements = source->xelements; + compressed->yelements = source->yelements; + compressed->zelements = source->zelements; + compressed->nelements = source->nelements; + + + /*********************/ + /* Decorr */ + /*********************/ + + switch (decorr) + { + + case DECORR_DIFF : + + ccStep = ccProduct | CC_DECORR_DIFF; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out 1D differencing on %d samples\n", source->nelements); + + Delta32 ((int *)source->data, source->nelements); + Map2Pos32 ((int *)source->data, source->nelements); + + break; + + case DECORR_KEYFR : + + ccStep = ccProduct | CC_DECORR_KEYFR; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out keyframe subtraction on %d (%dx%d) frames\n", source->zelements, source->xelements, source->yelements); + + FrameSubtract(source); + + Map2Pos32 ((int *)source->data + source->xelements, source->nelements - source->xelements); /* NOTE: do not map the 1st line (the keyframe is assumed to be positive) */ + + break; + + case DECORR_IWT1 : + + ccStep = ccProduct | CC_DECORR_IWT1; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out 1D IWT/PD on %d samples\n", source->nelements); + IntegerWaveletTransform_Decompose ((int *)source->data, (int *)compressed->data, source->nelements); + /* note: elements and datatype stay the same */ + + /* shift source pointer to the processed data and vice versa */ + SWITCH_PTRS(source->data, compressed->data); + Map2Pos32 ((int *)source->data, source->nelements); + + break; + + case DECORR_IWT2 : + + { + /* in order to transform 3d data sets, we use y*z for the y dimension. So we actually transform a "film strip". */ + unsigned int source_xelements = source->xelements; + unsigned int source_yelements = source->yelements * source->zelements; + + ccStep = ccProduct | CC_DECORR_IWT2; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out 2D IWT/PD on %d x %d = %d samples\n", source_xelements, source_yelements, source->nelements); + + SDPRINT("D0: %d %d .. %d\n", ((int *)source->data)[0], ((int *)source->data)[1], ((int *)source->data)[source->nelements-1]); + + /* transform all lines */ + for (i=0; i < source_yelements; i++) + IntegerWaveletTransform_Decompose ((int *)source->data + i*source_xelements, (int *)compressed->data + i*source_xelements, source_xelements); + + /*SDPRINT("D1: %d %d .. %d\n", ((int *)compressed->data)[0], ((int *)compressed->data)[1], ((int *)compressed->data)[source->nelements-1]); */ + + /* transpose */ + Transpose2Di ((int *)compressed->data, source_xelements, source_yelements, (int *)source->data); + + /*SDPRINT("D4: %d %d .. %d\n", ((int *)source->data)[0], ((int *)source->data)[1], ((int *)source->data)[source->nelements-1]); */ + + /* loop over all transposed lines */ + for (i=0; i < source_xelements; i++) + IntegerWaveletTransform_Decompose ((int *)source->data + i*source_yelements, (int *)compressed->data + i*source_yelements, source_yelements); + + /*SDPRINT("D3: %d %d .. %d\n", ((int *)compressed->data)[0], ((int *)compressed->data)[1], ((int *)compressed->data)[source->nelements-1]); */ + + /* For the entropy it is not needed to transpose again, but for nonsquare image dimensions it is nice. */ + Transpose2Di ((int *)compressed->data, source_yelements, source_xelements, (int *)source->data); + + /*SDPRINT("D4: %d %d .. %d\n", ((int *)source->data)[0], ((int *)source->data)[1], ((int *)source->data)[source->nelements-1]); */ + + Map2Pos32((int *)source->data, source->nelements); + break; + } + + case DECORR_NONE : + default : + + ccStep = ccProduct | CC_DECORR_NONE; + CrIaPaste(CCSTEP_ID, &ccStep); + + break; + } + +#ifdef DEBUGFILES + + /* save fits file for debug purposes */ + if (product == PRODUCT_IMAGETTES) + { + strncpy (debugfilename, "!Debug_Image_DECORR.fits\0", 256); /* ! means overwrite */ + SDPRINT(" the source buffer has: %d %d %d .. %d\n", ((int *)(source->data))[0], ((int *)(source->data))[1], ((int *)(source->data))[2], ((int *)(source->data))[source->nelements-1]); + saveFitsImage (debugfilename, source); + } +#endif + + /*********************/ + /* Llc */ + /*********************/ + + switch (llc) + { + + case LLC_RZIP : + + ccStep = ccProduct | CC_LLC_RZIP; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out RZip on %d samples\n", source->nelements); + SDPRINT(" U: %d %d %d .. %d CRC %04x\n", ((unsigned int *)(source->data))[0], ((unsigned int *)(source->data))[1], ((unsigned int *)(source->data))[2], ((unsigned int *)(source->data))[source->nelements-1], Checksum_CRC16_32 ((unsigned int *)(source->data), 4*source->nelements)); + + if (swapbuffer->nelements < source->nelements) /* alpha channel has same size as input for speed reason */ + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT(ANSI_COLOR_RED "ERROR: (RZIP) Not enough RAM for work buffer!\n" ANSI_COLOR_RESET); +#else + evt_data[0] = ccStep; + evt_data[1] = 0; + SdpEvtRaise(3, CRIA_SERV5_EVT_SDP_NOMEM, evt_data, 4); +#endif + } + + /* compress the buffer */ + /* we skip one output word for the range codes */ + compressed->llcsize = RZip32 ((unsigned int *)(source->data), source->nelements, (unsigned int *)(compressed->data) + 1, (unsigned int *)swapbuffer->data, 5); + /* NOTE: data pool variables RZIP_ITER1, RZIP_ITER2, RZIP_ITER3, RZIP_ITER4 are not used, + because there is little gain from iterative application on the many floats in the header. */ + + ((unsigned int *)(compressed->data))[0] = 5 << 24; + compressed->llcsize += 4; + + SDPRINT(" compressed output is %d bytes\n", compressed->llcsize); + SDPRINT(" C: %08x %08x %08x .. %08x\n", ((unsigned int *)(compressed->data))[0], ((unsigned int *)(compressed->data))[1], ((unsigned int *)(compressed->data))[2], ((unsigned int *)(compressed->data))[(compressed->llcsize + 3)/4 - 1]); + + break; + + case LLC_ARI1 : + + ccStep = ccProduct | CC_LLC_ARI1; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- carrying out semi-adaptive Arithmetic compression on %d samples\n", source->nelements); + SDPRINT(" U: %d %d %d .. %d CRC %04x\n", ((unsigned int *)(source->data))[0], ((unsigned int *)(source->data))[1], ((unsigned int *)(source->data))[2], ((unsigned int *)(source->data))[source->nelements-1], Checksum_CRC16_32 ((unsigned int *)(source->data), 4*source->nelements)); + + if (swapbuffer->nelements < (source->nelements + 257 + 258)) /* magic numbers (c) RO */ + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT(ANSI_COLOR_RED "ERROR: (ARI1) Not enough RAM for work buffer!\n" ANSI_COLOR_RESET); +#else + evt_data[0] = ccStep; + evt_data[1] = 0; + SdpEvtRaise(3, CRIA_SERV5_EVT_SDP_NOMEM, evt_data, 4); +#endif + } + + /* compress the buffer */ + compressed->llcsize = fmari_compress((unsigned int *)(source->data), source->nelements, (unsigned int *)(compressed->data), (unsigned int *)swapbuffer->data, 0); + compressed->llcsize *= 4; /* ARI counts words, we want bytes */ + + SDPRINT(" compressed output is %d bytes\n", compressed->llcsize); + SDPRINT(" C: %08x %08x %08x .. %08x\n", ((unsigned int *)(compressed->data))[0], ((unsigned int *)(compressed->data))[1], ((unsigned int *)(compressed->data))[2], ((unsigned int *)(compressed->data))[(compressed->llcsize + 3)/4 - 1]); + + break; + + case LLC_PACK16 : + + ccStep = ccProduct | CC_LLC_PACK16; + CrIaPaste(CCSTEP_ID, &ccStep); + + SDPRINT("- simple packing of %d samples in 16 bits (with truncation)\n", source->nelements); + if (source->nelements >= 3) + SDPRINT(" U: %08x %08x %08x .. %08x\n", ((unsigned int *)(source->data))[0], ((unsigned int *)(source->data))[1], ((unsigned int *)(source->data))[2], ((unsigned int *)(source->data))[source->nelements - 1]); + + PackU16FromU32 ((uint32_t *)(source->data), source->nelements, (uint32_t *)(compressed->data), UNPACK_NOSWAP); + compressed->llcsize = source->nelements * 2; + + SDPRINT(" compressed output is %d bytes\n", compressed->llcsize); + if (source->nelements >= 3) + SDPRINT(" C: %08x %08x %08x .. %08x\n", ((unsigned int *)(compressed->data))[0], ((unsigned int *)(compressed->data))[1], ((unsigned int *)(compressed->data))[2], ((unsigned int *)(compressed->data))[(compressed->llcsize + 3)/4 - 1]); + + break; + + case LLC_NONE : + default : + + ccStep = ccProduct | CC_LLC_NONE; + CrIaPaste(CCSTEP_ID, &ccStep); + + /* if nothing is to be done at all, we still have to enter the "compressed" size */ + compressed->llcsize = source->nelements * TYPESIZE(source->datatype); + + /* SDPRINT("at this point, the data are: %u %u %u\n", ((unsigned int *)(source->data))[0],((unsigned int *)(source->data))[1],((unsigned int *)(source->data))[2]); */ + + /* and copy the data */ + sram2memcpy(compressed->data, source->data, compressed->llcsize); + + break; + } + + /* The steps above finish with the compressed data in compressed->data */ + /* However, we don't know if this is the true (non-SWITCHED) buffer. */ + /* We have to make sure that the compressed data are in the originally */ + /* reserved buffer, administered by the right structure */ + if ((unsigned long)(compressed->data) != (unsigned long)(comprdata)) + { + sram2memcpy(source->data, compressed->data, compressed->llcsize); + SWITCH_PTRS(source->data, compressed->data); + } + + /* NOTE: this strategy could be revised to avoid extra copy, + taking advantage of the location parameter. */ + if (location == SRCBUF) + { + /* copy data from dest back */ + sram2memcpy(source->data, compressed->data, compressed->llcsize); + } + + return 0; +} + diff --git a/CompressionEntity/src/SdpAlgorithmsImplementation.h b/CompressionEntity/src/SdpAlgorithmsImplementation.h new file mode 100644 index 0000000000000000000000000000000000000000..232d4f3b94f9451d44a94f1422b8101654e2e0e3 --- /dev/null +++ b/CompressionEntity/src/SdpAlgorithmsImplementation.h @@ -0,0 +1,145 @@ +/** + * @file SdpAlgorithmsImplementation.h + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef SDP_ALGORITHMS_IMPLEMENTATION_H +#define SDP_ALGORITHMS_IMPLEMENTATION_H + +#include "SdpBuffers.h" +#include "IfswMath.h" + +#define FLOATASUINT(f) ( *((unsigned int *)(&f)) ) + +#define UINTASFLOAT(u) ( *((float *)(&u)) ) + +#define FILLBYTE(bpos) (7 - ((bpos+7)%8)) + +#define SWITCH_PTRS(ptra, ptrb) { void *tmp; tmp = (void *)ptra; ptra = ptrb; ptrb = tmp; } + +#define SWITCH_VALUES_UI(vala, valb) { unsigned int tmp; tmp = vala; vala = valb; valb = tmp; } + +/** @{ + * @brief retrieve masked value from the key for the respective step + */ +#define GETPRODUCT(key) (key & 0xf0000000) +#define GETPREPROC(key) (key & 0x0f000000) +#define GETLOSSY1(key) (key & 0x00f00000) +#define GETLOSSY2(key) (key & 0x000f0000) +#define GETDECORR(key) (key & 0x00000f00) +#define GETLLC(key) (key & 0x0000000f) +/* @} */ + +/** !@{ + * @brief macros to unify the function calls of the different bitstream access functions + */ +#define PUTNBITS(putval, putoff, putn, putptr) (PutNBits32 (putval, putoff, putn, (unsigned int *)putptr)) +#define GETNBITS(getval, getoff, getn, getptr) { unsigned int gv; GetNBits32 (&gv, getoff, getn, (unsigned int *)getptr); getval = gv; } +#define PUTBYTE(putval, putoff, putptr) (PutByte32 ((putval), (putoff) >> 3, (unsigned int *)putptr)) +#define GETBYTE(getval, getoff, getptr) { getval = GetByte32 ((getoff) >> 3, (unsigned int *)getptr); } +/** !@} */ + + +#ifdef DEBUGFILES +extern char debugfilename[256]; +void saveFitsImage (char *filename, struct ScienceBuf *imgdata); +#endif + + +#define RINGEXTRACT_XOFF 0 +#define RINGEXTRACT_YOFF 0 +#define RINGEXTRACT_MASKVAL 0 + + +/** + * @brief replacement of the floor function after a division by 2^n + * @param a the integer value to operate on + * @param n the number of bits to shift + * @returns a/2^n + */ + +#define FLOORSH(a,n) (a >> n) + + +void *sram2memcpy(void *dest, const void *src, unsigned long int n); + +void *sram2memcpy_aligned(void *dest, const void *src, unsigned long int n); + +unsigned short *sram1tosram2_shorts (unsigned short *p_src, unsigned int nshorts, unsigned short *p_dest_short); + +void PutBit32 (unsigned int value, unsigned int bitOffset, unsigned int *destAddr); + +unsigned int GetBit32 (unsigned int bitOffset, unsigned int *src); + +unsigned int PutNBits32 (unsigned int value, unsigned int bitOffset, unsigned int nBits, unsigned int *destAddr); + +unsigned int GetNBits32 (unsigned int *p_value, unsigned int bitOffset, unsigned int nBits, unsigned int *srcAddr); + +void PutByte32 (unsigned char value, unsigned int byteOffset, unsigned int *destAddr); + +unsigned char GetByte32 (unsigned int byteOffset, unsigned int *srcAddr); + + +int CoAdd32s (int *source, unsigned short Xdim, unsigned short Ydim, unsigned short N, int *dest); + +int Average32s (int *source, unsigned short Xdim, unsigned short Ydim, unsigned short N, int *dest); + +int ProcessGroups32s (int *source, unsigned short Xdim, unsigned short Ydim, unsigned short Zdim, unsigned char N, unsigned char operation, int *dest); + +int CropCopyFromSibAndUnpack (unsigned int *source, unsigned short Xdim, unsigned short Ydim, unsigned short XcDim, unsigned short YcDim, unsigned short XcStart, unsigned short YcStart, unsigned int *dest); + +unsigned int CountOnes16 (unsigned short value); + +void ColSelect16_32 (unsigned int *data, unsigned int y, unsigned short mask, unsigned int *output); + +int CircMask32 (unsigned int *source, unsigned int Xdim, unsigned int Ydim, int xoff, int yoff, float radius, unsigned int maskval, unsigned int *dest); + +int RingExtract32 (unsigned int *source, unsigned int Xdim, unsigned int Ydim, int xoff, int yoff, float iradius, float oradius, unsigned int *dest); + +unsigned short Checksum_CRC16_32 (unsigned int *data, unsigned int N); + + +void MeanSigma (int *data, int len, float *m, float *sig); + +#ifdef GROUNDSW +int compint (const void *a, const void *b); +#endif + +int Median (int *data, int len); + +int MedAbsDev (int *data, int len, int median, int* swap); + +typedef struct { + int symbol; + int freq; +} symentry ; + + +int IntegerWaveletTransform_Core (int *Input, int *Output, unsigned int n); + +int IntegerWaveletTransform_Decompose (int *Input, int *Output, unsigned int n); + +void Delta32 (int *buf, int words); + +void Map2Pos32 (int *buffer, unsigned int N); + +void Transpose2Di (int *src, unsigned int src_xdim, unsigned int src_ydim, int *dest); + +int FrameSubtract(struct ScienceBuf *fdata); + +int Compress(struct ScienceBuf *source, struct ComprEntStructure *cestruct, unsigned int CeKey, struct CompressedBuf *compressed, int location, struct ScienceBuf *swapbuffer); + + +#endif diff --git a/CompressionEntity/src/SdpAlgorithmsImplementationLlc.c b/CompressionEntity/src/SdpAlgorithmsImplementationLlc.c new file mode 100644 index 0000000000000000000000000000000000000000..6eeacc5acc59bce511b5c1672172daaadd8c3709 --- /dev/null +++ b/CompressionEntity/src/SdpAlgorithmsImplementationLlc.c @@ -0,0 +1,818 @@ +/** + * @file SdpAlgorithmsImplementationLlc.c + * @ingroup SdpAlgorithmsImplementationLlc + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * + * @defgroup SdpAlgorithmsImplementationLlc + * @ingroup Sdp + * + * @brief various lossless compression algorithms used in the data processing chain + * + */ + +#include <CrIaDataPool.h> /* for reporting the spillctr */ +#include <CrIaDataPoolId.h> /* for reporting the spillctr */ + +#include "SdpAlgorithmsImplementationLlc.h" +#include "SdpAlgorithmsImplementation.h" /* for putnbits getnbits */ +#include <stdio.h> /* for SDPRINT */ + + +/** + * @brief minimalistic lexical (kind of) lossless compressor. + * @detail published in "Herschel/PACS On-board Reduction/Compression Software Implementation", + * R. Ottensamer et al., Proceedings of the SPIE, Astronomical Telescopes and Instrumentation, 2004. + * @date 22.12.2001, revised for CHEOPS in Mar 2017 -- yeah! + * @param source array of input samples to compress + * @param len number of samples to compress + * @param cstream buffer to save the destination bitstream + * @param alpha work buffer, imagine as alpha channel. Should allow len elements. + * @param range saturated at 31, defines the length of the look ahead window, basically len = 2^range - 1 + * @note this is not exhaustive, it can be applied in a few iterations, e.g. with ranges 5-3-5 + * @returns size in bytes of the compressed buffer + */ + +unsigned int RZip32 (unsigned int *source, unsigned int len, unsigned int *cstream, unsigned int *alpha, unsigned int range) +{ + unsigned int cmprSize; /* compressed size in bytes */ + unsigned int maxoff; /* maximum offset possible with the current range setting */ + unsigned int symbol, ctr, i; + + /* inner loop variables to carry out the entry search */ + unsigned int sctr; /* search counter, to find next equal symbol */ + unsigned int uctr; /* number of symbols left out during the search */ + unsigned int wctr; /* counts destination bits */ + unsigned int lastpos; /* holds the positions where symbols occur */ + + if (range == 0) + { + return 0; + } + + /* maximum offset according to the range */ + maxoff = 0xffffffffU >> (32-(range & 31)); + + /* clean the alpha channel */ + for (i=0; i < len; i++) + alpha[i] = 0; + + /* + now loop over the samples + we start filling the bit stream at pos 32 because, later, the 32 first bits will contain a small header with the range and the input size + */ + for (ctr=0, wctr=32; ctr < len; ctr++) + { + /* find a fresh symbol */ + while ((alpha[ctr] == 1) && (ctr < len)) + { + ctr++; + } + + /* read and set to used in alpha channel */ + symbol = source[ctr]; + alpha[ctr] = 1; + + /* encode the symbol */ + PUTNBITS (symbol, wctr, 32, cstream); + wctr += 32; + + /* search the buffer from the symbol onward */ + for (uctr=0, sctr = ctr+1, lastpos = ctr; (sctr < len) & ((sctr-lastpos-uctr) < maxoff); sctr++) + { + /* if the current entry has already been coded before, keep this in mind */ + uctr += (alpha[sctr] == 1); + + /* find and code an offset */ + if (symbol == source[sctr]) + { + /* first code YES */ + PutBit32 (1, wctr, cstream); + wctr++; + + /* code the reduced offset + + That is: (current search position) - (where the last occurrence was) - + - (number of already coded entries) - 1 (0 means neighbour) */ + + PUTNBITS (sctr-lastpos-uctr-1, wctr, range, cstream); + wctr += range; + + /* set the current finding to used state */ + alpha[sctr] = 1; + + /* set the last position of occurrence to the current one */ + lastpos = sctr; + + /* reset the number of uncountable entries */ + uctr = 0; + } + } + + /* we come here if no entry was found for the current symbol */ + if (ctr < len) + { + /* we code a NO */ + PutBit32 (0, wctr, cstream); + wctr++; + } + /* go back until the end of the file is reached */ + } + + /* stuff the stream with bits to be %0 */ + PUTNBITS (0, wctr, FILLBYTE(wctr), cstream); + wctr += FILLBYTE(wctr); + + /* compressed size in bytes */ + cmprSize = wctr >> 3; + + /* write the original size in bytes into the header */ + cstream[0] = len * 4; + + return cmprSize; +} + + +/** + * @brief initialize the model table for arithmetic compression (internal function) + * @param model pointer to the @ref arimodel structure + * @param buffer pointer to the buffer where the table will reside + * @param symbols number of symbols covered by the model (i.e. the number of histogram bins) + */ + +void init_arimodel (struct arimodel *model, unsigned int *buffer, int symbols) +{ + /* note: symbols is counted here without the spill probability */ + model->freqtable = buffer; + model->cptable = model->freqtable + symbols + 1; /* cumulative probability table */ + model->ncptable = model->cptable + 1; /* next cumulative probability table */ + model->spillover = model->ncptable + symbols + 1; /* swap buffer for spillover, i.e. words > 8 Bit */ + model->spillctr = 0; + model->probability = 0; + + return; +} + + +/** + * @brief initialize the cumulative frequency in the model table for arithmetic compression (internal function) + * @param table pointer to the frequency table of the @ref arimodel (freqtable) + * @param cumu pointer to the cumulative frequency table of the @ref arimodel (cptable) + * @param nrows number of symbols covered by the model (i.e. the number of histogram bins) + * @returns last value of the cumulative table, i.e. the number of samples, the sum of the histogram + */ + +int makeCumulative (unsigned int *table, unsigned int nrows, unsigned int *cumu) +{ + unsigned int ctr; + + for (ctr=0; ctr < nrows; ctr++) /* clean table for the "cumulative probabilities" */ + cumu[ctr] = 0; + + for (ctr=0; ctr < nrows; ctr++) /* the new table is +1 in size !! */ + cumu[ctr+1] = cumu[ctr] + table[ctr]; + + return cumu[nrows]; +} + + +/** + * @brief create a new model from a histogram of a buffer + * @param buffer pointer to the buffer of samples to make the histogram + * @param nwords number of samples in that buffer + * @param symbols number of samples to skip at the beginning of the buffer (where the spillover values are) + * @param initval bias value used in every histogram bin. We recommend 1. + * @param model pointer to the @ref armodel structure + */ + +void update_fm_ari_model (unsigned int *buffer, unsigned int nwords, unsigned int symbols, int initval, struct arimodel *model) +{ + unsigned int ctr; + unsigned int value; + + /* start model with 0 or 1 in every entry -> smooth */ + for (ctr=0; ctr < FMARISPILL; ctr++) + model->freqtable[ctr] = initval; + + /* count freqs over the buffer, but leave out the first FMACROWS words for smoothing */ + for (ctr=symbols; ctr < nwords; ctr++) + { + value = buffer[ctr]; + /*SDPRINT ("updatemodel [%d] = %d\n", ctr, buffer[ctr]); */ + + if (value < FMARIROWS) + model->freqtable[value]++; + else + model->freqtable[FMARIROWS]++; /* spillover */ + } + + /* make new (n)cp array */ + model->probability = makeCumulative (model->freqtable, FMARISPILL, model->cptable); + + return; +} + + +/** + * @brief set the initial values for the arithemtic compression model (histogram) for the first chunk + * @param destmodel pointer to the histogram buffer in the @ref arimodel + * @param ModeID select which model to use + * @note this is still from PACS, need a CHEOPS statistic here + */ + +void initAriTable (int *destmodel, int ModeID) +{ + switch ( ModeID ) + { + case ( PHOT_STANDARD ) : + default : + { + /* startmodel for default full-frame compression */ + destmodel[0] = 201; + destmodel[1] = 200; + destmodel[2] = 200; + destmodel[3] = 197; + destmodel[4] = 199; + destmodel[5] = 194; + destmodel[6] = 195; + destmodel[7] = 190; + destmodel[8] = 192; + destmodel[9] = 184; + destmodel[10] = 186; + destmodel[11] = 178; + destmodel[12] = 181; + destmodel[13] = 172; + destmodel[14] = 174; + destmodel[15] = 165; + destmodel[16] = 167; + destmodel[17] = 157; + destmodel[18] = 160; + destmodel[19] = 150; + destmodel[20] = 153; + destmodel[21] = 143; + destmodel[22] = 145; + destmodel[23] = 134; + destmodel[24] = 138; + destmodel[25] = 127; + destmodel[26] = 130; + destmodel[27] = 120; + destmodel[28] = 123; + destmodel[29] = 113; + destmodel[30] = 116; + destmodel[31] = 107; + destmodel[32] = 109; + destmodel[33] = 99; + destmodel[34] = 102; + destmodel[35] = 93; + destmodel[36] = 95; + destmodel[37] = 87; + destmodel[38] = 89; + destmodel[39] = 81; + destmodel[40] = 83; + destmodel[41] = 75; + destmodel[42] = 78; + destmodel[43] = 70; + destmodel[44] = 72; + destmodel[45] = 65; + destmodel[46] = 67; + destmodel[47] = 60; + destmodel[48] = 62; + destmodel[49] = 56; + destmodel[50] = 58; + destmodel[51] = 51; + destmodel[52] = 54; + destmodel[53] = 47; + destmodel[54] = 49; + destmodel[55] = 44; + destmodel[56] = 46; + destmodel[57] = 40; + destmodel[58] = 42; + destmodel[59] = 37; + destmodel[60] = 39; + destmodel[61] = 34; + destmodel[62] = 36; + destmodel[63] = 31; + destmodel[64] = 33; + destmodel[65] = 28; + destmodel[66] = 30; + destmodel[67] = 26; + destmodel[68] = 28; + destmodel[69] = 24; + destmodel[70] = 26; + destmodel[71] = 22; + destmodel[72] = 23; + destmodel[73] = 20; + destmodel[74] = 22; + destmodel[75] = 18; + destmodel[76] = 19; + destmodel[77] = 16; + destmodel[78] = 18; + destmodel[79] = 15; + destmodel[80] = 16; + destmodel[81] = 14; + destmodel[82] = 15; + destmodel[83] = 12; + destmodel[84] = 14; + destmodel[85] = 11; + destmodel[86] = 12; + destmodel[87] = 10; + destmodel[88] = 11; + destmodel[89] = 10; + destmodel[90] = 10; + destmodel[91] = 9; + destmodel[92] = 9; + destmodel[93] = 8; + destmodel[94] = 9; + destmodel[95] = 7; + destmodel[96] = 8; + destmodel[97] = 7; + destmodel[98] = 7; + destmodel[99] = 6; + destmodel[100] = 7; + destmodel[101] = 5; + destmodel[102] = 6; + destmodel[103] = 5; + destmodel[104] = 5; + destmodel[105] = 4; + destmodel[106] = 5; + destmodel[107] = 4; + destmodel[108] = 5; + destmodel[109] = 4; + destmodel[110] = 4; + destmodel[111] = 4; + destmodel[112] = 4; + destmodel[113] = 3; + destmodel[114] = 4; + destmodel[115] = 3; + destmodel[116] = 3; + destmodel[117] = 3; + destmodel[118] = 3; + destmodel[119] = 3; + destmodel[120] = 3; + destmodel[121] = 2; + destmodel[122] = 3; + destmodel[123] = 2; + destmodel[124] = 2; + destmodel[125] = 2; + destmodel[126] = 2; + destmodel[127] = 2; + destmodel[128] = 2; + destmodel[129] = 2; + destmodel[130] = 2; + destmodel[131] = 2; + destmodel[132] = 2; + destmodel[133] = 2; + destmodel[134] = 2; + destmodel[135] = 2; + destmodel[136] = 2; + destmodel[137] = 2; + destmodel[138] = 2; + destmodel[139] = 2; + destmodel[140] = 2; + destmodel[141] = 1; + destmodel[142] = 2; + destmodel[143] = 1; + destmodel[144] = 2; + destmodel[145] = 1; + destmodel[146] = 2; + destmodel[147] = 1; + destmodel[148] = 1; + destmodel[149] = 1; + destmodel[150] = 1; + destmodel[151] = 1; + destmodel[152] = 1; + destmodel[153] = 1; + destmodel[154] = 1; + destmodel[155] = 1; + destmodel[156] = 1; + destmodel[157] = 1; + destmodel[158] = 1; + destmodel[159] = 1; + destmodel[160] = 1; + destmodel[161] = 1; + destmodel[162] = 1; + destmodel[163] = 1; + destmodel[164] = 1; + destmodel[165] = 1; + destmodel[166] = 1; + destmodel[167] = 1; + destmodel[168] = 1; + destmodel[169] = 1; + destmodel[170] = 1; + destmodel[171] = 1; + destmodel[172] = 1; + destmodel[173] = 1; + destmodel[174] = 1; + destmodel[175] = 1; + destmodel[176] = 1; + destmodel[177] = 1; + destmodel[178] = 1; + destmodel[179] = 1; + destmodel[180] = 1; + destmodel[181] = 1; + destmodel[182] = 1; + destmodel[183] = 1; + destmodel[184] = 1; + destmodel[185] = 1; + destmodel[186] = 1; + destmodel[187] = 1; + destmodel[188] = 1; + destmodel[189] = 1; + destmodel[190] = 1; + destmodel[191] = 1; + destmodel[192] = 1; + destmodel[193] = 1; + destmodel[194] = 1; + destmodel[195] = 1; + destmodel[196] = 1; + destmodel[197] = 1; + destmodel[198] = 1; + destmodel[199] = 1; + destmodel[200] = 1; + destmodel[201] = 1; + destmodel[202] = 1; + destmodel[203] = 1; + destmodel[204] = 1; + destmodel[205] = 1; + destmodel[206] = 1; + destmodel[207] = 1; + destmodel[208] = 1; + destmodel[209] = 1; + destmodel[210] = 1; + destmodel[211] = 1; + destmodel[212] = 1; + destmodel[213] = 1; + destmodel[214] = 1; + destmodel[215] = 1; + destmodel[216] = 1; + destmodel[217] = 1; + destmodel[218] = 1; + destmodel[219] = 1; + destmodel[220] = 1; + destmodel[221] = 1; + destmodel[222] = 1; + destmodel[223] = 1; + destmodel[224] = 1; + destmodel[225] = 1; + destmodel[226] = 1; + destmodel[227] = 1; + destmodel[228] = 1; + destmodel[229] = 1; + destmodel[230] = 1; + destmodel[231] = 1; + destmodel[232] = 1; + destmodel[233] = 1; + destmodel[234] = 1; + destmodel[235] = 1; + destmodel[236] = 1; + destmodel[237] = 1; + destmodel[238] = 1; + destmodel[239] = 1; + destmodel[240] = 1; + destmodel[241] = 1; + destmodel[242] = 1; + destmodel[243] = 1; + destmodel[244] = 1; + destmodel[245] = 1; + destmodel[246] = 1; + destmodel[247] = 1; + destmodel[248] = 1; + destmodel[249] = 1; + destmodel[250] = 1; + destmodel[251] = 1; + destmodel[252] = 1; + destmodel[253] = 1; + destmodel[254] = 1; + destmodel[255] = 1; + destmodel[256] = 131; /* NOTE: spillover, yes this table has 257 entries! */ + break; + } + } + return; +} + + +/** + * + * these variables are shared among the core coding functions of fmari + * + *@{*/ + +/** lower bound of local encoding interval */ +unsigned int fm_ari_low = 0; + +/** upper bound of local encoding interval */ +unsigned int fm_ari_high = 0xffff; + +/** flag to signal underflow */ +unsigned int fm_ari_underflow = 0; + +/** the write counter for the output bitstream */ +unsigned int fm_ari_wctr = 0; + +/**@}*/ + + +/** + * @brief calculate the new interval and output bits to the bitstream if necessary + * @param dest pointer to the base of the output bitstream + * @param cp the cumulative probability of that value (taken from the @ref arimodel) + * @param ncp the next cumulative probability of that value (taken from the @ref arimodel) + * @par Globals + * @ref fm_ari_low, @ref fm_ari_high, @ref fm_ari_underflow, @ref fm_ari_wctr + */ + +void fmari_encodeSym8k (unsigned int *dest, unsigned int cp, unsigned int ncp) +{ + unsigned int width; + unsigned int a; + + /* calculate the new interval */ + width = (fm_ari_high - fm_ari_low) + 1; + + fm_ari_high = fm_ari_low + ((ncp * width) >> 13) - 1; /* L + Pni * (H - L) */ + + fm_ari_low = fm_ari_low + ((cp * width) >> 13); /* L + Pci * (H - L) */ + + for ( ; ; ) + { + a = fm_ari_high & 0x8000; + + /* write out equal bits */ + if (a == (fm_ari_low & 0x8000)) + { + PutBit32 (a >> 15, fm_ari_wctr++, dest); + + while (fm_ari_underflow > 0) + { + PutBit32 ((~fm_ari_high & 0x8000) >> 15, fm_ari_wctr++, dest); + fm_ari_underflow--; + } + } + + /* underflow coming up, because <> and the 2nd bits are just one apart */ + else if ((fm_ari_low & 0x4000) && !(fm_ari_high & 0x4000)) + { + fm_ari_underflow++; + fm_ari_low &= 0x3fff; + fm_ari_high |= 0x4000; + } + else + { + return; + } + + fm_ari_low <<= 1; + fm_ari_low &= 0xffff; + fm_ari_high <<= 1; + fm_ari_high |= 1; + fm_ari_high &= 0xffff; + } + + /* the return is inside the for loop */ +} + + +/** + * @brief at the end of an encoding chunk, flush out necessary remaining bits + * @param dest pointer to the base of the output bitstream + * @par Globals + * @ref fm_ari_low, @ref fm_ari_underflow, @ref fm_ari_wctr + */ + +void fmari_flushEncoder (unsigned int *dest) +{ + + PutBit32 ((fm_ari_low & 0x4000) >> 14, fm_ari_wctr++, dest); + + fm_ari_underflow++; + + while (fm_ari_underflow-- > 0) + PutBit32 ((~fm_ari_low & 0x4000) >> 14, fm_ari_wctr++, dest); + + return; +} + + +/** + * @brief encode a chunk of symbols to an output bitstream. Spillover values are saved in the @ref arimodel's dedicated buffer + * @param chunk pointer to the input data + * @param chunksize number of symbols in this chunk, best use @ref MAXFREQ (or less if the chunk is smaller) + * @param dest pointer to the base of the output bitstream of that chunk segment + * @param model pointer to the @ref arimodel structure + * @par Globals + * A number of (local) globals are initialized here + * @ref fm_ari_low, @ref fm_ari_high, @ref fm_ari_underflow, @ref fm_ari_wctr + * @note make the (local) globales either static or move to arimodel or pass as arguments (or live with it) + */ + +int fmari_encode_chunk (int *chunk, int chunksize, int *dest, struct arimodel *model) +{ + int ctr, tail; + unsigned int symbol, cp, ncp; + + /* now init ari */ + fm_ari_low = 0; + fm_ari_high = 0xffff; + fm_ari_underflow = 0; + fm_ari_wctr = 32; /* offset for chunksize_w */ + + for (ctr=0; ctr < chunksize; ctr++) + { + symbol = chunk[ctr]; /* get next symbol */ + + /* look it up in the tables */ + /* first we check for spillover */ + if (symbol >= SPILLCUT) + { + /* encode spillover signal in ari stream */ + cp = model->cptable[FMARIROWS]; + ncp = model->ncptable[FMARIROWS]; + + fmari_encodeSym8k ((unsigned int *) dest, cp, ncp); + + /* put the symbol into the spillover buffer and increment counter */ + model->spillover[(model->spillctr)++] = symbol; + } + else /* valid symbol */ + { + cp = model->cptable[symbol]; + ncp = model->ncptable[symbol]; + + fmari_encodeSym8k ((unsigned int *)dest, cp, ncp); + } + + } + + /* encode the rest */ + fmari_flushEncoder ((unsigned int *) dest); + + /* calc fillup and fill up with 0s */ + tail = (32 - fm_ari_wctr % 32) % 32; + fm_ari_wctr += tail; + dest[0] = (fm_ari_wctr / 32); + + return dest[0]; /* now in words */ +} + + +unsigned int bits_used (unsigned int num) +{ + unsigned int u; + + for (u=0; num != 0; u++) + { + num >>= 1; + } + + return u; +} + + +/** + * @brief variable block word length encoding. Used for the spillover in FmAri + * @param source pointer to the input data + * @param words number of symbols to encode + * @param dest pointer to the base of the output bitstream + * @param BS block size, i.e. how many symbols are put into a group + * @note this function is the weak point of the FmAri (ARI1) implementation. + * Ok, it has worked for Herschel, where we had very few spill counts, but we want to get rid of it in CHEOPS. + * @returns size in 32-bit words of the output stream, rounded up + */ + +int vbwl_midsize (int *source, int words, int *dest, int BS) +{ + int ctr, bctr; + int bits, width; + int outbits = 32; /* keep track of the output bits; we start at dest[1] */ + + /* main loop counts through the source words */ + for (ctr=0; ctr < words; ctr++) + { + /* block-loop, we count through the words of a block */ + for (width=0, bctr=ctr; (bctr < ctr+BS) & (bctr < words); bctr++) + { + /* determine used bits of current word */ + /* bits = 32-lzeros */ + bits = bits_used(((unsigned int *)source)[bctr]); + + width = bits > width ? bits : width; + } + + /* now we know width = the number of bits to encode the block */ + /* first code the width */ + if (width < VBWLMINW) /* ... due to the optional -FMARIROWS */ + width = VBWLMINW; + + /* use VBWLCODE bits for the encoding of the width */ + PutNBits32(width-VBWLMINW, outbits, VBWLCODE, (unsigned int *) dest); + outbits += VBWLCODE; + + /* now code the words of the block in width bits */ + for (bctr=ctr; (ctr < bctr+BS) & (ctr < words); ctr++) + { + PutNBits32 (source[ctr], outbits, width, (unsigned int *)dest); + outbits += width; + } + ctr--; + } + + /* store the original size */ + dest[0] = words; + + /* return the size in words, rounding up */ + return (outbits+31)/32; +} + + +/** + * @brief The FM Arithmetic compression function. ARI1 in CHEOPS-slang. + * @param source pointer to the input data. + * @param nwords number of symbols to encode + * @param dest pointer to the base of the output bitstream + * @param swap a working buffer is needed with a size of (strictly speaking) nwords+257+258 words, + * but if you can guess the spillcount, use spillcount+257+258 + * @param modeltype initial probability model to start with. Choose from @ref initAriTable + * @returns size in 32-bit words of the output stream, rounded up + * @note The spillover is encoded with @ref vbwl_midsize and that algorithm is quite inefficient. + * Ok, it is difficult to encode the spill, but that algorithm really does a bad job at it. + * In particular, the @ref VBWLCODE define is limiting the range of values. + */ + +int fmari_compress (unsigned int *source, unsigned int nwords, unsigned int *dest, unsigned int *swap, unsigned int modeltype) +{ + int ctr; + int src_ctr; + int remaining; + int *streamctr_w; + unsigned int *stream; + + struct arimodel model; + + init_arimodel (&model, swap, FMARIROWS); + + dest[0] = nwords; /* store original size in words */ + remaining = nwords; + + src_ctr = 0; + + streamctr_w = (int *) (dest + 1); /* here the size of the ari stream in words will grow */ + *streamctr_w = 0; /* we start with 2, because we have the osize and the streamctr */ + + stream = dest + ARIHDR; /* set dest stream and counter */ + + initAriTable((int *) model.freqtable, modeltype); /* initialize starting model */ + + /* make probability model */ + model.probability = makeCumulative(model.freqtable, FMARISPILL, model.cptable); + + /* start compressing chunks with initial model */ + while (remaining > MAXFREQ) + { + *streamctr_w += fmari_encode_chunk((int *)(source + src_ctr), MAXFREQ, \ + (int *)(stream + *streamctr_w), &model); + + /* derive new model from current data */ + update_fm_ari_model (source + src_ctr, MAXFREQ, FMARISPILL, 1, &model); + + src_ctr += MAXFREQ; + remaining -= MAXFREQ; + } + + /* encode the last chunk */ + if (remaining > 0) + *streamctr_w += fmari_encode_chunk ((int *)(source + src_ctr), remaining, \ + (int *)(stream + *streamctr_w), &model); + + /* report the spill to DP */ + { + unsigned int spill_ctr; + spill_ctr = model.spillctr; + CrIaPaste(SPILL_CTR_ID, &spill_ctr); + } + + /* .. treat the spillover here */ + /* subtract FMARIROWS from the spill values */ + for (ctr=0; ctr < model.spillctr; ctr++) + model.spillover[ctr] -= FMARIROWS; + + model.spillctr = vbwl_midsize ((int *) model.spillover, model.spillctr, \ + (int *)(dest + ARIHDR + (*streamctr_w)), 4); + + + return (int)(ARIHDR + *streamctr_w + model.spillctr); +} + + diff --git a/CompressionEntity/src/SdpAlgorithmsImplementationLlc.h b/CompressionEntity/src/SdpAlgorithmsImplementationLlc.h new file mode 100644 index 0000000000000000000000000000000000000000..a1bbad71dc0cf5db770d6e256fca7dc9e40a00ee --- /dev/null +++ b/CompressionEntity/src/SdpAlgorithmsImplementationLlc.h @@ -0,0 +1,105 @@ +/** + * @file SdpAlgorithmsImplementationLlc.h + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef SDP_ALGORITHMS_IMPLEMENTATION_LLC_H +#define SDP_ALGORITHMS_IMPLEMENTATION_LLC_H + + +#ifdef COMPR_DEBUG_ARI +#define DUMPMODEL(m) { int c; for (c=0; c < FMARISPILL; c++) SDPRINT ("i: %d p: %d cp: %d ncp: %d\n", c, m[c], m[c+FMARISPILL], m[c+FMARISPILL+1]); } +#define CHECKMODEL(m) { int v, c; for (v=0, c=0; c < FMARISPILL; c++) v += m[c]; SDPRINT ("Model sum is: %d\n", v); } +#endif + + + +/** + * ARI parameters + */ +#define ARIHDR 2 +#define FMARIROWS 256 +#define FMARISPILL 257 +#define MAXFREQ 8192 +#define SPILLCUT FMARIROWS +#define PHOT_STANDARD 0 + + +/** + * @brief structure used by the @ref fmari_compress algorithm + */ + +struct arimodel { + unsigned int *freqtable; + unsigned int *cptable; /* cumulative probability table */ + unsigned int *ncptable; /* next cumulative probability table */ + unsigned int *spillover; /* swap buffer for spillover, i.e. words > 8 Bit */ + int spillctr; + int probability; +}; + + +/** + * This number defines the number of bits used for the codeword in the @ref vbwl_midsize + * algorithm, which is located at the start of each group and says how many bits are used for + * the symbols in this group. + * + * set to 3 if you are sure that there are no larger values than 16 bits (the length code L = 9..16 + * will be encoded as L-VBWLMINW = C = 0..7 in 4 bits. Each symbol of the group will be encoded in L bits) + * + * set to 4 for a cap of 24 bits, set to 5 for a cap of 40 bits + * + * @warning Larger values than what you set as cap will corrupt the output stream + * and it would be hard to decode such a stream. + * + */ + +#define VBWLCODE 5 + +/** + * The minimum number of bits to encode a spillover value is 9, + * because if it was 8, it would not have landed in the spill. + * There is one exception, because the bias @ref FMARIROWS is subtracted + * from the spill before calling the @ref vbwl_midyize function. + * This leaves a small range of values to get a width of < 9, but + * at present vbwl does not make efficient use of it and encodes them in 9 bits. + */ + +#define VBWLMINW 9 + +unsigned int RZip32 (unsigned int *source, unsigned int len, unsigned int *cstream, unsigned int *alpha, unsigned int range); + +void init_arimodel (struct arimodel *model, unsigned int *buffer, int symbols); + +void initAriTable (int *destmodel, int ModeID); + +int makeCumulative (unsigned int *table, unsigned int nrows, unsigned int *cumu); + +void update_fm_ari_model (unsigned int *buffer, unsigned int nwords, unsigned int symbols, int initval, struct arimodel *model); + +void fmari_encodeSym8k (unsigned int *dest, unsigned int cp, unsigned int ncp); + +void fmari_flushEncoder (unsigned int *dest); + +int fmari_encode_chunk (int *chunk, int chunksize, int *dest, struct arimodel *model); + +unsigned int bits_used (unsigned int num); + +int vbwl_midsize (int *source, int words, int *dest, int BS); + +int fmari_compress (unsigned int *source, unsigned int nwords, unsigned int *dest, unsigned int *swap, unsigned int modeltype); + + +#endif diff --git a/CompressionEntity/src/SdpBuffers.c b/CompressionEntity/src/SdpBuffers.c new file mode 100644 index 0000000000000000000000000000000000000000..5db212de36b69f662ecde9561694147e6f853cd3 --- /dev/null +++ b/CompressionEntity/src/SdpBuffers.c @@ -0,0 +1,1429 @@ +/** + * @file SdpBuffers.c + * @ingroup SdpBuffers + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup SdpBuffers Science Data Processing Buffers + * @ingroup Sdp + * + * @brief various functions to initialize and manage buffers related with the + * science data processing + * + * ## Overview + * + * This file contains functions to set up the compression entity, to set up + * the image buffers (@ref SIB) and increment them during input buffering, functions that + * manage the compression buffers internally, to convert header data to flat arrays + * and a set of small helper functions to deal with science-related memory access. + * + * ### @anchor SDB SDB (Science Data Buffer) + * + * For science data processing, a simple decision was taken -- it gets the second CPU core and the second half of the RAM, the SRAM2. + * Unfortunately this RAM bank is accessed with 32 bit granularity, i.e. access of shorts and characters will be wrong, consequently + * only 32 bit values can be read or stored. Second, there is one wait state on this bank, which increases the already slow data + * access by another ~10%. With these restrictions in mind, all of the 32 MiB of the SRAM2 are completely available for SDB data allocation. + * + * ## Mode of Operation + * + * ### Image Buffer Model + * + * Each input image is stored in a @anchor SIB __SIB__ (Single Image Buffer) before a number of images are picked up + * by the compression and processed to create a @ref CompressionEntity. Such a SIB has a certain + * reserved size and the number of consecutive SIBs is configured by the Configure SDB + * procedure through Service 198. + * + * An input image is not just a 2-dimensional array of pixel values, but a set of 5 sub-images. In addition, + * header data, such as temeperatures and voltages, the measured centroid for that image, quick photometry, + * counters, settings such as exposure time etc. are also stored within a SIB. In order to generate the internal + * layout of the SIB, the @ref CrIaSib structure is set up for an incoming image (set) whenever the first packet + * of such a set is processed. In window mode, the @ref CrIaSetupSibWin function is used, in full-frame mode, + * CrIaSetupSibFull is used. + * + * As already mentioned, a number of SIB slots is available as configured by the user per command. The current slot + * to be written and the current slot to be read are pointed to by the @ref SibIn and @ref SibOut pointers. These + * are two of the four @anchor XIB __XIB__ pointers (the others are GibIn and GibOut), which are 16 bit pointers + * of 1024 B unit and their base is the @ref SDB. + * + * They are managed in circular fashion using the following rules: + * - the SibIn must not run into the SibOut, i.e. if all slots are full (because of misconfiguration by the used), + * the slot pointed to by SibOut must not be overwritten by the new incoming data. This would corrupt the ongoing compression! + * For a better understanding of the incrementation mechanism described beneath, the term __border__ is introduced here. Here, the + * SibOut acts as a border to SibIn. + * - at the beginning SibIn and SibOut are equal. SibIn can start, but SibOut must not. + * - if there is no free slot available for incoming data, the most recently written SIB will be overwritten. + * We do not simply discard the new data, because they are needed for the @ref Centroid generation + * - The SibOut may assume the value of the SibIn, i.e. if all buffered images have been processed, it moves on. + * The SibOut cannot get ahead of the SibIn. In a misconfigured situation, where only 2 images are buffered, but 3 are + * commanded to be read, the last image will be read twice. This can happen, if the user has configured less slots + * than the number of images to be stacked. + * - the user must allow sufficient slots to be available. + * + * Similar to the SIB, the output data are stored in @anchor GIB GIB (Ground Image Buffer) slots. They are not structured with + * a setup function, because a GIB only + * holds one @ref CompressionEntity, the result of a data processing run. The same rules as for the SIB also apply to the GIB, in + * particular, a GibIn must not assume the value of the GibOut by incrementation, otherwise the currently being down transferred data + * may be corrupted. + * + * The two functions @ref updateXib and @ref updateXibFwd are available to increment the buffers in accordance with the rules above. + * @ref updateXib will not allow to run into a border, @updateXibFwd will allow to assume the border value, but not go further. + * In other words, @ref updateXibFwd goes one slot further than @ref updateXib, but none of the two ever get ahead of the border. + * @ref updateXib is used for the SibIn and for the GibIn, updateXibFwd is used for the SibOut and the GibOut. + * + * ### Data Processing Buffer + * + * Only one Compression is run at a time, and the data porcessing chain consists of several (optional) very different steps, + * so that the processing buffers need to be specially managed. For this purpose, all the @anchor CIB CIBs (Compression Image Buffer) that were + * configured are combined and then subdivided into CompressionEntity buffers using the @ref SetupCeBuffers function. All the metadata + * of the processing buffers are stored in the @ref ComprEntStructure. @ref SetupCeBuffers creates a buffer layout based on maximum product sizes + * for the compressed products. The first buffer will hold the compressed headers, the next one the compressed imagettes etc. + * At the tail of these 10 buffers, a processing buffer @anchor ProcBuf __ProcBuf__ is established, which starts at the beginning of the + * rest of the combined CIB area. This buffer can be used directly, or it can serve as a heap, where a special allocation + * function @ref AllocFromProcBuf is available. At the beginning, its size is set to 0. Use @ref ProcBufBorgMode to assimilate the whole + * remaining space. + * + * + * ## Notes + * + * As a guideline for the user to set up the @ref SDB, be greedy with the SIB (2x stacking order slots are sufficient) and the + * GIB (2 slots are sufficient), but give all the rest to the CIB (doesn't matter which one and how many slots, it will all be combined). + * + */ + +#include "SdpBuffers.h" +#include "SdpCompressionEntityStructure.h" +#include "CrIaDataPoolId.h" +#include "CrIaDataPool.h" +#ifndef ISOLATED +#include "Services/General/CrIaConstants.h" +#endif + +#include <stdio.h> + +#ifndef GROUNDSW +#include "CrIaIasw.h" /* for CrFwGetCurrentTime */ +#else +#include "GroundSupport.h" +extern struct cuctime GetCurrentTime(void); /* is in GroundSupport.c */ +extern unsigned char __BUILD_ID; +#endif + +#ifdef PC_TARGET +/** + * @brief allocate memory from the @ref SDB + * @param size the number of bytes to allocate. Use sizes which are multiples of 4 + * @param reset a bool which resets the whole SDB + * + * @returns the real address of the allocated buffer + * @note the size is not tracked internally, and there is no + * error if too much ram is requested. + */ + +unsigned int * sdballoc (unsigned int size, unsigned char reset) +{ + static unsigned int used; + unsigned long int allocmem; + + if (reset == 1) + { + used = 0; + return NULL; + } + + allocmem = GET_ADDR_FROM_SDB_OFFSET(0) + used; + used += size; + + return (unsigned int *)allocmem; /* this shall return the real address */ +} + + +/** + * @brief allocate memory from the @ref RESERVED area + * @param size the number of bytes to allocate. Use sizes which are multiples of 4 + * @param reset a bool which resets the whole RESERVED area + * + * @returns the real address of the allocated buffer + * @note the size is not tracked internally, and there is no + * error if too much ram is requested. + */ + +unsigned int * resalloc (unsigned int size, unsigned char reset) +{ + static unsigned int used; + unsigned long int allocmem; + + if (reset == 1) + { + used = 0; + return NULL; + } + + allocmem = GET_ADDR_FROM_RES_OFFSET(0) + used; + used += size; + + return (unsigned int *)allocmem; /* this shall return the real address */ +} + +unsigned int * auxalloc (unsigned int size, unsigned char reset) +{ + static unsigned int used; + unsigned long int allocmem; + + if (reset == 1) + { + used = 0; + return NULL; + } + + allocmem = GET_ADDR_FROM_AUX_OFFSET(0) + used; + used += size; + + return (unsigned int *)allocmem; /* this shall return the real address */ +} + +unsigned int * swapalloc (unsigned int size, unsigned char reset) +{ + static unsigned int used; + unsigned long int allocmem; + + if (reset == 1) + { + used = 0; + return NULL; + } + + allocmem = GET_ADDR_FROM_SWAP_OFFSET(0) + used; + used += size; + + return (unsigned int *)allocmem; /* this shall return the real address */ +} + +#endif + + +/** + * @brief initialize the CompressionEntity with values taken from the data pool + * @param cestruct pointer to the ComprEntStructure + * + * @note Some of these data pool variables are mandatory to be set. Make + * sure they contain no rubbish before starting the compression. + */ + +void InitComprEntStructureFromDataPool (struct ComprEntStructure *cestruct) +{ + unsigned short uint16, sdbstate; + unsigned int uint32; + unsigned char uint8; + + CrIaCopy (OBSERVATIONID_ID, &uint32); + cestruct->Obsid = uint32; + +#ifndef GROUNDSW + { + CrFwTimeStamp_t timetag; + + timetag = CrFwGetCurrentTime(); + /* NOTE: the next two lines are big endian. */ + uint32 = (((unsigned int)timetag.t[0]) << 24) | (((unsigned int)timetag.t[1]) << 16) | (((unsigned int)timetag.t[2]) << 8) | ((unsigned int)timetag.t[3]); + uint16 = (unsigned short) ((((unsigned int)timetag.t[4]) << 8) | ((unsigned int)timetag.t[5])); + cestruct->Timetag.coarse = uint32; + cestruct->Timetag.fine = uint16; + cestruct->Timetag.sync = uint16 & 0x1; + } +#else + /* + On ground we look at the cestruct->Timetag. + - If there is a nonzero value, we go ahead with it. + - If it is zero, we fetch the current PC time. + + Note, that in order to work, the CE constructor + must clear the field upon instantiation (it does so.). + */ + + if (cestruct->Timetag.coarse == 0) + { + cestruct->Timetag = GetCurrentTime(); + } + uint32 = cestruct->Timetag.coarse; + uint16 = cestruct->Timetag.fine; +#endif + CrIaPaste (CE_TIMETAG_CRS_ID, &uint32); + CrIaPaste (CE_TIMETAG_FINE_ID, &uint16); + + CrIaCopy (CE_COUNTER_ID, &uint16); + cestruct->Counter = uint16; + + /* NOTE: the build number (previously updated here) is now filled in the CrIaInit function */ + uint16 = VERSION; + CrIaPaste (CE_VERSION_ID, &uint16); + cestruct->Version = uint16; + + CrIaCopy(STCK_ORDER_ID, &uint16); + cestruct->StackingNumber = uint16 & 0xff; + + /* + NOTE: The following cestruct parameters are not initialized here, + but in the SibToFlatHeaders function, because they come from the SIB: + + "AcquisitionMode" is set in SIB by the science update function. On ground we set it through RawHeadersToSib. + "FrameSource" is set in SIB by the science update function. On ground it is set by RawHeadersToSib to 0 (CCD). + "ExposureTime" is set in SIB by the science update function. On ground we set it through RawHeadersToSib. + */ + + /* "Integrity" is set here to "OK", but later overwritten by SdpCompress as well as by the ScienceProcessing function. */ + uint8 = DATA_OK; + CrIaPaste(CE_INTEGRITY_ID, &uint8); + cestruct->Integrity = uint8; + + CrIaCopy(PCCDRDMODE_ID, &uint16); + cestruct->ReadoutMode = (unsigned char) uint16; + + CrIaCopy(PDATAOS_ID, &uint16); + cestruct->Oversampling = (unsigned char) uint16; + + CrIaCopy (PIMAGEREP_ID, &uint32); + cestruct->RepetitionPeriod = uint32; + + CrIaCopy (CE_SEMWINDOWPOSX_ID, &uint16); + cestruct->SemWindowPosX = uint16; + + CrIaCopy (CE_SEMWINDOWPOSY_ID, &uint16); + cestruct->SemWindowPosY = uint16; + + CrIaCopy (CE_SEMWINDOWSIZEX_ID, &uint16); + cestruct->SemWindowSizeX = uint16; + + CrIaCopy (CE_SEMWINDOWSIZEY_ID, &uint16); + cestruct->SemWindowSizeY = uint16; + + CrIaCopy (TARGETLOCATIONX_ID, &uint32); + cestruct->Target_LocationX = uint32; + + CrIaCopy (TARGETLOCATIONY_ID, &uint32); + cestruct->Target_LocationY = uint32; + + /* NOTE: win and full have different CeKeys for Headers and Stacked. */ + CrIaCopy(SDBSTATE_ID, &sdbstate); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + { + CrIaCopy (SDPFULLHDRCEKEY_ID, &uint32); + cestruct->HeaderData_CeKey = uint32; + + CrIaCopy (SDPFULLIMGCEKEY_ID, &uint32); + cestruct->Stacked_CeKey = uint32; + } + else + { + CrIaCopy (SDPWINHDRCEKEY_ID, &uint32); + cestruct->HeaderData_CeKey = uint32; + + CrIaCopy (SDPWINIMAGECEKEY_ID, &uint32); + cestruct->Stacked_CeKey = uint32; + } + + CrIaCopy (SDPIMAGEAPTSHAPE_ID, &uint16); + cestruct->Stacked_Shape = uint16; + + CrIaCopy (SDPIMAGEAPTX_ID, &uint16); + cestruct->Stacked_SizeX = uint16; + + CrIaCopy (SDPIMAGEAPTY_ID, &uint16); + cestruct->Stacked_SizeY = uint16; + + CrIaCopy (SDPWINIMGTTCEKEY_ID, &uint32); + cestruct->Imagettes_CeKey = uint32; + + CrIaCopy (SDPIMGTTAPTSHAPE_ID, &uint16); + cestruct->Imagettes_ApertureShape = uint16; + + CrIaCopy (SDPIMGTTSTRAT_ID, &uint16); + cestruct->Imagettes_CroppingStrategy = uint16; + + CrIaCopy (SDPIMGTTAPTX_ID, &uint16); + cestruct->Imagettes_ApertureSizeX = uint16; + + CrIaCopy (SDPIMGTTAPTY_ID, &uint16); + cestruct->Imagettes_ApertureSizeY = uint16; + + CrIaCopy (SDPIMGTTSTCKORDER_ID, &uint8); + cestruct->Imagettes_StackingOrder = uint8; + + CrIaCopy (SDPWINMLOSCEKEY_ID, &uint32); + cestruct->ImgMrgLOS_CeKey = uint32; + + CrIaCopy (SDPWINMLBLKCEKEY_ID, &uint32); + cestruct->ImgMrgLBLK_CeKey = uint32; + + CrIaCopy (SDPWINMLDKCEKEY_ID, &uint32); + cestruct->ImgMrgLDK_CeKey = uint32; + + CrIaCopy (SDPWINMRDKCEKEY_ID, &uint32); + cestruct->ImgMrgRDK_CeKey = uint32; + + CrIaCopy (SDPWINMRBLKCEKEY_ID, &uint32); + cestruct->ImgMrgRBLK_CeKey = uint32; + + CrIaCopy (SDPWINMTOSCEKEY_ID, &uint32); + cestruct->ImgMrgTOS_CeKey = uint32; + + CrIaCopy (SDPWINMTDKCEKEY_ID, &uint32); + cestruct->ImgMrgTDK_CeKey = uint32; + + CrIaCopy(SDPLDKCOLMASK_ID, &uint16); + cestruct->ImgMrgLDK_ColumnSelectionMask = uint16; + + CrIaCopy(SDPRDKCOLMASK_ID, &uint16); + cestruct->ImgMrgRDK_ColumnSelectionMask = uint16; + + return; +} + + +/** + * @brief Increment the XIB pointer by one slot unless we would land on the the border. If we start on the border, move. + * @param currentXib XIB pointer to be incremented + * @param borderXibXIB pointer acting as @ref border + * @param xibOffset the local xib offset calculated from the real address of the XIB (e.g. sibAddressWin, must be aligned to 1024 B) + * best use GET_SDB_OFFSET_FROM_ADDR(xibAddress) for it + * @param xibSize the size of a XIB slot + * @param xibN the number of slots in this XIB + * @param xib_err_id the id to put into the EVT_XIB_FULL + * + * @returns the updated XIB pointer. If it cannot be incremented, hand back the input XIB + * + * @note This is the "In" strategy. + */ + +unsigned short updateXib(unsigned int currentXib, unsigned int borderXib, unsigned long int xibOffset, unsigned int xibSize, unsigned int xibN, unsigned short xib_err_id) +{ + unsigned int lastXib; + unsigned int nextXib; + unsigned long int localOff; + unsigned short fails; + unsigned short evt_data[2]; + + localOff = (unsigned int) xibOffset; + + /* calcualte what the next XIB would be */ + nextXib = currentXib + xibSize; + + /* calcualte the 16 bit offset pointing to the last possible Slot */ + lastXib = localOff + xibSize*(xibN-1); + + /* l_SDPRINT("xibin = %d and lastxib=%d and nextXib=%d\n", currentXib, lastXib, nextXib); */ + + /* if the last slot was used, the new slot will be the first one */ + if (currentXib == lastXib) + nextXib = localOff; + + /* if this collides with the output xib, return the unmodified XIB with error */ + if (nextXib == borderXib) + { + /* in this case the buffer is full */ + CrIaCopy(XIB_FAILURES_ID, &fails); + fails++; + CrIaPaste(XIB_FAILURES_ID, &fails); +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR incrementing XIB with id %u\n", xib_err_id); +#else + evt_data[0] = xib_err_id; + SdpEvtRaise(3, CRIA_SERV5_EVT_XIB_FULL, evt_data, 4); +#endif + + return currentXib; + } + + return nextXib; +} + + +/** + * @brief Increment the XIB pointer by one slot and allow to land on the the border. If we start on the border, do not move. + * @param currentXib XIB pointer to be incremented + * @param borderXib XIB pointer acting as @ref border + * @param xibOffset the local xib offset calculated from the real address of the XIB (e.g. sibAddressWin, must be aligned to 1024 B) + * best use GET_SDB_OFFSET_FROM_ADDR(xibAddress) for it + * @param xibSize the size of a XIB slot + * @param xibN the number of slots in this XIB + * @param xib_err_id the id to put into the EVT_XIB_FULL + * + * @returns the updated XIB pointer. If it cannot be incremented, hand back the input XIB + * + * @note This is the "Out" strategy. + */ + +unsigned short updateXibFwd(unsigned int currentXib, unsigned int borderXib, unsigned long int xibOffset, unsigned int xibSize, unsigned int xibN, unsigned short xib_err_id) +{ + unsigned int lastXib; + unsigned int nextXib; + unsigned int localOff; + unsigned short fails; + unsigned short evt_data[2]; + + + if (currentXib == borderXib) + { + /* in this case the buffer is full */ + CrIaCopy(XIB_FAILURES_ID, &fails); + fails++; + CrIaPaste(XIB_FAILURES_ID, &fails); +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR incrementing XIB with id %u\n", xib_err_id); +#else + evt_data[0] = xib_err_id; + SdpEvtRaise(3, CRIA_SERV5_EVT_XIB_FULL, evt_data, 4); +#endif + return currentXib; + } + + localOff = (unsigned int) xibOffset; + + /* calcualte what the next XIB would be */ + nextXib = currentXib + xibSize; + + /* calcualte the 16 bit offset pointing to the last possible Slot */ + lastXib = localOff + xibSize*(xibN-1); + + /* l_SDPRINT("xibin = %d and lastxib=%d and nextXib=%d\n", currentXib, lastXib, nextXib); */ + + /* if the last slot was used, the new slot will be the first one */ + if (currentXib == lastXib) + nextXib = localOff; + + /* if this collides with the output xib, return the new one, so they are equal */ + + return nextXib; +} + + +/** + * @brief Attempt to increment the XIB pointer by N slots and allow to land on the the border. If we start on the border, do not move. + * @param currentXib XIB pointer to be incremented + * @param borderXib XIB pointer acting as @ref border + * @param xibOffset the local xib offset calculated from the real address of the XIB (e.g. sibAddressWin, must be aligned to 1024 B) + * best use GET_SDB_OFFSET_FROM_ADDR(xibAddress) for it + * @param xibSize the size of a XIB slot + * @param xibN the number of slots in this XIB + * @param Nupdates the number of slots to move + * @param xib_err_id the id to put into the EVT_XIB_FULL + * + * @returns the updated XIB pointer. If it cannot be incremented, hand back the last XIB that was successfully incremented. + * + * @note This is the "Out" strategy. + */ + +unsigned short updateXibNTimesFwd(unsigned int currentXib, unsigned int borderXib, unsigned long int xibOffset, unsigned int xibSize, unsigned int xibN, unsigned int Nupdates, unsigned short xib_err_id) +{ + unsigned int i; + + if (Nupdates == 0) + return currentXib; + + for (i=0; i < Nupdates-1; i++) + currentXib = updateXib(currentXib, borderXib, xibOffset, xibSize, xibN, xib_err_id); + + currentXib = updateXibFwd(currentXib, borderXib, xibOffset, xibSize, xibN, xib_err_id); + + return currentXib; +} + + +/** + * @brief Set this @ref SIB up in window mode + * @param sib pointer to sib structure + * @param sibIn @ref XIB pointer to the slot + * @param Xdim horizontal size of the input image area (the main image), e.g. 200 + * @param Ydim vertical size, e.g. 200 + * + * @returns the size of the SIB that has been internally distibuted, or 0 if the distribution would exceed the SIB size. + * + */ + +unsigned int CrIaSetupSibWin (struct CrIaSib *sib, unsigned short sibIn, unsigned int Xdim, unsigned int Ydim) +{ + unsigned short sibSize; + unsigned int usedSize; + unsigned short evt_data[2]; + + sib->LsmSamples = 0; + sib->RsmSamples = 0; + sib->TmSamples = 0; + sib->ExposSamples = 0; + sib->Xdim = Xdim; + sib->Ydim = Ydim; + + sib->Base = (unsigned int *)GET_ADDR_FROM_SDB_OFFSET(sibIn); + + sib->Header = sib->Base; + sib->HeaderSize = SEM_DAT_HEADER_VALUES * BPW_SRAM2; + + sib->Centroid = (unsigned int *)((unsigned long int)(sib->Header) + sib->HeaderSize); + sib->CentroidSize = SIB_CENTROID_VALUES * BPW_SRAM2; + + sib->Photometry = (unsigned int *)((unsigned long int)(sib->Centroid) + sib->CentroidSize); + sib->PhotometrySize = SIB_PHOTOMETRY_VALUES * BPW_SRAM2; + + sib->Lsm = (unsigned int *)((unsigned long int)(sib->Photometry) + sib->PhotometrySize); + sib->LsmSize = sib->Ydim * LSM_XDIM * BPW_PIXEL; + sib->LsmSize = (sib->LsmSize + 3) & 0xfffffffc; /* round up to 4B */ + + sib->Rsm = (unsigned int *)((unsigned long int)(sib->Lsm) + sib->LsmSize); + sib->RsmSize = sib->Ydim * RSM_XDIM * BPW_PIXEL; + sib->RsmSize = (sib->RsmSize + 3) & 0xfffffffc; /* round up to 4B */ + + sib->Tm = (unsigned int *)((unsigned long int)(sib->Rsm) + sib->RsmSize); + sib->TmSize = sib->Xdim * TM_YDIM * BPW_PIXEL; + sib->TmSize = (sib->TmSize + 3) & 0xfffffffc; /* round up to 4B */ + + sib->Expos = (unsigned int *)((unsigned long int)(sib->Tm) + sib->TmSize); + sib->ExposSize = sib->Xdim * sib->Ydim * BPW_PIXEL; + sib->ExposSize = (sib->ExposSize + 3) & 0xfffffffc; /* round up to 4B */ + + usedSize = (unsigned long int)(sib->Expos) + sib->ExposSize - (unsigned long int)(sib->Base); + + sib->UsedSize = usedSize; + + CrIaCopy (SIBSIZEWIN_ID, &sibSize); + + if (((unsigned int)sibSize * 1024) >= sib->UsedSize) + return sib->UsedSize; + +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR setting up SIB WIN structure with size of %u\n", sib->UsedSize); +#else + evt_data[0] = (unsigned short)((sib->UsedSize >> 16) & 0xffff); + evt_data[1] = (unsigned short)(sib->UsedSize & 0xffff); + SdpEvtRaise(3, CRIA_SERV5_EVT_IMG_INSUF, evt_data, 4); +#endif + + /* we keep the sizes for the header, centroid and photometry, but set the others to 0 */ + sib->LsmSize = 0; + sib->RsmSize = 0; + sib->TmSize = 0; + sib->ExposSize = 0; + + /* set the pointers right after the photometry */ + sib->Rsm = sib->Lsm; + sib->Tm = sib->Rsm; + sib->Expos = sib->Tm; + + return 0; +} + + +/** + * @brief Set this @ref SIB up in full frame + * @param sib pointer to sib structure + * @param sibIn @ref XIB pointer to the slot + * + * @returns the size of the SIB that has been internally distibuted, or 0 if the distribution would exceed the SIB size. + * + */ + +unsigned int CrIaSetupSibFull (struct CrIaSib *sib, unsigned short sibIn) +{ + unsigned short sibSize; + unsigned int usedSize; + unsigned short evt_data[2]; + + sib->LsmSamples = 0; + sib->RsmSamples = 0; + sib->TmSamples = 0; + sib->ExposSamples = 0; + sib->Xdim = FULL_SIZE_X; + sib->Ydim = FULL_SIZE_Y; + + sib->Base = (unsigned int *)GET_ADDR_FROM_SDB_OFFSET(sibIn); + + sib->Header = sib->Base; + sib->HeaderSize = SEM_DAT_HEADER_VALUES * BPW_SRAM2; + + sib->Centroid = (unsigned int *)((unsigned long int)(sib->Header) + sib->HeaderSize); + sib->CentroidSize = SIB_CENTROID_VALUES * BPW_SRAM2; + + sib->Photometry = (unsigned int *)((unsigned long int)(sib->Centroid) + sib->CentroidSize); + sib->PhotometrySize = SIB_PHOTOMETRY_VALUES * BPW_SRAM2; + + sib->Lsm = (unsigned int *)((unsigned long int)(sib->Photometry) + sib->PhotometrySize); + sib->LsmSize = 0; + + sib->Rsm = (unsigned int *)((unsigned long int)(sib->Lsm) + sib->LsmSize); + sib->RsmSize = 0; + + sib->Tm = (unsigned int *)((unsigned long int)(sib->Rsm) + sib->RsmSize); + sib->TmSize = 0; + + sib->Expos = (unsigned int *)((unsigned long int)(sib->Tm) + sib->TmSize); + sib->ExposSize = sib->Xdim * sib->Ydim * BPW_PIXEL; + sib->ExposSize = (sib->ExposSize + 3) & 0xfffffffc; /* round up to 4B */ + + usedSize = ((unsigned long int)sib->Expos) + sib->ExposSize - (unsigned long int)(sib->Base); + + sib->UsedSize = usedSize; + + CrIaCopy (SIBSIZEFULL_ID, &sibSize); + + if (((unsigned int)sibSize * 1024) >= sib->UsedSize) + return sib->UsedSize; + +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR setting up SIB FULL structure with size of %u\n", sib->UsedSize); +#else + evt_data[0] = (unsigned short)((sib->UsedSize >> 16) & 0xffff); + evt_data[1] = (unsigned short)(sib->UsedSize & 0xffff); + SdpEvtRaise(3, CRIA_SERV5_EVT_IMG_INSUF, evt_data, 4); +#endif + + /* we keep the sizes for the header, centroid and photometry, but set the expos to 0 */ + sib->ExposSize = 0; + + /* set the pointers right after the photometry */ + sib->Expos = sib->Tm; + + return 0; +} + + +#ifdef GROUNDSW +/** + * @brief allocate a working buffer from the @ref ProcBuf + * @param requested_size size of the buffer that you request (see note) + * @param cestruct pointer to ComprEntStructure (it owns the ProcBuf) + * + * @returns pointer to the requested buffer or NULL if insufficient space was available + * + * @note requested size is rounded up to be word-aligned + * + */ + +unsigned int *AllocFromProcBuf (unsigned int requested_size, struct ComprEntStructure *cestruct) +{ + unsigned int wordsleft; + unsigned int *newbuffer; + unsigned short evt_data[2]; + + /* round up the requested size to word alignment */ + requested_size = (requested_size + 3) & ~0x3; + + /* check if enough space is left in the cib */ + wordsleft = (cestruct->CibSize - cestruct->UsedBufferSize) >> 2; + + SDPRINT("SIZES are: space: %d used: %d\n", cestruct->CibSize, cestruct->UsedBufferSize); + + if (4*wordsleft < requested_size) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", 4*wordsleft, requested_size); +#else + evt_data[0] = (unsigned short)((requested_size >> 16) & 0xffff); + evt_data[1] = (unsigned short)(requested_size & 0xffff); + SdpEvtRaise(3, CRIA_SERV5_EVT_SDP_NOMEM, evt_data, 4); +#endif + return NULL; + } + + /* take the tail of the procbuffer as baseptr */ + newbuffer = (unsigned int *)((unsigned long int)(cestruct->ProcBuf) + cestruct->ProcBufBufferSize); + + /* adjust procbuffer size and used size */ + cestruct->ProcBufBufferSize += requested_size; + cestruct->UsedBufferSize += requested_size; + + + return newbuffer; +} +#endif + +/** + * @brief moves the new ProcBuf pointer to the end of the previous one + * @param cestruct pointer to ComprEntStructure (it owns the ProcBuf) + * + * @note use this after @ref AllocFromProcBuf + * + */ + +void ForwardProcBuf (struct ComprEntStructure *cestruct) +{ + cestruct->ProcBuf = (unsigned int *)((unsigned long int)(cestruct->ProcBuf) + cestruct->ProcBufBufferSize); + cestruct->ProcBufBufferSize = 0; + + return; +} + +#ifdef GROUNDSW +/** + * @brief moves the ProcBuf pointer back to where it originally started + * @param cestruct pointer to ComprEntStructure (it owns the ProcBuf) + * + */ + +void ResetProcBuf (struct ComprEntStructure *cestruct) +{ + cestruct->ProcBuf = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgTDK) + cestruct->ComprImgMrgTDKBufferSize); + cestruct->ProcBufBufferSize = 0; + + cestruct->UsedBufferSize = (unsigned long int)(cestruct->ProcBuf) + cestruct->ProcBufBufferSize - (unsigned long int)(cestruct->Base); + return; +} +#endif + +/** + * @brief Forward the ProbBuf and set its Size such that it comsumes all the remaining space + * @param cestruct pointer to ComprEntStructure (it owns the ProcBuf) + * + */ + +void ProcBufBorgMode (struct ComprEntStructure *cestruct) +{ + ForwardProcBuf (cestruct); + + cestruct->ProcBufBufferSize = (cestruct->CibSize - cestruct->UsedBufferSize) & ~0x3; + + cestruct->UsedBufferSize += cestruct->ProcBufBufferSize; + + return; +} + +/** + * @brief Set up the buffer layout in the @ref CIB for compression. + * @param cestruct pointer to ComprEntStructure (it has all the controls) + * @param cibIn XIB pointer where to set it all up (just use what is set in the CrIaSdbFunc.c) + * @param Xdim horizontal size of main input image + * @param Ydim vertical size of main input image + * @param Zdim transversal size, or better stack depth, number of frames + * @param cemode @ref CEMODE_WIN (=1) or @ref CEMODE_FULL (=0) + * + * @todo this can be rewritten using the @ref AllocFromProcBuf function, such as this is done in @ref SetupDecomprBuffers, (but that does not make it shorter or simpler...) + */ + +unsigned int SetupCeBuffers (struct ComprEntStructure *cestruct, unsigned short cibIn, unsigned int Xdim, unsigned int Ydim, unsigned int Zdim, unsigned int cemode) +{ + unsigned short cibSizeWin, cibNWin, cibSizeFull, cibNFull; + unsigned int usedBufferSize; + unsigned short evt_data[2]; + + cestruct->Base = (unsigned int *)GET_ADDR_FROM_SDB_OFFSET(cibIn); + /* SDPRINT("---> the CIB base is set up at %x\n", (unsigned int)cestruct->Base); */ + + cestruct->ComprHeaders = cestruct->Base; + cestruct->ComprHeadersBufferSize = MAX_FLAT_HEADER_VALUES * Zdim * BPW_SRAM2 + OVERSIZE_HEADERS; + + cestruct->ComprImagettes = (unsigned int *)((unsigned long int)(cestruct->ComprHeaders) + cestruct->ComprHeadersBufferSize); + cestruct->ComprImagettesBufferSize = (MAX_IMAGETTES_VALUES * Zdim * BPW_SRAM2 + OVERSIZE_IMAGETTES) * cemode ; + + cestruct->ComprStacked = (unsigned int *)((unsigned long int)(cestruct->ComprImagettes) + cestruct->ComprImagettesBufferSize); + cestruct->ComprStackedBufferSize = Xdim * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_STACKED; + + cestruct->ComprImgMrgLOS = (unsigned int *)((unsigned long int)(cestruct->ComprStacked) + cestruct->ComprStackedBufferSize); +cestruct->ComprImgMrgLOSBufferSize = (IMGMRG_LOS_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LOS) * cemode ; + + cestruct->ComprImgMrgLDK = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgLOS) + cestruct->ComprImgMrgLOSBufferSize); +cestruct->ComprImgMrgLDKBufferSize = (IMGMRG_LDK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LDK) * cemode ; + + cestruct->ComprImgMrgLBLK = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgLDK) + cestruct->ComprImgMrgLDKBufferSize); +cestruct->ComprImgMrgLBLKBufferSize = (IMGMRG_LBLK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LBLK) * cemode ; + + cestruct->ComprImgMrgRBLK = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgLBLK) + cestruct->ComprImgMrgLBLKBufferSize); +cestruct->ComprImgMrgRBLKBufferSize = (IMGMRG_RBLK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_RBLK) * cemode ; + + cestruct->ComprImgMrgRDK = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgRBLK) + cestruct->ComprImgMrgRBLKBufferSize); +cestruct->ComprImgMrgRDKBufferSize = (IMGMRG_RDK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_RDK) * cemode ; + + cestruct->ComprImgMrgTOS = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgRDK) + cestruct->ComprImgMrgRDKBufferSize); +cestruct->ComprImgMrgTOSBufferSize = (IMGMRG_TOS_H * Xdim * Zdim * BPW_SRAM2 + OVERSIZE_TOS) * cemode ; + + cestruct->ComprImgMrgTDK = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgTOS) + cestruct->ComprImgMrgTOSBufferSize); +cestruct->ComprImgMrgTDKBufferSize = (IMGMRG_TDK_H * Xdim * Zdim * BPW_SRAM2 + OVERSIZE_TDK) * cemode; + + /* NOTE: do not change the order here, or the ProcBuf reset will no longer work */ + cestruct->ProcBuf = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgTDK) + cestruct->ComprImgMrgTDKBufferSize); + cestruct->ProcBufBufferSize = 0; /* NOTE: ProcBuf is "allocated" 0 bytes here, but in fact you can use cestruct->CibBufferSize - cestruct->UsedBufferSize bytes. */ + + /* overloaded buffers */ + cestruct->FlatHeaders = cestruct->ProcBuf; /* Fetcher uses the ProcBuf */ + cestruct->Stacked = cestruct->ProcBuf; + cestruct->Imagettes = cestruct->ProcBuf; + cestruct->ImgMrgLOS = cestruct->ProcBuf; + cestruct->ImgMrgLDK = cestruct->ProcBuf; + cestruct->ImgMrgLBLK = cestruct->ProcBuf; + cestruct->ImgMrgRBLK = cestruct->ProcBuf; + cestruct->ImgMrgRDK = cestruct->ProcBuf; + cestruct->ImgMrgTOS = cestruct->ProcBuf; + cestruct->ImgMrgTDK = cestruct->ProcBuf; +#if (__sparc__) + cestruct->SwapBuf = (unsigned int *)SRAM1_SWAP_ADDR; +#else + swapalloc(0, 1); + cestruct->SwapBuf = SWAPALLOC (SRAM1_SWAP_SIZE, SWAP); +#endif + + cestruct->FlatHeadersBufferSize = 0; + cestruct->StackedBufferSize = 0; + cestruct->ImagettesBufferSize = 0; + cestruct->ImgMrgLOSBufferSize = 0; + cestruct->ImgMrgLDKBufferSize = 0; + cestruct->ImgMrgLBLKBufferSize = 0; + cestruct->ImgMrgRBLKBufferSize = 0; + cestruct->ImgMrgRDKBufferSize = 0; + cestruct->ImgMrgTOSBufferSize = 0; + cestruct->ImgMrgTDKBufferSize = 0; + cestruct->SwapBufBufferSize = SRAM1_SWAP_SIZE; + + usedBufferSize = (unsigned long int)(cestruct->ProcBuf) + cestruct->ProcBufBufferSize - (unsigned long int)(cestruct->Base); + + cestruct->UsedBufferSize = usedBufferSize; + + /* we combine all CIBs, win and full into one cib */ + /* NOTE: make sure they are allocated sequentially */ + CrIaCopy (CIBSIZEWIN_ID, &cibSizeWin); + CrIaCopy (CIBSIZEFULL_ID, &cibSizeFull); + CrIaCopy (CIBNWIN_ID, &cibNWin); + CrIaCopy (CIBNFULL_ID, &cibNFull); + + /* SDPRINT("CIB Win Size: %d N:%d\n", cibSizeWin, cibNWin); */ + /* SDPRINT("CIB Full Size: %d N:%d\n", cibSizeFull, cibNFull); */ + + /* overall, the CIB is dimensioned after the larger one of Win/Full */ + cestruct->CibSize = (unsigned int)cibSizeWin * (unsigned int)cibNWin * 1024; + + if ((unsigned int)cibSizeFull * (unsigned int)cibNFull > (unsigned int)cibSizeWin * (unsigned int)cibNWin) + { + cestruct->CibSize = (unsigned int)cibSizeFull * (unsigned int)cibNFull * 1024; + } + + if (cestruct->CibSize >= cestruct->UsedBufferSize) + return cestruct->UsedBufferSize; + +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR setting up CIB compressed structure with size of %u\n", cestruct->UsedBufferSize); +#else + evt_data[0] = (unsigned short)((cestruct->UsedBufferSize >> 16) & 0xffff); + evt_data[1] = (unsigned short)(cestruct->UsedBufferSize & 0xffff); + SdpEvtRaise(3, CRIA_SERV5_EVT_CMPR_SIZE, evt_data, 4); +#endif + + return 0; +} + + +#ifdef GROUNDSW +/** + * @brief Set up the buffer layout in the @ref CIB for de-compression. + * @param cestruct pointer to ComprEntStructure (it has all the controls) + * @param cibIn XIB pointer where to set it all up (just use what is set in the CrIaSdbFunc.c) + * @param Xdim horizontal size of main input image + * @param Ydim vertical size of main input image + * @param Zdim transversal size, or better stack depth, number of frames + * + * @note This is only used on ground + */ + +unsigned int SetupDecomprBuffers (struct ComprEntStructure *cestruct, unsigned short cibIn, unsigned int Xdim, unsigned int Ydim, unsigned int Zdim) +{ + unsigned short cibSizeWin, cibNWin, cibSizeFull, cibNFull; + unsigned int request, gbOffset; + + cestruct->Base = (unsigned int *)GET_ADDR_FROM_SDB_OFFSET(cibIn); + + /* all is ProcBuf */ + cestruct->ProcBuf = cestruct->Base; + + /* and we allocate from it ... but the cibsize must be calculated first, + because it is used in AllocFroProcBuf */ + + /* we combine all CIBs, win and full into one cib */ + /* NOTE: make sure they are allocated sequentially */ + CrIaCopy (CIBSIZEWIN_ID, &cibSizeWin); + CrIaCopy (CIBSIZEFULL_ID, &cibSizeFull); + CrIaCopy (CIBNWIN_ID, &cibNWin); + CrIaCopy (CIBNFULL_ID, &cibNFull); + + /* overall, the CIB is dimensioned after the larger one of Win/Full */ + cestruct->CibSize = (unsigned int)cibSizeWin * (unsigned int)cibNWin * 1024; + + if ((unsigned int)cibSizeFull * (unsigned int)cibNFull > (unsigned int)cibSizeWin * (unsigned int)cibNWin) + { + cestruct->CibSize = (unsigned int)cibSizeFull * (unsigned int)cibNFull * 1024; + } + + /* NOTE: On ground, we allocate the buffers for the decompressed products separately */ + gbOffset = 0; + + /* Flat headers */ + request = MAX_FLAT_HEADER_VALUES * Zdim * BPW_SRAM2 + OVERSIZE_HEADERS; + cestruct->FlatHeaders = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->FlatHeadersBufferSize = request; + + /* Imagettes */ + request = MAX_IMAGETTES_VALUES * Zdim * BPW_SRAM2 + OVERSIZE_IMAGETTES; + cestruct->Imagettes = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImagettesBufferSize = request; + + /* Stacked */ + request = Xdim * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_STACKED; + cestruct->Stacked = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->StackedBufferSize = request; + + /* ImgMrgLOS */ + request = IMGMRG_LOS_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LOS; + cestruct->ImgMrgLOS = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImgMrgLOSBufferSize = request; + + /* ImgMrgLDK */ + request = IMGMRG_LDK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LDK; + cestruct->ImgMrgLDK = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImgMrgLDKBufferSize = request; + + /* ImgMrgLBLK */ + request = IMGMRG_LBLK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LBLK; + cestruct->ImgMrgLBLK = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImgMrgLBLKBufferSize = request; + + /* ImgMrgRBLK */ + request = IMGMRG_RBLK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_RBLK; + cestruct->ImgMrgRBLK = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImgMrgRBLKBufferSize = request; + + /* ImgMrgRDK */ + request = IMGMRG_RDK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_RDK; + cestruct->ImgMrgRDK = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImgMrgRDKBufferSize = request; + + /* ImgMrgTOS */ + request = IMGMRG_TOS_H * Xdim * Zdim * BPW_SRAM2 + OVERSIZE_TOS; + cestruct->ImgMrgTOS = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImgMrgTOSBufferSize = request; + + /* ImgMrgTDK */ + request = IMGMRG_TDK_H * Xdim * Zdim * BPW_SRAM2 + OVERSIZE_TDK; + cestruct->ImgMrgTDK = groundBuffer + gbOffset; + gbOffset += (request+3)/4; + cestruct->ImgMrgTDKBufferSize = request; + + if ((gbOffset * 4) > GROUNDBUFFERSIZE) + { + SDPRINT("ERROR: We cannot reserve enough space in the groundBuffer for the decompressed products!\n"); + } + + /* The buffers for the compressed data are allocated from the CIB */ + request = MAX_FLAT_HEADER_VALUES * Zdim * BPW_SRAM2 + OVERSIZE_HEADERS; + if ((cestruct->ComprHeaders = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprHeadersBufferSize = request; + + request = MAX_IMAGETTES_VALUES * Zdim * BPW_SRAM2 + OVERSIZE_IMAGETTES; + if ((cestruct->ComprImagettes = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImagettesBufferSize = request; + + request = Xdim * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_STACKED; + if ((cestruct->ComprStacked = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprStackedBufferSize = request; + + request = IMGMRG_LOS_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LOS; + if ((cestruct->ComprImgMrgLOS = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImgMrgLOSBufferSize = request; + + request = IMGMRG_LDK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LDK; + if ((cestruct->ComprImgMrgLDK = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImgMrgLDKBufferSize = request; + + request = IMGMRG_LBLK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_LBLK; + if ((cestruct->ComprImgMrgLBLK = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImgMrgLBLKBufferSize = request; + + request = IMGMRG_RBLK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_RBLK; + if ((cestruct->ComprImgMrgRBLK = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImgMrgRBLKBufferSize = request; + + request = IMGMRG_RDK_W * Ydim * Zdim * BPW_SRAM2 + OVERSIZE_RDK; + if ((cestruct->ComprImgMrgRDK = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImgMrgRDKBufferSize = request; + + request = IMGMRG_TOS_H * Xdim * Zdim * BPW_SRAM2 + OVERSIZE_TOS; + if ((cestruct->ComprImgMrgTOS = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImgMrgTOSBufferSize = request; + + request = IMGMRG_TDK_H * Xdim * Zdim * BPW_SRAM2 + OVERSIZE_TDK; + if ((cestruct->ComprImgMrgTDK = AllocFromProcBuf (request, cestruct)) != NULL) + cestruct->ComprImgMrgTDKBufferSize = request; + + + /* NOTE: do not change the order here, or the ProcBuf reset will no longer work */ + /* NOTE: ProcBuf is implicitly forwarded here */ + cestruct->ProcBuf = (unsigned int *)((unsigned long int)(cestruct->ComprImgMrgTDK) + cestruct->ComprImgMrgTDKBufferSize); + cestruct->ProcBufBufferSize = 0; /* NOTE: ProcBuf is "allocated" 0 bytes here, but in fact you can use cestruct->CibBufferSize - cestruct->UsedBufferSize bytes. */ + +#if (__sparc__) + cestruct->SwapBuf = (unsigned int *)SRAM1_SWAP_ADDR; +#else + swapalloc(0, 1); + cestruct->SwapBuf = SWAPALLOC (SRAM1_SWAP_SIZE, SWAP); +#endif + cestruct->SwapBufBufferSize = SRAM1_SWAP_SIZE; + + cestruct->UsedBufferSize = (unsigned long int)(cestruct->ProcBuf) + cestruct->ProcBufBufferSize - (unsigned long int)(cestruct->Base); + + + if (cestruct->CibSize >= cestruct->UsedBufferSize) + return cestruct->UsedBufferSize; + + return 0; +} +#endif + + +#ifdef ISOLATED +/** + * @brief print CE buffer layout for debugging + * @param cestruct pointer to ComprEntStructure + */ + +void PrintoutCeBuffers (struct ComprEntStructure *cestruct) +{ +#if (__sparc__) + SDPRINT("Base : %x\n", (unsigned int)cestruct->Base); + SDPRINT("FlatHeaders : %x \t %d\n", (unsigned int)cestruct->FlatHeaders, cestruct->FlatHeadersBufferSize); + SDPRINT("Stacked : %x \t %d\n", (unsigned int)cestruct->Stacked, cestruct->StackedBufferSize); + SDPRINT("Imagettes : %x \t %d\n", (unsigned int)cestruct->Imagettes, cestruct->ImagettesBufferSize); + SDPRINT("ImgMrgLOS : %x \t %d\n", (unsigned int)cestruct->ImgMrgLOS, cestruct->ImgMrgLOSBufferSize); + SDPRINT("ImgMrgLDK : %x \t %d\n", (unsigned int)cestruct->ImgMrgLDK, cestruct->ImgMrgLDKBufferSize); + SDPRINT("ImgMrgLBLK : %x \t %d\n", (unsigned int)cestruct->ImgMrgLBLK, cestruct->ImgMrgLBLKBufferSize); + SDPRINT("ImgMrgRBLK : %x \t %d\n", (unsigned int)cestruct->ImgMrgRBLK, cestruct->ImgMrgRBLKBufferSize); + SDPRINT("ImgMrgRDK : %x \t %d\n", (unsigned int)cestruct->ImgMrgRDK, cestruct->ImgMrgRDKBufferSize); + SDPRINT("ImgMrgTOS : %x \t %d\n", (unsigned int)cestruct->ImgMrgTOS, cestruct->ImgMrgTOSBufferSize); + SDPRINT("ImgMrgTDK : %x \t %d\n", (unsigned int)cestruct->ImgMrgTDK, cestruct->ImgMrgTDKBufferSize); + SDPRINT("ComprHeaders : %x \t %d\n", (unsigned int)cestruct->ComprHeaders, cestruct->ComprHeadersBufferSize); + SDPRINT("ComprImagettes : %x \t %d\n", (unsigned int)cestruct->ComprImagettes, cestruct->ComprImagettesBufferSize); + SDPRINT("ComprStacked : %x \t %d\n", (unsigned int)cestruct->ComprStacked, cestruct->ComprStackedBufferSize); + SDPRINT("ComprImgMrgLOS : %x \t %d\n", (unsigned int)cestruct->ComprImgMrgLOS, cestruct->ComprImgMrgLOSBufferSize); + SDPRINT("ComprImgMrgLDK : %x \t %d\n", (unsigned int)cestruct->ComprImgMrgLDK, cestruct->ComprImgMrgLDKBufferSize); + SDPRINT("ComprImgMrgLBLK: %x \t %d\n", (unsigned int)cestruct->ComprImgMrgLBLK, cestruct->ComprImgMrgLBLKBufferSize); + SDPRINT("ComprImgMrgRBLK: %x \t %d\n", (unsigned int)cestruct->ComprImgMrgRBLK, cestruct->ComprImgMrgRBLKBufferSize); + SDPRINT("ComprImgMrgRDK : %x \t %d\n", (unsigned int)cestruct->ComprImgMrgRDK, cestruct->ComprImgMrgRDKBufferSize); + SDPRINT("ComprImgMrgTOS : %x \t %d\n", (unsigned int)cestruct->ComprImgMrgTOS, cestruct->ComprImgMrgTOSBufferSize); + SDPRINT("ComprImgMrgTDK : %x \t %d\n", (unsigned int)cestruct->ComprImgMrgTDK, cestruct->ComprImgMrgTDKBufferSize); + SDPRINT("ProcBuf : %x \t %d\n", (unsigned int)cestruct->ProcBuf, cestruct->ProcBufBufferSize); + SDPRINT("SwapBuf : %x \t %d\n", (unsigned int)cestruct->SwapBuf, cestruct->SwapBufBufferSize); + + SDPRINT("Used size: %d\n", cestruct->UsedBufferSize); + SDPRINT("Cib size: %d\n", cestruct->CibSize); +#else + SDPRINT("Base : %lx\n", (unsigned long int)cestruct->Base); + SDPRINT("FlatHeaders : %lx \t %d\n", (unsigned long int)cestruct->FlatHeaders, cestruct->FlatHeadersBufferSize); + SDPRINT("Stacked : %lx \t %d\n", (unsigned long int)cestruct->Stacked, cestruct->StackedBufferSize); + SDPRINT("Imagettes : %lx \t %d\n", (unsigned long int)cestruct->Imagettes, cestruct->ImagettesBufferSize); + SDPRINT("ImgMrgLOS : %lx \t %d\n", (unsigned long int)cestruct->ImgMrgLOS, cestruct->ImgMrgLOSBufferSize); + SDPRINT("ImgMrgLDK : %lx \t %d\n", (unsigned long int)cestruct->ImgMrgLDK, cestruct->ImgMrgLDKBufferSize); + SDPRINT("ImgMrgLBLK : %lx \t %d\n", (unsigned long int)cestruct->ImgMrgLBLK, cestruct->ImgMrgLBLKBufferSize); + SDPRINT("ImgMrgRBLK : %lx \t %d\n", (unsigned long int)cestruct->ImgMrgRBLK, cestruct->ImgMrgRBLKBufferSize); + SDPRINT("ImgMrgRDK : %lx \t %d\n", (unsigned long int)cestruct->ImgMrgRDK, cestruct->ImgMrgRDKBufferSize); + SDPRINT("ImgMrgTOS : %lx \t %d\n", (unsigned long int)cestruct->ImgMrgTOS, cestruct->ImgMrgTOSBufferSize); + SDPRINT("ImgMrgTDK : %lx \t %d\n", (unsigned long int)cestruct->ImgMrgTDK, cestruct->ImgMrgTDKBufferSize); + SDPRINT("ComprHeaders : %lx \t %d\n", (unsigned long int)cestruct->ComprHeaders, cestruct->ComprHeadersBufferSize); + SDPRINT("ComprImagettes : %lx \t %d\n", (unsigned long int)cestruct->ComprImagettes, cestruct->ComprImagettesBufferSize); + SDPRINT("ComprStacked : %lx \t %d\n", (unsigned long int)cestruct->ComprStacked, cestruct->ComprStackedBufferSize); + SDPRINT("ComprImgMrgLOS : %lx \t %d\n", (unsigned long int)cestruct->ComprImgMrgLOS, cestruct->ComprImgMrgLOSBufferSize); + SDPRINT("ComprImgMrgLDK : %lx \t %d\n", (unsigned long int)cestruct->ComprImgMrgLDK, cestruct->ComprImgMrgLDKBufferSize); + SDPRINT("ComprImgMrgLBLK: %lx \t %d\n", (unsigned long int)cestruct->ComprImgMrgLBLK, cestruct->ComprImgMrgLBLKBufferSize); + SDPRINT("ComprImgMrgRBLK: %lx \t %d\n", (unsigned long int)cestruct->ComprImgMrgRBLK, cestruct->ComprImgMrgRBLKBufferSize); + SDPRINT("ComprImgMrgRDK : %lx \t %d\n", (unsigned long int)cestruct->ComprImgMrgRDK, cestruct->ComprImgMrgRDKBufferSize); + SDPRINT("ComprImgMrgTOS : %lx \t %d\n", (unsigned long int)cestruct->ComprImgMrgTOS, cestruct->ComprImgMrgTOSBufferSize); + SDPRINT("ComprImgMrgTDK : %lx \t %d\n", (unsigned long int)cestruct->ComprImgMrgTDK, cestruct->ComprImgMrgTDKBufferSize); + SDPRINT("ProcBuf : %lx \t %d\n", (unsigned long int)cestruct->ProcBuf, cestruct->ProcBufBufferSize); + SDPRINT("SwapBuf : %lx \t %d\n", (unsigned long int)cestruct->SwapBuf, cestruct->SwapBufBufferSize); + + SDPRINT("Used size: %d\n", cestruct->UsedBufferSize); + SDPRINT("Cib size: %d\n", cestruct->CibSize); +#endif + + return; +} +#endif + + +/** + * @brief collect data from the @ref SIB header and assemble as flat array in the FlatHeader section of the CeBuffer. + * @param Headers pointer to a ScienceBuf structure (the Compression has one) + */ + +void SibToFlatHeaders (struct ScienceBuf *Headers, struct ComprEntStructure *cestruct) +{ + unsigned int i, push_back; + unsigned int *uip; + int status; + unsigned short ustemp1, ustemp2; + struct CrIaSib sib; + struct SibHeader *sibHeader; + struct SibCentroid *sibCentroid; + struct SibPhotometry *sibPhotometry; + unsigned short sibIn, sibOut, newSibOut, sibSizeWin, sibNWin, sibSizeFull, sibNFull, sdbstate; + unsigned long int xibOffset; + unsigned int *FlatHeaders = (unsigned int *) Headers->data; + + /* get Sib parameters and state of SDB (WIN or FULL) */ + CrIaCopy (SIBIN_ID, &sibIn); + CrIaCopy (SIBOUT_ID, &sibOut); + CrIaCopy (SIBSIZEWIN_ID, &sibSizeWin); + CrIaCopy (SIBNWIN_ID, &sibNWin); + CrIaCopy (SIBSIZEFULL_ID, &sibSizeFull); + CrIaCopy (SIBNFULL_ID, &sibNFull); + CrIaCopy (SDBSTATE_ID, &sdbstate); + + push_back = 0; + + /* loop over frames */ + for (i=0; i < Headers->zelements; i++) + { + /* setup SIB structure using current sibOut (the compression is the SIB consumer, thus it reads from "out") */ + status = 0; + if (sdbstate == CrIaSdb_CONFIG_WIN) + status = CrIaSetupSibWin (&sib, sibOut, Headers->xelements, Headers->yelements); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + status = CrIaSetupSibFull (&sib, sibOut); + + if (status == 0) + { + /* error gets reported by setup function */ + break; + } + + /* init structure pointers */ + sibHeader = (struct SibHeader *) sib.Header; + sibCentroid = (struct SibCentroid *) sib.Centroid; + sibPhotometry = (struct SibPhotometry *) sib.Photometry; + + /* NOTE: There are a few cestruct parameters left, which were not initialized from data pool, + but which shall come from the first SIB header. We initialize them here. + They are not used at all by the compression, but the collection wants them. */ + if (i == 0) + { + cestruct->AcquisitionMode = sibHeader->AcqType; /* CCD_FULL etc */ + cestruct->FrameSource = sibHeader->AcqSrc; + cestruct->ExposureTime = sibHeader->ExposureTime; + } + + /* enter the header parameters from the SIB into the flat header array */ + FlatHeaders[push_back++] = sibHeader->AcqId; /* 4B SemHkStatDataAcqId */ + FlatHeaders[push_back++] = sibHeader->VoltFeeVod; /* 4B HkVoltFeeVod */ + FlatHeaders[push_back++] = sibHeader->VoltFeeVrd; /* 4B HkVoltFeeVrd */ + FlatHeaders[push_back++] = sibHeader->VoltFeeVog; /* 4B HkVoltFeeVog */ + FlatHeaders[push_back++] = sibHeader->VoltFeeVss; /* 4B HkVoltFeeVss */ + FlatHeaders[push_back++] = sibHeader->TempFeeCcd; /* 4B HkTempFeeCcd */ + FlatHeaders[push_back++] = sibHeader->TempFeeAdc; /* 4B HkTempFeeAdc */ + FlatHeaders[push_back++] = sibHeader->TempFeeBias; /* 4B HkTempFeeBias */ + ustemp1 = sibHeader->N5V; + ustemp2 = sibHeader->Temp1; + FlatHeaders[push_back++] = PACKSHORTS(ustemp1,ustemp2); /* 2B | 2B */ + ustemp1 = sibHeader->TempOh1A; + ustemp2 = sibHeader->TempOh1B; + FlatHeaders[push_back++] = PACKSHORTS(ustemp1,ustemp2); /* 2B | 2B */ + ustemp1 = sibHeader->TempOh2A; + ustemp2 = sibHeader->TempOh2B; + FlatHeaders[push_back++] = PACKSHORTS(ustemp1,ustemp2); /* 2B | 2B */ + ustemp1 = sibHeader->TempOh3A; + ustemp2 = sibHeader->TempOh3B; + FlatHeaders[push_back++] = PACKSHORTS(ustemp1,ustemp2); /* 2B | 2B */ + ustemp1 = sibHeader->TempOh4A; + ustemp2 = sibHeader->TempOh4B; + FlatHeaders[push_back++] = PACKSHORTS(ustemp1,ustemp2); /* 2B | 2B */ + ustemp1 = sibHeader->CcdTimingScriptId; + ustemp2 = sibHeader->PixDataOffset; + FlatHeaders[push_back++] = PACKSHORTS(ustemp1,ustemp2); /* 2B CcdTimingScript | 2B PixDataOffset */ + /* pack Centroid */ + FlatHeaders[push_back++] = sibCentroid->offsetX; /* 3B stored in 4B */ + FlatHeaders[push_back++] = sibCentroid->offsetY; /* 3B stored in 4B */ + FlatHeaders[push_back++] = sibCentroid->targetLocX; /* 3B stored in 4B */ + FlatHeaders[push_back++] = sibCentroid->targetLocY; /* 3B stored in 4B */ + FlatHeaders[push_back++] = sibCentroid->startIntegCoarse; /* 4B */ + FlatHeaders[push_back++] = sibCentroid->startIntegFine; /* 2B stored in 4B */ + FlatHeaders[push_back++] = sibCentroid->endIntegCoarse; /* 4B */ + FlatHeaders[push_back++] = sibCentroid->endIntegFine; /* 2B stored in 4B */ + FlatHeaders[push_back++] = PACKSHORTS(sibCentroid->dataCadence, sibCentroid->validityStatus); /* 2B Cadence | 1B spare | 1B Validity */ + /* pack Photometry */ + uip = (unsigned int *)&sibPhotometry->centrum; /* 4B */ + FlatHeaders[push_back++] = *uip; + uip = (unsigned int *)&sibPhotometry->annulus1; + FlatHeaders[push_back++] = *uip; + uip = (unsigned int *)&sibPhotometry->annulus2; + FlatHeaders[push_back++] = *uip; + + + if (i < Headers->zelements - 1) /* don't update for the last frame */ + { + /* move to the next sibIn in sequence */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + } + else + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressFull); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeFull, (unsigned int)sibNFull, SIBOUT_FULL_XIB); + } + + /* NOTE: if SIBOUT couldn't be incremented, we clone the last one */ + + sibOut = newSibOut; + } + + /* NOTE: We do not write back SIBOUT into the DP here */ + } + + if (MAX_FLAT_HEADER_VALUES * i != push_back) + SDPRINT("ERROR assembling flat header array! %d != %d\n", MAX_FLAT_HEADER_VALUES * i, push_back); + + return; +} + + + +/** + * @brief copy values packed as unsigned shorts into ints + * + * @param[out] dest pointer to the output array + * @param[in] src pointer to the input array of shorts + * @param[in] nValues number of values to be copied + * + * @returns number of words written + * @note the output data must be 4-byte aligned + * @note this version also works in SRAM2 + */ + +unsigned int UnpackU16ToU32 (uint32_t *src, uint32_t nValues, uint32_t *dest, uint32_t swapFlag) +{ + uint32_t i, j, nHalf; + + nHalf = nValues >> 1; + + if (swapFlag == UNPACK_NOSWAP) + { + for (i=0, j=0; i < nHalf; i++) + { + dest[j++] = src[i] >> 16; + dest[j++] = src[i] & 0xffff; + } + + /* treat the last sample of an odd number of input samples */ + if (nValues & 0x01) + dest[j++] = src[i] >> 16; + } + else + { + for (i=0, j=0; i < nHalf; i++) + { + dest[j++] = src[i] & 0xffff; + dest[j++] = src[i] >> 16; + } + + /* treat the last sample of an odd number of input samples */ + if (nValues & 0x01) + dest[j++] = src[i] & 0xffff; + } + + return j; +} + +/** + * @brief copy values packed as unsigned shorts into ints + * @param[out] dest pointer to the output array + * @param[in] src pointer to the input array of shorts + * @param[in] nValues number of values to be copied + * @returns number of halfwords written + * + * @note the output data must be 4-byte aligned + * @note this version also works in SRAM2 + */ + +/* NOTE: the input data must be 4-byte aligned */ +unsigned int PackU16FromU32 (uint32_t *src, uint32_t nValues, uint32_t *dest, uint32_t swapFlag) +{ + uint32_t i, j, nHalf; + + nHalf = nValues >> 1; + + if (swapFlag == 0) + { + for (i=0, j=0; i < nHalf; i++) + { + dest[i] = src[j++] << 16; + dest[i] |= src[j++] & 0xffff; + } + + /* treat the last sample of an odd number of input samples */ + if (nValues & 0x01) + { + /* do not overwrite the other half word */ + dest[i] &= 0xffff; + dest[i] |= src[j++] << 16; + /* i++; */ + } + } + else + { + for (i=0, j=0; i < nHalf; i++) + { + dest[i] = src[j++] & 0xffff; + dest[i] |= src[j++] << 16; + } + + /* treat the last sample of an odd number of input samples */ + if (nValues & 0x01) + { + /* do not overwrite the other half word */ + dest[i] &= 0xffff0000; + dest[i] |= src[j++] & 0xffff; + /* i++; */ + } + } + + return j; +} + + +/** + * @brief initialize a swap science buffer with the needed values + * @param swapbuffer pointer to a @ref ScienceBuf struct + * @param cestruct pointer to the ComprEntStructure (where the buffer location is taken from) + */ + +void PrepareSwap (struct ScienceBuf *swapbuffer, struct ComprEntStructure *cestruct) +{ + /* prepare a swap buffer that uses the SwapBuf of the CE structure */ + swapbuffer->datatype = DATATYPE_UINT32; + swapbuffer->xelements = cestruct->SwapBufBufferSize / TYPESIZE(DATATYPE_UINT32); + swapbuffer->yelements = 1; + swapbuffer->zelements = 1; + swapbuffer->nelements = swapbuffer->xelements * swapbuffer->yelements * swapbuffer->zelements; + swapbuffer->data = (void *) cestruct->SwapBuf; + + return; +} + diff --git a/CompressionEntity/src/SdpBuffers.h b/CompressionEntity/src/SdpBuffers.h new file mode 100644 index 0000000000000000000000000000000000000000..6f6e261caaa7e4f856f113c5593a1d7c5825f77b --- /dev/null +++ b/CompressionEntity/src/SdpBuffers.h @@ -0,0 +1,299 @@ +/** + * @file SdpBuffers.h + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef SDP_BUFFERS_H +#define SDP_BUFFERS_H + +#include <stdint.h> /* for uint32_t */ +#include "SdpCeDefinitions.h" +#include "SdpCompressionEntityStructure.h" + +/* access to RAM */ +#if (__sparc__) +#include <wrap_malloc.h> +#else +#define SRAM1_SWAP_SIZE 0x600000 +#define SRAM1_RES_SIZE 0x800000 +#define SRAM1_FLASH_SIZE 0x420000 +#endif + +#define MAX_FLAT_HEADER_VALUES 26 +#define MAX_IMAGETTES_VALUES (100*100) +#define MAX_STCK_ORDER 100 +#define OVERSIZE_HEADERS 32 +#define OVERSIZE_IMAGETTES 0 +#define OVERSIZE_STACKED 0 +#define OVERSIZE_LOS 0 +#define OVERSIZE_LDK 0 +#define OVERSIZE_LBLK 0 +#define OVERSIZE_RBLK 0 +#define OVERSIZE_RDK 0 +#define OVERSIZE_TOS 0 +#define OVERSIZE_TDK 0 + +/* from CrIaIasw.h */ +extern unsigned long int sdb_offset, res_offset, aux_offset, swap_offset; +extern unsigned int *sibAddressFull, *cibAddressFull, *gibAddressFull; +extern unsigned int *sibAddressWin, *cibAddressWin, *gibAddressWin; + +#define GET_SDB_OFFSET_FROM_ADDR(address) ( ((unsigned long int)address - sdb_offset) >> 10 ) +#define GET_RES_OFFSET_FROM_ADDR(address) ( ((unsigned long int)address - res_offset) >> 10 ) + +#define GET_ADDR_FROM_SDB_OFFSET(iboffset) ( (unsigned long int)sdb_offset + 1024*iboffset ) +#define GET_ADDR_FROM_RES_OFFSET(iboffset) ( (unsigned long int)res_offset + 1024*iboffset ) +#define GET_ADDR_FROM_AUX_OFFSET(iboffset) ( (unsigned long int)aux_offset + 1024*iboffset ) +#define GET_ADDR_FROM_SWAP_OFFSET(iboffset) ( (unsigned long int)swap_offset + 1024*iboffset ) + +#define PACKSHORTS(a,b) ( ((unsigned int)a << 16) | ((unsigned int)b & 0xffff) ) + + +/* from wrap_malloc.h */ +#define BPW_SRAM2 4 +#define BPW_PIXEL 2 + +#define DESTBUF 1 +#define SRCBUF 0 + +#define SEM_DAT_HEADER_VALUES ((sizeof(struct SibHeader) + 3)>>2) /* = 26 */ +#define FLAT_HEADER_VALUES 26 /* as used in FlatHeaders */ +#define SIB_CENTROID_VALUES 10 +#define SIB_PHOTOMETRY_VALUES 4 + +#define LSM_XDIM 28 +#define RSM_XDIM 24 +#define TM_YDIM 9 + +#ifndef CRIA_CONSTANTS_H +#define FULL_SIZE_X 1076 +#define FULL_SIZE_Y 1033 +#endif + +#ifndef CrIaSdbCreate_H_ +#define CrIaSdb_CONFIG_FULL 1 +#define CrIaSdb_CONFIG_WIN 2 +#define CrIaSdb_UNCONFIGURED 3 +#endif + +#define CEMODE_FULL 0 +#define CEMODE_WIN 1 + +#define DATA_OK 0 +#define DATA_SAA 1 +#define DATA_NOK 2 +#define DATA_SUSPEND 3 + +#define SIBIN_FULL_XIB 1 +#define SIBIN_WIN_XIB 2 +#define SIBOUT_FULL_XIB 3 +#define SIBOUT_WIN_XIB 4 +#define GIBIN_FULL_XIB 5 +#define GIBIN_WIN_XIB 6 +#define GIBOUT_FULL_XIB 7 +#define GIBOUT_WIN_XIB 8 + +/** + * @brief SIB sub-structure to keep centroid data for later inclusion in science header + * @note all of these need to be 4-byte aligned because it will be used in SRAM2 + */ + +struct SibCentroid { + int offsetX; + int offsetY; + unsigned int startIntegFine; + unsigned int endIntegFine; + unsigned int dataCadence; + unsigned int targetLocX; + unsigned int targetLocY; + unsigned int startIntegCoarse; + unsigned int endIntegCoarse; + unsigned int validityStatus; +} ; + + +/** + * @brief SIB Sub-structure to keep quick photometry results of science data processing + */ + +struct SibPhotometry { + unsigned int FlagsActive; /* this has the SAA/SDS flag info */ + float centrum; /* Mantis 2212: This is used to store Gain0 */ + float annulus1; /* Mantis 2212: This is used to store Bias0 */ + float annulus2; /* Mantis 2212: This is used to store Bias */ +} ; + + +/** + * @brief Structure to hold the variables extracted from the DAT_CCD packets from SEM + */ + +struct SibHeader { + unsigned int AcqId; + unsigned int AcqType; + unsigned int AcqSrc; + unsigned int CcdTimingScriptId; /* new in ICD 2.1 */ + unsigned int startTimeCoarse; + unsigned int startTimeFine; + unsigned int ExposureTime; + unsigned int TotalPacketNum; + unsigned int CurrentPacketNum; + unsigned int VoltFeeVod; + unsigned int VoltFeeVrd; + unsigned int VoltFeeVog; + unsigned int VoltFeeVss; + unsigned int TempFeeCcd; + unsigned int TempFeeAdc; + unsigned int TempFeeBias; + unsigned int N5V; + unsigned int Temp1; + unsigned int PixDataOffset; /* new in ICD 2.1 */ + unsigned int NumDataWords; + unsigned int TempOh1A; + unsigned int TempOh1B; + unsigned int TempOh2A; + unsigned int TempOh2B; + unsigned int TempOh3A; + unsigned int TempOh3B; + unsigned int TempOh4A; + unsigned int TempOh4B; +} ; + + +/** + * @brief this structure keeps track of a @ref SIB's internal pointers + * @note all types have to be 4 bytes aligned + */ + +struct CrIaSib { + unsigned int *Base; + unsigned int *Header; /* int[26] */ + unsigned int *Centroid; /* int[10] */ + unsigned int *Photometry; /* float[3] */ + unsigned int *Lsm; + unsigned int *Rsm; + unsigned int *Tm; + unsigned int *Expos; + unsigned int LsmSamples; + unsigned int RsmSamples; + unsigned int TmSamples; + unsigned int ExposSamples; + unsigned int HeaderSize; + unsigned int CentroidSize; + unsigned int PhotometrySize; + unsigned int LsmSize; + unsigned int RsmSize; + unsigned int TmSize; + unsigned int ExposSize; + unsigned int Xdim; + unsigned int Ydim; + unsigned int UsedSize; +} ; + + +/** + * @brief a flat buffer structure for the science data processing steps. + * Such a buffer has a pointer to the data, a datatype for the elements (see @ref SdpCeDefinitions.h and the @ref TYPESIZE macro) + * and length specifiers in three dimensions (XYZ). @ref nelements is the product of the three. + */ + +struct ScienceBuf { + unsigned int datatype; + unsigned int nelements; + unsigned int xelements; + unsigned int yelements; + unsigned int zelements; + void *data; +} ; + + +/** + * @brief same as the @ref ScienceBuf structure, but also with two additional variables, one keeping track of the compressed size + * and the other one stores the checksum on the buffer's way through the compression. + * + */ + +/* a flat buffer structure for compressed data */ +struct CompressedBuf { + unsigned int datatype; + unsigned int llcsize; /* compressed size (bytes) */ + unsigned int nelements; /* number of elements that went into llc */ + unsigned int xelements; + unsigned int yelements; + unsigned int zelements; /* number of frames, e.g. for imagettes */ + unsigned int lossyCrc; /* CRC after lossy steps */ + void *data; +} ; + +#if (__sparc__) +#define SDBALLOC(s,id) alloc(s, id) +#define RESALLOC(s,id) alloc(s, id) +#define AUXALLOC(s,id) alloc(s, id) +#define SWAPALLOC(s,id) alloc(s, id) +#else +#define SDBALLOC(s,id) ((unsigned int *)sdballoc(s, 0)) +#define RESALLOC(s,id) ((unsigned int *)resalloc(s, 0)) +#define AUXALLOC(s,id) ((unsigned int *)auxalloc(s, 0)) +#define SWAPALLOC(s,id) ((unsigned int *)swapalloc(s, 0)) +unsigned int * sdballoc (unsigned int size, unsigned char reset); +unsigned int * resalloc (unsigned int size, unsigned char reset); +unsigned int * auxalloc (unsigned int size, unsigned char reset); +unsigned int * swapalloc (unsigned int size, unsigned char reset); +#endif + +unsigned int * FloatpAsUintp (float *fp); + +float * UintpAsFloatp (unsigned int *uip); + +void InitComprEntStructureFromDataPool (struct ComprEntStructure *cestruct); + +unsigned short updateXib(unsigned int currentXib, unsigned int borderXib, unsigned long int xibOffset, unsigned int xibSize, unsigned int xibN, unsigned short xib_err_id); + +unsigned short updateXibFwd(unsigned int currentXib, unsigned int borderXib, unsigned long int xibOffset, unsigned int xibSize, unsigned int xibN, unsigned short xib_err_id); + +unsigned short updateXibNTimesFwd(unsigned int currentXib, unsigned int borderXib, unsigned long int xibOffset, unsigned int xibSize, unsigned int xibN, unsigned int Nupdates, unsigned short xib_err_id); + +unsigned int CrIaSetupSibWin (struct CrIaSib *sib, unsigned short sibIn, unsigned int Xdim, unsigned int Ydim); + +unsigned int CrIaSetupSibFull (struct CrIaSib *sib, unsigned short sibIn); + +void ForwardProcBuf (struct ComprEntStructure *cestruct); + +void ProcBufBorgMode (struct ComprEntStructure *cestruct); + +unsigned int SetupCeBuffers (struct ComprEntStructure *cestruct, unsigned short cibIn, unsigned int Xdim, unsigned int Ydim, unsigned int Zdim, unsigned int cemode); + +#ifdef GROUNDSW +void ResetProcBuf (struct ComprEntStructure *cestruct); +unsigned int *AllocFromProcBuf (unsigned int requested_size, struct ComprEntStructure *cestruct); +unsigned int SetupDecomprBuffers (struct ComprEntStructure *cestruct, unsigned short cibIn, unsigned int Xdim, unsigned int Ydim, unsigned int Zdim); +#endif + +#ifdef DEBUGSDP +void PrintoutCeBuffers (struct ComprEntStructure *cestruct); +#endif + +void SibToFlatHeaders (struct ScienceBuf *Headers, struct ComprEntStructure *cestruct); + +#define UNPACK_NOSWAP 0 +#define UNPACK_SWAP 1 + +unsigned int UnpackU16ToU32 (uint32_t *src, uint32_t nValues, uint32_t *dest, uint32_t swapFlag); + +unsigned int PackU16FromU32 (uint32_t *src, uint32_t nValues, uint32_t *dest, uint32_t swapFlag); + +void PrepareSwap (struct ScienceBuf *swapbuffer, struct ComprEntStructure *cestruct); + +#endif diff --git a/CompressionEntity/src/SdpCeDefinitions.h b/CompressionEntity/src/SdpCeDefinitions.h new file mode 100644 index 0000000000000000000000000000000000000000..268f43907a65703a43b20629d122d7965e3829b9 --- /dev/null +++ b/CompressionEntity/src/SdpCeDefinitions.h @@ -0,0 +1,251 @@ +/** + * @file SdpCeDefinitions.h + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief various structures and defines used when dealing with a @ref ComprEntStructure + * + */ + +#ifndef SDP_COMPRESSION_ENTITY_DEFINITIONS_H +#define SDP_COMPRESSION_ENTITY_DEFINITIONS_H + + +/** + * @brief datatypes used in compression, especially in the @ref TYPESIZE macro + * @warning never change! + */ + +#define DATATYPE_INT8 1 +#define DATATYPE_UINT8 2 +#define DATATYPE_INT16 3 +#define DATATYPE_UINT16 4 +#define DATATYPE_INT32 7 +#define DATATYPE_UINT32 8 + + +/** + * @brief return the number of bytes used by a particular type + * @note this is a funny way to do it, but it could be done in a safer way + */ + +#define TYPESIZE(x) ((unsigned int)(x+1)/2) + + +/** + * @{ + * @brief CCD window types and dimensions + */ + +#define ACQ_TYPE_WIN_EXPOS 1 /* used in CE header to identify a window observation */ +#define ACQ_TYPE_WIN_LSM 2 +#define ACQ_TYPE_WIN_RSM 3 +#define ACQ_TYPE_WIN_TM 4 +#define ACQ_TYPE_FULL 5 /* used in CE header to identify a full frame observation */ +/** @} */ + + +/** + * @brief CCD window dimensions + */ + +#define CCD_IMAGE_X 1024 +#define CCD_IMAGE_Y 1024 +#define CCD_WIN_LSM 28 +#define CCD_WIN_RSM 24 +#define CCD_FULL_X 1076 +#define CCD_FULL_Y 1033 +#define CCD_FULL_YRED 1027 +#define IMGMRG_TOS_H 6 +#define IMGMRG_TDK_H 3 +#define IMGMRG_LOS_W 4 +#define IMGMRG_LBLK_W 8 +#define IMGMRG_LDK_W 16 +#define IMGMRG_RDK_W 16 +#define IMGMRG_RBLK_W 8 + +/* possible values for the windows, stacked and imagettes shape */ +#define SHAPE_RECTANGULAR 0 +#define SHAPE_CIRCULAR 1 + +#define STRAT_STATIC 0 +#define STRAT_MOVING 1 + +#define STAT_MEAN 0 +#define STAT_MEDIAN 1 + +/* masks for the keys */ +#define SDP_PRODUCT 0xf0000000 +#define SDP_PREPROC 0x0f000000 +#define SDP_LOSSY1 0x00f00000 +#define SDP_LOSSY2 0x000f0000 +#define SDP_LOSSY3 0x0000f000 +#define SDP_DECORR 0x00000f00 +#define SDP_SPARE2 0x000000f0 +#define SDP_LLC 0x0000000f + +/* defines used to shape the CeKey */ +#define PRODUCT_HEADERS 0x10000000 +#define PRODUCT_IMAGETTES 0x20000000 +#define PRODUCT_STACKED 0x30000000 +#define PRODUCT_MRGLOS 0x40000000 +#define PRODUCT_MRGLBLK 0x50000000 +#define PRODUCT_MRGLDK 0x60000000 +#define PRODUCT_MRGRDK 0x70000000 +#define PRODUCT_MRGRBLK 0x80000000 +#define PRODUCT_MRGTOS 0x90000000 +#define PRODUCT_MRGTDK 0xA0000000 +#define PRODUCT_DISABLE 0xF0000000 +/* Preprocessing */ +#define PREPROC_NONE 0x00000000 +#define PREPROC_NLC 0x01000000 +#define PREPROC_NLCPHOT 0x02000000 +#define PREPROC_NLC2 0x03000000 +#define PREPROC_PHOT 0x05000000 +/* Lossy Step 1 */ +#define LOSSY1_NONE 0x00000000 +#define LOSSY1_COADD 0x00100000 +#define LOSSY1_MEAN 0x00200000 +#define LOSSY1_GMEAN 0x00800000 +#define LOSSY1_GCOADD 0x00900000 +/* Lossy Step 2 */ +#define LOSSY2_NONE 0x00000000 +#define LOSSY2_3STAT 0x00010000 +#define LOSSY2_3STATUI 0x00020000 +#define LOSSY2_4STAT 0x00030000 +#define LOSSY2_CIRCMASK 0x00040000 +#define LOSSY2_CIRCEXTRACT 0x00050000 +#define LOSSY2_3STATUI_ROW 0x00090000 +#define LOSSY2_3STATUI_COL 0x000A0000 +/* Lossy Step 3 */ +#define LOSSY3_NONE 0x00000000 +#define LOSSY3_ROUND1 0x00001000 +#define LOSSY3_ROUND2 0x00002000 +#define LOSSY3_ROUND3 0x00003000 +#define LOSSY3_ROUND4 0x00004000 +#define LOSSY3_ROUND5 0x00005000 +#define LOSSY3_ROUND6 0x00006000 +/* Decorrelation */ +#define DECORR_NONE 0x00000000 +#define DECORR_DIFF 0x00000100 +#define DECORR_KEYFR 0x00000200 +#define DECORR_IWT1 0x00000300 +#define DECORR_IWT2 0x00000400 +/* + in principle there is space for another step: + here: 0x000000X0 +*/ +/* Lossless Compression */ +#define LLC_NONE 0x00000000 +#define LLC_RZIP 0x00000001 +#define LLC_ARI1 0x00000003 +#define LLC_PACK16 0x00000007 + + +/** + * @brief convenient CUC time structure + */ + +struct cuctime +{ + /* in the CE, the sizes are 32 + 15 + 1 + here we use more convenient types + + coarse time counts seconds since 01-01-2000 00:00:00 TAI + This is defined by requirement CIS-SW-ICD-057 of ICD-049 */ + unsigned int coarse; + + /* fine time counts fractions of seconds */ + unsigned short fine; /* last bit is cleared (it is the sync bit) */ + + /* flag showing synchronization is LSbit of fine time */ + unsigned short sync; /* 0..desync 1..sync */ +} ; + + +#ifdef GROUNDSW +/** + * @brief convenient centroid structure for ground usage + * @note The origin is the bottom left pixel starting with the margin, its center is 50/50 + * before you ask: (we don't care about the rounded 5 mas systematic shift) + * @warning Do not mix with struct SibCentroid! + * @note only used on ground + */ + +struct Centroid { + int OffsetX; /* residual (measured-intended) in X given in centiarcsec [24 bits used] */ + int OffsetY; /* residual in Y given in centiarcsec [24 bits used] */ + unsigned int TargetLocationX; /* position on CCD in centiarcsec, [24 bits used] */ + unsigned int TargetLocationY; /* origin is bottom left pixel corner in margin area [24 bits used] */ + struct cuctime StartIntegration; /* start time of integration (no sync) [48 bits used] */ + struct cuctime EndIntegration; /* timestamp end of exposure (no sync) [48 bits used] */ + unsigned short Cadence; /* centroid data cadence in centisec [16 bits used] */ + unsigned char Validity; /* validity of this centroid [ 8 bits used] */ +} ; /* total size = 27 B, actually: 36 */ + + +/** + * @brief data structure for the uncompressed header data + * @note only used on ground + */ + +struct Meterology { + unsigned int SemHkStatDataAcqId; + float HkVoltFeeVod; + float HkVoltFeeVrd; + float HkVoltFeeVog; + float HkVoltFeeVss; + float HkTempFeeCcd; + float HkTempFeeAdc; + float HkTempFeeBias; + float ThermAft1; + float ThermAft2; + float ThermAft3; + float ThermAft4; + float ThermFront1; + float ThermFront2; + float ThermFront3; + float ThermFront4; + float N5V; + float Temp1; + unsigned short CcdTimingScript; + unsigned short PixDataOffset; + struct Centroid Centroid; /* 27B packed in 36B, not as a pointer because we want sizeof(Meterology) consider this */ + float Phot1; + float Phot2; + float Phot3; +} ; /* 4 + 28 + 32 + 8 + 27 + 3*4 = 111, actually: 120 (Centroid is 36 in aligned words) */ +#endif + + +/** + * @brief small structure to hold the mean, stdev, median and MAD + * + */ + +struct StatValues { + float mean; + float stdev; + unsigned int median; + unsigned int mad; +} ; + +#if (__sparc__) +#include "IfswDebug.h" +#define SDPRINT SDDEBUGP +#else +#define SDPRINT printf +#endif + + +#endif diff --git a/CompressionEntity/src/SdpCollect.c b/CompressionEntity/src/SdpCollect.c new file mode 100644 index 0000000000000000000000000000000000000000..3e34decdc31cd2f61e90f191b207da77e5d91323 --- /dev/null +++ b/CompressionEntity/src/SdpCollect.c @@ -0,0 +1,409 @@ +/** + * @file SdpCollect.c + * @ingroup SdpCollect + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup SdpCollect Science Data Collect Function + * @ingroup Sdp + * + * @brief A single function which packs the contents of a ComprEntStructure into a bitstream. + * This output bitstream follows strictly the format described in CHEOPS-UVIE-ICD-003 + * + */ + + +#include "SdpCollect.h" +#include "SdpBuffers.h" +#include "SdpAlgorithmsImplementation.h" + +#include "CrIaDataPool.h" +#include "CrIaDataPoolId.h" + +#include <stdio.h> /* for SDPRINT */ + + + +/** + * @brief collect the various contents of a @ref ComprEntStructure and pack them out in a bitstream + * @param cestruct pointer to the @ref ComprEntStructure + * @note The packed output bitstream is in the GibIn (see @ref GIB) + */ + +void SdpCollect (struct ComprEntStructure *cestruct) +{ + unsigned int *cstream = NULL; + unsigned int streampos, i, value; + unsigned int CeSizePos; /* to track where to enter the size at the end */ + + unsigned short gibIn; + + /* get Gib parameters and state of SDB (WIN or FULL) */ + CrIaCopy (GIBIN_ID, &gibIn); + + /* point cstream to gibIn */ + cstream = (unsigned int *)GET_ADDR_FROM_RES_OFFSET(gibIn); + + /* start to copy all components entries into the bitstream */ + streampos = 0; + + /* + -0- pack the CE Header + */ + PUTNBITS (cestruct->Obsid, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->Timetag.coarse, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->Timetag.fine, streampos, 16, cstream); + streampos += 15; /* 1 less to overwrite with sync */ + PUTNBITS (cestruct->Timetag.sync, streampos, 1, cstream); + streampos += 1; + PUTNBITS (cestruct->Counter, streampos, 16, cstream); + streampos += 16; + CeSizePos = streampos; + streampos += 32; /* NOTE: the size is entered at the end! */ + PUTNBITS (cestruct->Version, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->StackingNumber, streampos, 8, cstream); + streampos += 8; + PUTNBITS (cestruct->AcquisitionMode, streampos, 4, cstream); + streampos += 4; + PUTNBITS (cestruct->ReadoutMode, streampos, 4, cstream); + streampos += 4; + PUTNBITS (cestruct->Oversampling, streampos, 4, cstream); + streampos += 4; + PUTNBITS (cestruct->FrameSource, streampos, 2, cstream); + streampos += 2; + PUTNBITS (cestruct->Integrity, streampos, 2, cstream); + streampos += 2; + PUTNBITS (cestruct->RepetitionPeriod, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ExposureTime, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->SemWindowPosX, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->SemWindowPosY, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->SemWindowSizeX, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->SemWindowSizeY, streampos, 16, cstream); + streampos += 16; + + /* PRINTCE(); */ + + SDPRINT(" CeHeader Size: %d bits\n", streampos); + + /* stuff the stream with bits to be %0 */ + PUTNBITS (0, streampos, FILLBYTE(streampos), cstream); + streampos += FILLBYTE(streampos); + + /* + -1- continue with Header Data + */ + if ((cestruct->HeaderData_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->HeaderData_OriginalSize != 0) + { + PUTNBITS (cestruct->HeaderData_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->HeaderData_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->HeaderData_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->HeaderData_Checksum, streampos, 16, cstream); + streampos += 16; + + /* handle CeHeaderData */ + for (i=0; i < cestruct->HeaderData_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprHeaders); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -2- Stacked Image Frame + */ + if ((cestruct->Stacked_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->Stacked_OriginalSize != 0) + { + PUTNBITS (cestruct->Stacked_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->Stacked_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->Stacked_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->Stacked_Checksum, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->Stacked_Datatype, streampos, 8, cstream); + streampos += 8; + PUTNBITS (cestruct->Stacked_Shape, streampos, 8, cstream); + streampos += 8; + PUTNBITS (cestruct->Stacked_SizeX, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->Stacked_SizeY, streampos, 16, cstream); + streampos += 16; + + /* handle Stacked Data */ + for (i=0; i < cestruct->Stacked_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprStacked); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + if (cestruct->AcquisitionMode == ACQ_TYPE_FULL) + { + /* don't wanna make an if clause over the next 260 lines */ + goto exit_collect; + } + + /* + -3- continue with Imagettes + */ + if ((cestruct->Imagettes_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->Imagettes_OriginalSize != 0) + { + PUTNBITS (cestruct->Imagettes_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->Imagettes_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->Imagettes_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->Imagettes_Checksum, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->Imagettes_ApertureShape, streampos, 2, cstream); + streampos += 2; + PUTNBITS (cestruct->Imagettes_CroppingStrategy, streampos, 2, cstream); + streampos += 2; + PUTNBITS (cestruct->Imagettes_StackingOrder, streampos, 4, cstream); + streampos += 4; + PUTNBITS (cestruct->Imagettes_ApertureSizeX, streampos, 8, cstream); + streampos += 8; + PUTNBITS (cestruct->Imagettes_ApertureSizeY, streampos, 8, cstream); + streampos += 8; + + /* handle Imagettes Data */ + for (i=0; i < cestruct->Imagettes_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImagettes); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -4- same for Image Margins LOS + */ + if ((cestruct->ImgMrgLOS_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->ImgMrgLOS_OriginalSize != 0) + { + PUTNBITS (cestruct->ImgMrgLOS_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ImgMrgLOS_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgLOS_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgLOS_Checksum, streampos, 16, cstream); + streampos += 16; + + /* handle LOS Margins Data */ + for (i=0; i < cestruct->ImgMrgLOS_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImgMrgLOS); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -5- same for Image Margins LDK + */ + if ((cestruct->ImgMrgLDK_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->ImgMrgLDK_OriginalSize != 0) + { + PUTNBITS (cestruct->ImgMrgLDK_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ImgMrgLDK_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgLDK_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgLDK_Checksum, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->ImgMrgLDK_ColumnSelectionMask, streampos, 16, cstream); + streampos += 16; + + /* handle LDK Margins Data */ + for (i=0; i < cestruct->ImgMrgLDK_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImgMrgLDK); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -6- same for Image Margins LBLK + */ + if ((cestruct->ImgMrgLBLK_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->ImgMrgLBLK_OriginalSize != 0) + { + PUTNBITS (cestruct->ImgMrgLBLK_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ImgMrgLBLK_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgLBLK_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgLBLK_Checksum, streampos, 16, cstream); + streampos += 16; + + /* handle LBLK Margins Data */ + for (i=0; i < cestruct->ImgMrgLBLK_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImgMrgLBLK); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -7- same for Image Margins RDK + */ + if ((cestruct->ImgMrgRDK_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->ImgMrgRDK_OriginalSize != 0) + { + PUTNBITS (cestruct->ImgMrgRDK_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ImgMrgRDK_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgRDK_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgRDK_Checksum, streampos, 16, cstream); + streampos += 16; + PUTNBITS (cestruct->ImgMrgRDK_ColumnSelectionMask, streampos, 16, cstream); + streampos += 16; + + /* handle RDK Margins Data */ + for (i=0; i < cestruct->ImgMrgRDK_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImgMrgRDK); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -8- same for Image Margins RBLK + */ + if ((cestruct->ImgMrgRBLK_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->ImgMrgRBLK_OriginalSize != 0) + { + PUTNBITS (cestruct->ImgMrgRBLK_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ImgMrgRBLK_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgRBLK_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgRBLK_Checksum, streampos, 16, cstream); + streampos += 16; + + /* handle RBLK Margins Data */ + for (i=0; i < cestruct->ImgMrgRBLK_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImgMrgRBLK); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -9- same for Image Margins TOS + */ + if ((cestruct->ImgMrgTOS_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->ImgMrgTOS_OriginalSize != 0) + { + PUTNBITS (cestruct->ImgMrgTOS_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ImgMrgTOS_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgTOS_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgTOS_Checksum, streampos, 16, cstream); + streampos += 16; + + /* handle TOS Margins Data */ + for (i=0; i < cestruct->ImgMrgTOS_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImgMrgTOS); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + /* + -10- same for Image Margins TDK + */ + if ((cestruct->ImgMrgTDK_CeKey & SDP_PRODUCT) != PRODUCT_DISABLE) + { + if (cestruct->ImgMrgTDK_OriginalSize != 0) + { + PUTNBITS (cestruct->ImgMrgTDK_CeKey, streampos, 32, cstream); + streampos += 32; + PUTNBITS (cestruct->ImgMrgTDK_OriginalSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgTDK_ComprSize, streampos, 24, cstream); + streampos += 24; + PUTNBITS (cestruct->ImgMrgTDK_Checksum, streampos, 16, cstream); + streampos += 16; + + /* handle TDK Margins Data */ + for (i=0; i < cestruct->ImgMrgTDK_ComprSize; i++) + { + GETBYTE (value, i*8, cestruct->ComprImgMrgTDK); + PUTBYTE (value, streampos, cstream); + streampos += 8; + } + } + } + + exit_collect : + + /* finally enter the size */ + cestruct->Size = streampos / 8; + PUTNBITS (cestruct->Size, CeSizePos, 32, cstream); + + /* NOTE: the GIB is incremented in the caller */ + + return; +} + diff --git a/CompressionEntity/src/SdpCollect.h b/CompressionEntity/src/SdpCollect.h new file mode 100644 index 0000000000000000000000000000000000000000..481b78482a4f55cc5239085267996ea4fb906a5c --- /dev/null +++ b/CompressionEntity/src/SdpCollect.h @@ -0,0 +1,9 @@ +#ifndef SDPCOLLECT_H +#define SDPCOLLECT_H + +#include "SdpCompressionEntityStructure.h" + +void SdpCollect (struct ComprEntStructure *cestruct); + + +#endif diff --git a/CompressionEntity/src/SdpCompress.c b/CompressionEntity/src/SdpCompress.c new file mode 100644 index 0000000000000000000000000000000000000000..62adecdc51905c82608b47fb4c4e21faf568b29a --- /dev/null +++ b/CompressionEntity/src/SdpCompress.c @@ -0,0 +1,825 @@ +/** +* @file SdpCompress.c +* @ingroup SdpCompress +* @author Roland Ottensamer (roland.ottensamer@univie.ac.at) +* @date August, 2016 +* +* @copyright +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* +* @defgroup SdpCompress Science Data Processing Chain +* @ingroup Sdp +* +* @brief Top-level compression function, sets up buffers and executes @ref Compress for each product to be added to the @ref CompressionEntity +* +* +* ## Overview +* +* Once the @ref ComprEntStructure has been initialized (@ref InitComprEntStructureFromDataPool), we are good to go for the +* compression of the up to 10 products. The @ref SdpCompress function first sets up the buffers in the @ref ComprEntStructure +* using @ref SetupCeBuffers, then calls a "Compress..." function for each product, for instance @ref CompressHeaders. +* That function will make dedicated preparations for that particular product, then call @ref Compress. +* +* The @ref Compression section has the details how the @ref Compress function works. +* +* ### The ten products +* +* For each product it is the same procedure: call Compress... +* In principle the order in which these are called does not matter, with a few exceptions: +* - the @ref CompressStacked should be executed before @ref CompressHeaders if on-board quick photometry +* is desired (options @ref PREPROC_PHOT, @ref PREPROC_NLCPHOT in the @ref SdpWinImageCeKey). +* The reason is that the photometry is carried out by that preprocessing step and entered in the @ref CrIaSib, from +* where the @ref CompressHeaders functions gathers its input. +* - To be extra safe, execute the order in the same order in which the compressed buffers are arranged by the +* @ref SetupCeBuffers. In this case, a buffer overrun (which should of course not happen) does not corrupt any +* previously prepared output data. @ref SetupCeBuffers arranges buffers such that the maximum product size is reserved +* for that segment, but we could theoretically squeeze them to the predicted output size to gain some more memory. +* It is not recommended, though. +* +* ### The preparations for the ten products +* +* Here, we take a look at the particular preparations that are done by the 10 Compress... functions. +* Their purpose is to set the dimensions of the dataset and to prepare the input and output buffers, the processing buffer, +* the auxiliary buffer in a memory-saving way, knowing that the @ref Compress function will use them in a @ref ping-pong way. +* The detailed description here is necessary, because some of the ways how we minimize memory usage need to be explained. +* +* @ref CompressHeaders +* The flow in this function is the following: +* - set the input buffer (source->data) to be the the ComprHeaders buffer from the ComprEntStructure +* - set source dimensions to the actual SEM window size +* This is needed because the headers are fetched from the SIB using @ref SibToFlatHeaders and the +* SIB structure therein is given by the window size. +* The source dimensions will be overwritten by the PRODUCT_HEADERS step in @ref Compress. +* - prepare a swap buffer using @ref PrepareSwap +* - check if the @ref ProcBuf has sufficient space left +* - set the output buffer to the @ref ProcBuf +* - call @ref Compress function stating that the result should be returned in the source (here it was the ComprHeaders) +* - enter the returned @ref CompressedBuf parameters relevant for that product in the @ref ComprEntStructure +* +* @ref CompressStacked +* The flow of the stacked frame is the same as above, only the ComprStacked buffer is used as source +* and we have more output parameters. +* +* @ref CompressStacked +* The flow of the imagettes is the same as for the headers, only the ComprImagettes buffer is used as source +* +* @ref CompressImgMrgLOS +* The flow of the stacked frame is the same as for the headers, with the following deviations: +* - the ComprImgMrgLOS buffer is used as source +* - the X dimension used for the source is @ref LSM_XDIM, because the LSM segment contains the LOS in the @ref SIB +* +* @ref CompressImgMrgLOS +* Likewise +* +* @ref CompressImgMrgLDK +* Likewise +* +* @ref CompressImgMrgLBLK +* Likewise +* +* @ref CompressImgMrgRBLK +* Likewise, with @ref RSM_XDIM +* +* @ref CompressImgMrgRDK +* Likewise +* +* @ref CompressImgMrgTDK +* Likewise, with TM_YDIM for the second axis +* +* @ref CompressImgMrgTOS +* Likewise +* +* +* ### Errors and Reporting +* +* The science data processing can report a number of fatal errors. In each case the data processing is severely compromised +* and it does not make sense to continue. The main cause is a mismatch between the configured SIB/CIB/GIB buffers and the +* actual data structures that are created by the compression. The following events are used: +* +* - EVT_IMG_INSUF, with parameter: 32 bit requested size for SIB structure. It is raised by @ref SetupSibWin to report that +* the SIB size does not allow to configure a SIB structure matching PWINSIZEX and PWINSIZEY. This event will already be seen +* during the incoming image buffering. +* +* - EVT_CMPR_SIZE, with parameter: 32 bit requested size for compressed data structure. This one is raised by @ref SetupCeBuffers +* to report that the CIB is too small for allocating the compressed data structure. +* +* - EVT_PROCBUF_INSUF, with parameter: 16 bit product ID. This error is reported by the @ref CompressStacked, @ref CompressImagettes, +* etc. functions to report that the CIB is too small to allocate sufficient space for the processing buffer from what is left after +* @ref SetupCeBuffers has made its reservations. +* +* - EVT_SDP_NOMEM, with parameter: 16 bit step ID. It is raised by the @ref Compress function to report that the swap buffer is too +* small to allocate memory for the lossless compression. +* +* - EVT_CLCT_SIZE, with parameter: 16 bit requested GIB size in kiB. This event is raised by the @ref Collect function to report that +* the compression entity is too big for the configured GIB. +* +* @todo the size of the aux buffer is presently fixed to a large size. Needs to be smaller! +*/ + + +#include "SdpCompress.h" +#include "SdpBuffers.h" +#include "SdpAlgorithmsImplementation.h" +#include "SdpCompressionEntityStructure.h" + +#include "CrIaDataPool.h" +#include "CrIaDataPoolId.h" +#ifndef ISOLATED +#include "Services/General/CrIaConstants.h" +#include "CrIaIasw.h" +#endif + +#include <stdio.h> /* for SDPRINT */ + + +#define ANSI_COLOR_CYAN "\x1b[36m" +#define ANSI_COLOR_RESET "\x1b[0m" + + +int CompressHeaders (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + + int status = 0; + + prodId = CC_HEADERS; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + /* NOTE: the product step which fetches the headers from SIB needs Sem Window size and stacking order to deal with the sib */ + source.datatype = DATATYPE_UINT32; + source.xelements = cestruct->SemWindowSizeX; /* yes we want the image size! */ + source.yelements = cestruct->SemWindowSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprHeaders; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = FLAT_HEADER_VALUES * TYPESIZE(DATATYPE_UINT32) * cestruct->StackingNumber; + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes for HEADER from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare processing buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress (&source, cestruct, cestruct->HeaderData_CeKey, &compressed, SRCBUF, &swap); + + cestruct->HeaderData_OriginalSize = outsize; + cestruct->HeaderData_Checksum = (unsigned short) compressed.lossyCrc; + cestruct->HeaderData_ComprSize = compressed.llcsize; + + return status; +} + +int CompressStacked (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_STACKED; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = cestruct->SemWindowSizeX; + source.yelements = cestruct->SemWindowSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprStacked; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes for STACKED from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare processing buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress (&source, cestruct, cestruct->Stacked_CeKey, &compressed, SRCBUF, &swap); + + if ((cestruct->Stacked_CeKey & SDP_LOSSY2) != LOSSY2_CIRCEXTRACT) + { + cestruct->Stacked_SizeX = compressed.xelements; + cestruct->Stacked_SizeY = compressed.yelements; + } + else + { + /* for the CIRCEXTRACT option, remember the original window size */ + cestruct->Stacked_SizeX = cestruct->SemWindowSizeX; + cestruct->Stacked_SizeY = cestruct->SemWindowSizeY; + } + + cestruct->Stacked_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->Stacked_Checksum = (unsigned short) compressed.lossyCrc; + cestruct->Stacked_ComprSize = compressed.llcsize; + cestruct->Stacked_Datatype = compressed.datatype; + + return status; +} + + +int CompressImagettes (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_IMAGETTES; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = cestruct->Imagettes_ApertureSizeX; + source.yelements = cestruct->Imagettes_ApertureSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImagettes; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare processing buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + SDPRINT(" Handing over uncompressed Imagettes: Size = %d B\n", outsize); + + status = Compress(&source, cestruct, cestruct->Imagettes_CeKey, &compressed, SRCBUF, &swap); + + cestruct->Imagettes_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->Imagettes_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->Imagettes_Checksum = compressed.lossyCrc; + + return status; +} + +int CompressImgMrgLOS (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_MRGLOS; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = LSM_XDIM; + source.yelements = cestruct->SemWindowSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImgMrgLOS; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare dest buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress(&source, cestruct, cestruct->ImgMrgLOS_CeKey, &compressed, SRCBUF, &swap); + + cestruct->ImgMrgLOS_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->ImgMrgLOS_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->ImgMrgLOS_Checksum = compressed.lossyCrc; + + return status; +} + +int CompressImgMrgLDK (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_MRGLDK; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = LSM_XDIM; + source.yelements = cestruct->SemWindowSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImgMrgLDK; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare dest buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress(&source, cestruct, cestruct->ImgMrgLDK_CeKey, &compressed, SRCBUF, &swap); + + cestruct->ImgMrgLDK_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->ImgMrgLDK_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->ImgMrgLDK_Checksum = compressed.lossyCrc; + + return status; +} + +int CompressImgMrgLBLK (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_MRGLBLK; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = LSM_XDIM; + source.yelements = cestruct->SemWindowSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImgMrgLBLK; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare dest buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress(&source, cestruct, cestruct->ImgMrgLBLK_CeKey, &compressed, SRCBUF, &swap); + + cestruct->ImgMrgLBLK_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->ImgMrgLBLK_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->ImgMrgLBLK_Checksum = compressed.lossyCrc; + + return status; +} + + +int CompressImgMrgRBLK (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_MRGRBLK; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = RSM_XDIM; + source.yelements = cestruct->SemWindowSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImgMrgRBLK; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare dest buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress(&source, cestruct, cestruct->ImgMrgRBLK_CeKey, &compressed, SRCBUF, &swap); + + cestruct->ImgMrgRBLK_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->ImgMrgRBLK_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->ImgMrgRBLK_Checksum = compressed.lossyCrc; + + return status; +} + + +int CompressImgMrgRDK (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_MRGRDK; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = RSM_XDIM; + source.yelements = cestruct->SemWindowSizeY; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImgMrgRDK; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare dest buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress(&source, cestruct, cestruct->ImgMrgRDK_CeKey, &compressed, SRCBUF, &swap); + + cestruct->ImgMrgRDK_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->ImgMrgRDK_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->ImgMrgRDK_Checksum = compressed.lossyCrc; + + return status; +} + + +int CompressImgMrgTDK (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_MRGTDK; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = cestruct->SemWindowSizeX; + source.yelements = TM_YDIM; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImgMrgTDK; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare dest buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress(&source, cestruct, cestruct->ImgMrgTDK_CeKey, &compressed, SRCBUF, &swap); + + cestruct->ImgMrgTDK_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->ImgMrgTDK_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->ImgMrgTDK_Checksum = compressed.lossyCrc; + + return status; +} + + +int CompressImgMrgTOS (struct ComprEntStructure *cestruct) +{ + unsigned int outsize; + struct ScienceBuf source, swap; + struct CompressedBuf compressed; + unsigned short prodId; + unsigned short evt_data[2]; + int status = 0; + + prodId = CC_MRGTOS; + CrIaPaste(CCPRODUCT_ID, &prodId); + + /* prepare source buffer */ + source.datatype = DATATYPE_UINT32; + source.xelements = cestruct->SemWindowSizeX; + source.yelements = TM_YDIM; + source.zelements = cestruct->StackingNumber; + source.nelements = source.xelements * source.yelements * source.zelements; + source.data = (void *) cestruct->ComprImgMrgTOS; + + /* prepare swap buffer */ + PrepareSwap (&swap, cestruct); + + /* check size of processing buffer */ + outsize = source.nelements * TYPESIZE(source.datatype); + if (outsize > cestruct->ProcBufBufferSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: could not allocate %u bytes from PROCBUF with %u bytes left!\n", outsize, cestruct->ProcBufBufferSize); +#else + evt_data[0] = prodId; /* product ID */ + evt_data[1] = 0; + + SdpEvtRaise(3, CRIA_SERV5_EVT_PROCBUF_INSUF, evt_data, 4); +#endif + return 0; + } + + /* prepare dest buffer */ + compressed.data = (void *) cestruct->ProcBuf; + + status = Compress(&source, cestruct, cestruct->ImgMrgTOS_CeKey, &compressed, SRCBUF, &swap); + + cestruct->ImgMrgTOS_OriginalSize = compressed.nelements * TYPESIZE(compressed.datatype); + cestruct->ImgMrgTOS_ComprSize = compressed.llcsize; /* is in bytes */ + cestruct->ImgMrgTOS_Checksum = compressed.lossyCrc; + + return status; +} + + +void SdpCompress (struct ComprEntStructure *cestruct) +{ + unsigned short cib, sdbstate; + unsigned int cemode = CEMODE_WIN; + + /* setup CIB */ + CrIaCopy(CIBIN_ID, &cib); + CrIaCopy(SDBSTATE_ID, &sdbstate); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + cemode = CEMODE_FULL; + + SetupCeBuffers (cestruct, cib, cestruct->SemWindowSizeX, cestruct->SemWindowSizeY, cestruct->StackingNumber, cemode); + + SDPRINT("buffer sizes: SWAP %d; CIB %d\n", cestruct->SwapBufBufferSize, cestruct->CibSize); + SDPRINT("1st ping-pong buffer: USED = %d. rest goes to PROC\n", cestruct->UsedBufferSize); + + /* use the remaining CIB size for the ProcBuf */ + ProcBufBorgMode (cestruct); + + /* + Stack and Compress Image Frame + */ + + SDPRINT(ANSI_COLOR_CYAN "Stacked Frame\n" ANSI_COLOR_RESET); + + CompressStacked (cestruct); + + + /* + Compressed Header Data + NOTE: The Image Frame should be compressed before the Headers to have + the three SibPhotometry values initialized! + */ + SDPRINT(ANSI_COLOR_CYAN "Header Data\n" ANSI_COLOR_RESET); + + CompressHeaders (cestruct); + SDPRINT(" Headers have been compressed to %d bytes, CRC=%04x\n\n", cestruct->HeaderData_ComprSize, cestruct->HeaderData_Checksum); + + + /* + Imagettes + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "Imagettes\n" ANSI_COLOR_RESET); + + CompressImagettes (cestruct); + SDPRINT(" Imagettes have been compressed to %ld bytes\n\n", (unsigned long int)cestruct->Imagettes_ComprSize); + } + + /* + Image Margins: LOS + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "ImgMrgLOS\n" ANSI_COLOR_RESET); + + CompressImgMrgLOS (cestruct); + SDPRINT(" LOS has been compressed to %d bytes\n\n", cestruct->ImgMrgLOS_ComprSize); + + /* SDPRINT("LOS are: %f .. %f .. %08x\n", ((float *)cestruct->ComprImgMrgLOS)[0], ((float *)cestruct->ComprImgMrgLOS)[21], cestruct->ComprImgMrgLOS[23]); */ + } + + /* + Image Margins: LDK + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "ImgMrgLDK\n" ANSI_COLOR_RESET); + CompressImgMrgLDK (cestruct); + SDPRINT(" LDK has been compressed to %d bytes\n\n", cestruct->ImgMrgLDK_ComprSize); + + /* SDPRINT("LDK are: %f .. %f .. %08x\n", ((float *)cestruct->ComprImgMrgLDK)[0], ((float *)cestruct->ComprImgMrgLDK)[21], cestruct->ComprImgMrgLDK[23]); */ + } + + /* + Image Margins: LBLK + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "ImgMrgLBLK\n" ANSI_COLOR_RESET); + CompressImgMrgLBLK (cestruct); + SDPRINT(" LBLK has been compressed to %d bytes\n\n", cestruct->ImgMrgLBLK_ComprSize); + + /* SDPRINT("LBLK are: %f .. %f .. %08x\n", ((float *)cestruct->ComprImgMrgLBLK)[0], ((float *)cestruct->ComprImgMrgLBLK)[21], cestruct->ComprImgMrgLBLK[23]); */ + } + + /* + Image Margins: RBLK + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "ImgMrgRBLK\n" ANSI_COLOR_RESET); + CompressImgMrgRBLK (cestruct); + SDPRINT(" RBLK has been compressed to %d bytes\n\n", cestruct->ImgMrgRBLK_ComprSize); + + /* SDPRINT("RBLK are: %f .. %f .. %08x\n", ((float *)cestruct->ComprImgMrgRBLK)[0], ((float *)cestruct->ComprImgMrgRBLK)[21], cestruct->ComprImgMrgRBLK[23]); */ + } + + /* + Image Margins: RDK + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "ImgMrgRDK\n" ANSI_COLOR_RESET); + CompressImgMrgRDK (cestruct); + SDPRINT(" RDK has been compressed to %d bytes\n\n", cestruct->ImgMrgRDK_ComprSize); + + /* SDPRINT("RDK are: %f .. %f .. %08x\n", ((float *)cestruct->ComprImgMrgRDK)[0], ((float *)cestruct->ComprImgMrgRDK)[21], cestruct->ComprImgMrgRDK[23]); */ + } + + /* + Image Margins: TOS + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "ImgMrgTOS\n" ANSI_COLOR_RESET); + CompressImgMrgTOS (cestruct); + SDPRINT(" TOS has been compressed to %d bytes\n\n", cestruct->ImgMrgTOS_ComprSize); + + /* SDPRINT("TOS are: %f .. %f .. %08x\n", ((float *)cestruct->ComprImgMrgTOS)[0], ((float *)cestruct->ComprImgMrgTOS)[21], cestruct->ComprImgMrgTOS[23]); */ + } + + /* + Image Margins: TDK + */ + + if (sdbstate != CrIaSdb_CONFIG_FULL) + { + SDPRINT(ANSI_COLOR_CYAN "ImgMrgTDK\n" ANSI_COLOR_RESET); + CompressImgMrgTDK (cestruct); + SDPRINT(" TDK has been compressed to %d bytes\n\n", cestruct->ImgMrgTDK_ComprSize); + + /* SDPRINT("TDK are: %f .. %f .. %08x\n", ((float *)cestruct->ComprImgMrgTDK)[0], ((float *)cestruct->ComprImgMrgTDK)[21], cestruct->ComprImgMrgTDK[23]); */ + } + + return; +} diff --git a/CompressionEntity/src/SdpCompress.h b/CompressionEntity/src/SdpCompress.h new file mode 100644 index 0000000000000000000000000000000000000000..2c49e349e7873b43f9447d269a871cf4285c742d --- /dev/null +++ b/CompressionEntity/src/SdpCompress.h @@ -0,0 +1,30 @@ +#ifndef SDPCOMPRESS_H +#define SDPCOMPRESS_H + +#include "SdpCompressionEntityStructure.h" + + +int CompressHeaders (struct ComprEntStructure *cestruct); + +int CompressStacked (struct ComprEntStructure *cestruct); + +int CompressImagettes (struct ComprEntStructure *cestruct); + +int CompressImgMrgLOS (struct ComprEntStructure *cestruct); + +int CompressImgMrgLDK (struct ComprEntStructure *cestruct); + +int CompressImgMrgLBLK (struct ComprEntStructure *cestruct); + +int CompressImgMrgRBLK (struct ComprEntStructure *cestruct); + +int CompressImgMrgRDK (struct ComprEntStructure *cestruct); + +int CompressImgMrgTDK (struct ComprEntStructure *cestruct); + +int CompressImgMrgTOS (struct ComprEntStructure *cestruct); + +void SdpCompress (struct ComprEntStructure *cestruct); + + +#endif diff --git a/CompressionEntity/src/SdpCompressionEntityStructure.h b/CompressionEntity/src/SdpCompressionEntityStructure.h new file mode 100644 index 0000000000000000000000000000000000000000..979983670aa63b2b236de2ab6ceb0d7d7c2eff94 --- /dev/null +++ b/CompressionEntity/src/SdpCompressionEntityStructure.h @@ -0,0 +1,249 @@ +/** + * @file SdpCompressionEntityStructure.h + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup CompressionEntity Compression Entity Structure + * @ingroup Sdp + * + * @brief this structure is a key component of the of the science data processing chain + * + * The term __Compression Entity__ is used in the following two ways: + * A Compression Entity (bitstream) is quasi the zip-File of the science data processing chain. + * A Compression Entity Structure (@ref ComprEntStructure) is the construct holding the various components and parameters in memory. + * Think of the Compression Entity being the serialization of the Compression Entity Structure. + * This serialization process is carried out by the @ref SdpCollect function. The equivalent + * on ground is the Decompose function in the CompressionEntity class. + * + * A @ref ComprEntStructure has a header with the most important parameters describing the contained science data. + * It starts with the Observation ID (@ref OBSID), equivalently called "visit ID" by some. The Compression Entity + * is supposed to hold up to 10 products (imagettes, 7 margin areas, the frame, headers). Also for these we have + * the most important parameters which are needed to de-compress and interpret the data. + * The structure then contains a number of pointers to buffers. The structure itself should be initialized with + * the @ref InitComprEntStructureFromDataPool function, before the @ref SdpCompress function can be executed. That will set up + * the buffers using the @ref SetupCeBuffers + * function in the @ref SDB, more precisely, in the @ref CIB. For each product, we have a pointer to the uncompressed data + * and one to the compressed data. In addition, a pointer to the @ref ProcBuf and one to an auxiliary buffer (@ref SwapBuf) is included. + * They are used by the @ref SdpCompress function. Navigate there, if you are interested in how they are used precisely. + */ + +#ifndef SDP_COMPRESSION_ENTITY_STRUCTURE_H +#define SDP_COMPRESSION_ENTITY_STRUCTURE_H + +#include "SdpCeDefinitions.h" + + +/* Offset in bits within a CE where the integrity flags (e.g. Science Data Suspend (SDS)) are located */ +#define STREAMPOS_INTEGRITY 166 + + +/** + * \struct ComprEntStructure + * @brief Compression Entity structure for IFSW and GS + * @note see CHEOPS-UVIE-ICD-003 Tables 3-7 + */ + +struct ComprEntStructure { + + /*** CE Header Parameters */ + unsigned int Obsid; /**< Observation ID */ + struct cuctime Timetag; /**< CUC time of CE [CE datatype is 48 bits] */ + unsigned short Counter; /**< CE counter */ + unsigned int Size; /**< size in B of the CE including CE headers */ + unsigned short Version; /**< IFSW build number / SW version */ + unsigned char StackingNumber; /**< nr of raw frames per stacked frame */ + unsigned char AcquisitionMode; /**< SEM CCD mode (eg. full frame) [CE datatype is 4 bits] */ + unsigned char ReadoutMode; /**< SEM readout mode (eg. faint) [CE datatype is 4 bits] */ + unsigned char Oversampling; /**< SEM data oversampling [CE datatype is 4 bits] */ + unsigned char FrameSource; /**< SEM data acquisition source [CE datatype is 2 bits] */ + unsigned char Integrity; /**< CE integrity [CE datatype is 2 bits] */ + unsigned int RepetitionPeriod; /**< inverse of frame rate in ms. this has changed to int */ + unsigned int ExposureTime; /**< exposure time in ms */ + unsigned short SemWindowPosX; /**< Window bottom left coordinate, it counts pixels the very bottom left pixel is in the overscan margin area */ + unsigned short SemWindowPosY; + unsigned short SemWindowSizeX; + unsigned short SemWindowSizeY; + unsigned int Target_LocationX; /**< intended target location as taken from the @ref StarMap command */ + unsigned int Target_LocationY; + /**@*/ + + + /*** Compressed Header Data ***/ + unsigned int HeaderData_CeKey; /**< MSB = ProductId, 3 LSB = compression mode */ + unsigned int HeaderData_OriginalSize; /**< uncompressed size in B */ + unsigned int HeaderData_ComprSize; /**< compressed size in B */ + unsigned short HeaderData_Checksum; + + unsigned int *Base; /**< will point to the base of the @ref CIB */ + unsigned int *FlatHeaders; /**< "raw" headers going into the CompressHeaders function */ + unsigned int *ComprHeaders; /**< container for binary blob */ + struct Meterology *CeHeaderData; /**< uncompressed headers for your convenience. Has @ref StackingNumber dimension. */ + + /*** Stacked Frame (or single raw frame) ***/ + unsigned int Stacked_CeKey; + unsigned int Stacked_OriginalSize; + unsigned int Stacked_ComprSize; + unsigned short Stacked_Checksum; + unsigned char Stacked_Datatype; + unsigned char Stacked_Shape; + unsigned short Stacked_SizeX; /**< @note also diameter of circular shape */ + unsigned short Stacked_SizeY; + + unsigned int *Stacked; + unsigned int *ComprStacked; /**< container for binary blob */ + + + /*** Imagettes ***/ + unsigned int Imagettes_CeKey; + unsigned int Imagettes_OriginalSize; + unsigned int Imagettes_ComprSize; + unsigned short Imagettes_Checksum; + unsigned char Imagettes_ApertureShape; + unsigned char Imagettes_CroppingStrategy; + unsigned char Imagettes_ApertureSizeX; + unsigned char Imagettes_ApertureSizeY; + unsigned char Imagettes_StackingOrder; + + unsigned int *Imagettes; /**< uncompressed imagettes */ + unsigned int *ComprImagettes; /**< container for binary blob */ + + + /*** Image Margins ***/ + /* LOS */ + unsigned int ImgMrgLOS_CeKey; + unsigned int ImgMrgLOS_OriginalSize; + unsigned int ImgMrgLOS_ComprSize; + unsigned short ImgMrgLOS_Checksum; + + unsigned int *ImgMrgLOS; /**< uncompressed margin */ + unsigned int *ComprImgMrgLOS; /**< container for binary blob */ + + /* LDK */ + unsigned int ImgMrgLDK_CeKey; + unsigned int ImgMrgLDK_OriginalSize; + unsigned int ImgMrgLDK_ComprSize; + unsigned short ImgMrgLDK_Checksum; + unsigned short ImgMrgLDK_ColumnSelectionMask; + + unsigned int *ImgMrgLDK; /**< uncompressed margin */ + unsigned int *ComprImgMrgLDK; /**< container for binary blob */ + + /* LBLK */ + unsigned int ImgMrgLBLK_CeKey; + unsigned int ImgMrgLBLK_OriginalSize; + unsigned int ImgMrgLBLK_ComprSize; + unsigned short ImgMrgLBLK_Checksum; + + unsigned int *ImgMrgLBLK; /**< uncompressed margin */ + unsigned int *ComprImgMrgLBLK; /**< container for binary blob */ + + /* RBLK */ + unsigned int ImgMrgRBLK_CeKey; + unsigned int ImgMrgRBLK_OriginalSize; + unsigned int ImgMrgRBLK_ComprSize; + unsigned short ImgMrgRBLK_Checksum; + + unsigned int *ImgMrgRBLK; /**< uncompressed margin */ + unsigned int *ComprImgMrgRBLK; /**< container for binary blob */ + + /* RDK */ + unsigned int ImgMrgRDK_CeKey; + unsigned int ImgMrgRDK_OriginalSize; + unsigned int ImgMrgRDK_ComprSize; + unsigned short ImgMrgRDK_Checksum; + unsigned short ImgMrgRDK_ColumnSelectionMask; + + unsigned int *ImgMrgRDK; /**< uncompressed margin */ + unsigned int *ComprImgMrgRDK; /**< container for binary blob */ + + /* TOS */ + unsigned int ImgMrgTOS_CeKey; + unsigned int ImgMrgTOS_OriginalSize; + unsigned int ImgMrgTOS_ComprSize; + unsigned short ImgMrgTOS_Checksum; + + unsigned int *ImgMrgTOS; /**< uncompressed margin */ + unsigned int *ComprImgMrgTOS; /**< container for binary blob */ + + /* TDK */ + unsigned int ImgMrgTDK_CeKey; + unsigned int ImgMrgTDK_OriginalSize; + unsigned int ImgMrgTDK_ComprSize; + unsigned short ImgMrgTDK_Checksum; + + unsigned int *ImgMrgTDK; /**< uncompressed margin */ + unsigned int *ComprImgMrgTDK; /**< container for binary blob */ + + /* additional Buffers and buffer size */ + unsigned int *ProcBuf; /**< the processing buffer needs to be at least as large as the largest raw input product */ + unsigned int *SwapBuf; /**< the SwapBuf is needed for arithmetic compression (see @ref fmari_compress) */ + unsigned int FlatHeadersBufferSize; + unsigned int StackedBufferSize; + unsigned int ImagettesBufferSize; + unsigned int ImgMrgLOSBufferSize; + unsigned int ImgMrgLDKBufferSize; + unsigned int ImgMrgLBLKBufferSize; + unsigned int ImgMrgRBLKBufferSize; + unsigned int ImgMrgRDKBufferSize; + unsigned int ImgMrgTOSBufferSize; + unsigned int ImgMrgTDKBufferSize; + unsigned int ComprHeadersBufferSize; + unsigned int ComprImagettesBufferSize; + unsigned int ComprStackedBufferSize; + unsigned int ComprImgMrgLOSBufferSize; + unsigned int ComprImgMrgLDKBufferSize; + unsigned int ComprImgMrgLBLKBufferSize; + unsigned int ComprImgMrgRBLKBufferSize; + unsigned int ComprImgMrgRDKBufferSize; + unsigned int ComprImgMrgTOSBufferSize; + unsigned int ComprImgMrgTDKBufferSize; + unsigned int ProcBufBufferSize; + unsigned int SwapBufBufferSize; + unsigned int UsedBufferSize; + unsigned int CibSize; + +#ifdef GROUNDSW + unsigned int ImgMrgLOS_Xdim; /**< dimension caclulated during decompression */ + unsigned int ImgMrgLOS_Ydim; + unsigned int ImgMrgLOS_Zdim; + + unsigned int ImgMrgLDK_Xdim; + unsigned int ImgMrgLDK_Ydim; + unsigned int ImgMrgLDK_Zdim; + + unsigned int ImgMrgLBLK_Xdim; + unsigned int ImgMrgLBLK_Ydim; + unsigned int ImgMrgLBLK_Zdim; + + unsigned int ImgMrgRBLK_Xdim; + unsigned int ImgMrgRBLK_Ydim; + unsigned int ImgMrgRBLK_Zdim; + + unsigned int ImgMrgRDK_Xdim; + unsigned int ImgMrgRDK_Ydim; + unsigned int ImgMrgRDK_Zdim; + + unsigned int ImgMrgTOS_Xdim; + unsigned int ImgMrgTOS_Ydim; + unsigned int ImgMrgTOS_Zdim; + + unsigned int ImgMrgTDK_Xdim; + unsigned int ImgMrgTDK_Ydim; + unsigned int ImgMrgTDK_Zdim; + + unsigned short overrideCRC; +#endif + +}; + +#endif diff --git a/CompressionEntity/src/SdpNlcPhot.c b/CompressionEntity/src/SdpNlcPhot.c new file mode 100644 index 0000000000000000000000000000000000000000..1b1850eb58242a51cea458dd376ad57d33698b3d --- /dev/null +++ b/CompressionEntity/src/SdpNlcPhot.c @@ -0,0 +1,885 @@ +/** + * @file SdpNlcPhot.c + * @ingroup SdpNlcPhot + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date March, 2017 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup SdpNlcPhot Linearization and Quick Photometry + * @ingroup Sdp + * + * @brief Contains the nonlinearity correction function @ref NlcSplineCorr28 and the quick photometry function @ref QuickPhotometry which can be + * used in the preprocessing step of the @ref Compress function. + * + */ + + +#include "SdpNlcPhot.h" +#include "SdpAlgorithmsImplementation.h" /* for Median, CircExtract32 */ +#include "SdpBuffers.h" /* for struct ScienceBuf and SibPhotometry */ + +#include "IfswMath.h" + +#include "CrIaDataPool.h" +#include "CrIaDataPoolId.h" + +#include <stdio.h> /* for SDPRINT */ + + +#define SPLINE_SEGMENTS 28 +#define GAIN_PARAMS SPLINE_SEGMENTS +#define NLC2_SEGMENTS 16 + +/* NOTE: these global arrays are sized after the old NLC */ +unsigned int rborder[SPLINE_SEGMENTS]; /* right borders of spline segment intervals */ +double A[SPLINE_SEGMENTS]; /* 0th order coefficients for nlcSplineCorr28 */ +double B[SPLINE_SEGMENTS]; /* 1st order coefficients for nlcSplineCorr28 */ +double C[SPLINE_SEGMENTS]; /* 2nd order coefficients for nlcSplineCorr28 */ +double D[SPLINE_SEGMENTS]; /* 3rd order coefficients for nlcSplineCorr28 */ + + +/** + * @brief Function used by @ref NlcSplineCorr28. It returns the index of the right (=upper) border of the interval that the + * given number belongs to. This function is designed to handle exactly 28 intervals. + * @param value the value which is sought within the intervals given by rborder + * @param rb an array of right (=upper) borders + * @note the right border is assumed to belong to the interval + * @note this is implemented as a bisection to be as fast as possible + * + * @returns the index of the interval to which the input value belongs + */ + +int GetInterval28 (unsigned int value, unsigned int *rb) +{ + int r=0; + + if (value <= rb[13]) + { + /* 0..13 */ + if (value <= rb[6]) + { + /* 0..6 */ + if (value <= rb[3]) + { + /* 0..3 */ + if (value <= rb[1]) + { + /* 0..1 */ + if (value <= rb[0]) + { + /* 0 */ + r = 0; + } + else + { + /* 1 */ + r = 1; + } + } + else + { + /* 2..3 */ + if (value <= rb[2]) + { + /* 2 */ + r = 2; + } + else + { + /* 3 */ + r = 3; + } + } + } + else + { + /* 4..6 */ + if (value <= rb[5]) + { + /* 4..5 */ + if (value <= rb[4]) + { + /* 4 */ + r = 4; + } + else + { + /* 5 */ + r = 5; + } + } + else + { + /* 6 */ + r = 6; + } + } + } + else + { + /* 7..13 */ + if (value <= rb[10]) + { + /* 7..10 */ + if (value <= rb[8]) + { + /* 7..8 */ + if (value <= rb[7]) + { + /* 7 */ + r = 7; + } + else + { + /* 8 */ + r = 8; + } + } + else + { + /* 9..10 */ + if (value <= rb[9]) + { + /* 9 */ + r = 9; + } + else + { + /* 10 */ + r = 10; + } + } + } + else + { + /* 11..13 */ + if (value <= rb[12]) + { + /* 11..12 */ + if (value <= rb[11]) + { + /* 11 */ + r = 11; + } + else + { + /* 12 */ + r = 12; + } + } + else + { + /* 13 */ + r = 13; + } + } + } + } + else + { + /* 14..27 */ + if (value <= rb[20]) + { + /* 14..20 */ + if (value <= rb[17]) + { + /* 14..17 */ + if (value <= rb[15]) + { + /* 14..15 */ + if (value <= rb[14]) + { + /* 14 */ + r = 14; + } + else + { + /* 15 */ + r = 15; + } + } + else + { + /* 16..17 */ + if (value <= rb[16]) + { + /* 16 */ + r = 16; + } + else + { + /* 17 */ + r = 17; + } + } + } + else + { + /* 18..20 */ + if (value <= rb[20]) + { + /* 18..19 */ + if (value <= rb[18]) + { + /* 18 */ + r = 18; + } + else + { + /* 19 */ + r = 19; + } + } + else + { + /* 20 */ + r = 20; + } + } + } + else + { + /* 21..27 */ + if (value <= rb[24]) + { + /* 21..24 */ + if (value <= rb[22]) + { + /* 21..22 */ + if (value <= rb[21]) + { + /* 21 */ + r = 21; + } + else + { + /* 22 */ + r = 22; + } + } + else + { + /* .. */ + if (value <= rb[23]) + { + /* 23 */ + r = 23; + } + else + { + /* 24 */ + r = 24; + } + } + } + else + { + /* 25..27 */ + if (value <= rb[26]) + { + /* 25..26 */ + if (value <= rb[25]) + { + /* 25 */ + r = 25; + } + else + { + /* 26 */ + r = 26; + } + } + else + { + /* 27 */ + r = 27; + } + } + } + } + + return r; +} + + +/** + * @brief Function used by @ref NlcSplineCorr16. It returns the index of the right (=upper) border of the interval that the + * given number belongs to. This function is designed to handle exactly 16 intervals. + * When there are less, coefficients should be adapted accordingly. + * @param value the value which is sought within the intervals given by rborder + * @param rb an array of right (=upper) borders + * @note the right border is assumed to belong to the interval + * @note this is implemented as a bisection to be as fast as possible + * + * @returns the index of the interval to which the input value belongs + */ + +int GetInterval16 (unsigned int value, unsigned int *rb) +{ + int r=0; + + if (value <= rb[7]) + { + /* 0..7 */ + if (value <= rb[3]) + { + /* 0..3 */ + if (value <= rb[1]) + { + /* 0..1 */ + if (value <= rb[0]) + { + /* 0 */ + r = 0; + } + else + { + /* 1 */ + r = 1; + } + } + else + { + /* 2..3 */ + if (value <= rb[2]) + { + /* 2 */ + r = 2; + } + else + { + /* 3 */ + r = 3; + } + } + } + else + { + /* 4..7 */ + if (value <= rb[5]) + { + /* 4..5 */ + if (value <= rb[4]) + { + /* 4 */ + r = 4; + } + else + { + /* 5 */ + r = 5; + } + } + else + { + /* 6..7 */ + if (value <= rb[6]) + { + /* 6 */ + r = 6; + } + else + { + /* 7 */ + r = 7; + } + } + } + } + else + { + /* 8..15 */ + if (value <= rb[11]) + { + /* 8..11 */ + if (value <= rb[9]) + { + /* 8..9 */ + if (value <= rb[8]) + { + /* 8 */ + r = 8; + } + else + { + /* 9 */ + r = 9; + } + } + else + { + /* 10..11 */ + if (value <= rb[10]) + { + /* 10 */ + r = 10; + } + else + { + /* 11 */ + r = 11; + } + } + } + else + { + /* 12..15 */ + if (value <= rb[13]) + { + /* 12..13 */ + if (value <= rb[12]) + { + /* 12 */ + r = 12; + } + else + { + /* 13 */ + r = 13; + } + } + else + { + /* 14..15 */ + if (value <= rb[14]) + { + /* 14 */ + r = 14; + } + else + { + /* 15 */ + r = 15; + } + } + } + } + + return r; +} + + +/** + * @brief Nonlinearity correction for the CHEOPS CCD readout values. + * It uses a set of splines as correction function. + * @param[in,out] data the array of pixel values stored as unsigned ints; + * this will be overwritten by the corrected values + * @param n the number of pixel values to be corrected + * @note overwrites input array + * @note saturates the corrected values at 65535 + */ + +void NlcSplineCorr28 (unsigned int *data, unsigned int n) +{ + unsigned int i, value, rightBorderIndex; + double x, xx, xxx; + unsigned int utemp32; + float ftemp; + + for (i=0; i < SPLINE_SEGMENTS; i++) + { + CrIaCopyArrayItem (NLCBORDERS_ID, &utemp32, i); + rborder[i] = utemp32; + + CrIaCopyArrayItem (NLCCOEFF_A_ID, &ftemp, i); + A[i] = (double) ftemp; + + CrIaCopyArrayItem (NLCCOEFF_B_ID, &ftemp, i); + B[i] = (double) ftemp; + + CrIaCopyArrayItem (NLCCOEFF_C_ID, &ftemp, i); + C[i] = (double) ftemp; + + CrIaCopyArrayItem (NLCCOEFF_D_ID, &ftemp, i); + D[i] = (double) ftemp; + } + + for (i=0; i < n; i++) + { + value = data[i]; + + /* get the index of the right border of the interval the current value belongs to */ + rightBorderIndex = GetInterval28 (value, rborder); + + /* The spline coefficients assume that x starts at 0 within the interval, + but our x counts from 0 to 65k, so we have to shift the x axis for + every interval back to zero by subtracting the left border. + The first interval starts at 0, so nothing has to be done for it. */ + + if (rightBorderIndex != 0) + { + x = (double) (value - rborder[rightBorderIndex-1]); + } + else + { + x = (double) value; + } + + /* this saves one multiplication */ + xx = x*x; + xxx = x*xx; + + x = D[rightBorderIndex]*xxx + C[rightBorderIndex]*xx + B[rightBorderIndex]*x + A[rightBorderIndex]; + + /* the result is not truncated to integer, but rounded with the help of the inbuilt fdtoi instruction */ + value = (unsigned int) roundf ((float)x); + + /* saturate a corrected value at 16 bits */ + if (value > 0xffff) + value = 0xffff; + + data[i] = value; + } + + return; +} + + +float NlcCalcGain (float Vss, float Vrd, float Vod, float Vog, float Tccd) +{ + double gain, gcorr, temp; + float ftemp; + unsigned int i; + + for (i=0; i < GAIN_PARAMS; i++) + { + /* D coefficients are used for the GAIN calculation */ + CrIaCopyArrayItem (NLCCOEFF_D_ID, &ftemp, i); + D[i] = (double) ftemp; + } + + /* sum up the terms with the coefficients */ + gcorr = 1.0; + + /* Vss - Rss */ + temp = (Vss - D[NLCI_Rss]); + gcorr += temp * D[NLCI_VssRss]; + + /* Vod - Vss - Rodss */ + temp = (Vod - Vss - D[NLCI_Rodss]); + gcorr += temp * D[NLCI_VodVssRodss]; + + /* (Vod - Vss - Rodss)**2 */ + temp = (Vod - Vss - D[NLCI_Rodss]); + gcorr += temp * temp * D[NLCI_VodVssRodss2]; + + /* Vrd - Vss - Rrdss */ + temp = (Vrd - Vss - D[NLCI_Rrdss]); + gcorr += temp * D[NLCI_VrdVssRrdss]; + + /* (Vrd - Vss - Rrdss)**2 */ + temp = (Vrd - Vss - D[NLCI_Rrdss]); + gcorr += temp * temp * D[NLCI_VrdVssRrdss2]; + + /* Vog - Vss - Rogss */ + temp = (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_VogVssRogss]; + + /* (Vog - Vss - Rogss)**2 */ + temp = (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * temp * D[NLCI_VogVssRogss2]; + + /* (Vog - Vss - Rogss)**3 */ + temp = (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * temp * temp * D[NLCI_VogVssRogss3]; + + /* (Vod - Vss - Rodss) * (Vrd - Vss - Rrdss) */ + temp = (Vod - Vss - D[NLCI_Rodss]) * (Vrd - Vss - D[NLCI_Rrdss]); + gcorr += temp * D[NLCI_VodxVrd]; + + /* (Vod - Vss - Rodss)**2 * (Vrd - Vss - Rrdss) */ + temp = (Vod - Vss - D[NLCI_Rodss]); + temp = temp * temp * (Vrd - Vss - D[NLCI_Rrdss]); + gcorr += temp * D[NLCI_Vod2xVrd]; + + /* (Vod - Vss - Rodss) * (Vrd - Vss - Rrdss)**2 */ + temp = (Vod - Vss - D[NLCI_Rodss]); + temp = temp * (Vrd - Vss - D[NLCI_Rrdss]) * (Vrd - Vss - D[NLCI_Rrdss]); + gcorr += temp * D[NLCI_VodxVrd2]; + + /* (Vod - Vss - Rodss)**2 * (Vrd - Vss - Rrdss)**2 */ + temp = (Vod - Vss - D[NLCI_Rodss]); + temp = temp * temp * (Vrd - Vss - D[NLCI_Rrdss]) * (Vrd - Vss - D[NLCI_Rrdss]); + gcorr += temp * D[NLCI_Vod2xVrd2]; + + /* (Vrd - Vss - Rrdss) * (Vog - Vss - Rogss) */ + temp = (Vrd - Vss - D[NLCI_Rrdss]) * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_VrdxVog]; + + /* (Vrd - Vss - Rrdss)**2 * (Vog - Vss - Rogss) */ + temp = (Vrd - Vss - D[NLCI_Rrdss]); + temp = temp * temp * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_Vrd2xVog]; + + /* (Vrd - Vss - Rrdss) * (Vog - Vss - Rogss)**2 */ + temp = (Vrd - Vss - D[NLCI_Rrdss]); + temp = temp * (Vog - Vss - D[NLCI_Rogss]) * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_VrdxVog2]; + + /* (Vrd - Vss - Rrdss)**2 * (Vog - Vss - Rogss)**2 */ + temp = (Vrd - Vss - D[NLCI_Rrdss]); + temp = temp * temp * (Vog - Vss - D[NLCI_Rogss]) * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_Vrd2xVog2]; + + /* (Vod - Vss - Rodss) * (Vog - Vss - Rogss) */ + temp = (Vod - Vss - D[NLCI_Rodss]) * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_VodxVog]; + + /* (Vod - Vss - Rodss)**2 * (Vog - Vss - Rogss) */ + temp = (Vod - Vss - D[NLCI_Rodss]); + temp = temp * temp * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_Vod2xVog]; + + /* (Vod - Vss - Rodss) * (Vog - Vss - Rogss)**2 */ + temp = (Vod - Vss - D[NLCI_Rodss]); + temp = temp * (Vog - Vss - D[NLCI_Rogss]) * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_VodxVog2]; + + /* (Vod - Vss - Rodss)**2 * (Vog - Vss - Rogss)**2 */ + temp = (Vod - Vss - D[NLCI_Rodss]); + temp = temp * temp * (Vog - Vss - D[NLCI_Rogss]) * (Vog - Vss - D[NLCI_Rogss]); + gcorr += temp * D[NLCI_Vod2xVog2]; + + /* Tccd + 40 */ + temp = Tccd + 40.0; + gcorr += temp * D[NLCI_Tccdmod]; + + gain = D[NLCI_Gain0] * gcorr; + + return (float) gain; +} + +/** + * @brief Nonlinearity correction for the CHEOPS CCD readout values. + * It uses a set of splines as correction function. + * @param[in,out] data the array of pixel values stored as unsigned ints; + * this will be overwritten by the corrected values + * @param bias the actual bias value derived from the image data (LOS part) + * @param bias0 the fixed "back-conversion" bias value + * @param gain actual gain derived from the voltages + * @param gain0 fixed gain used for back-conversion + * @param n the number of pixel values to be corrected + * @param rf the readout frequency, 100 or 230 kHz (default) + * @note overwrites input array + * @note bias0 should be set higher than the smallest value to be corrected: bias0 > min(data) + */ + +void NlcSplineCorr16 (unsigned int *data, double bias, double bias0, double gain, double gain0, unsigned int n, unsigned char rf) +{ + unsigned int i, rightBorderIndex; + double gaininv; + double g0_div_g, g0_div_gg; + double x; + unsigned int utemp32; + float ftemp; + + if ((gain == 0.0) || (gain0 == 0.0)) + { + return; + } + + gaininv = (double)1.0 / gain; + + g0_div_g = gain0 * gaininv; + g0_div_gg = g0_div_g * gaininv; + + if (rf != RF100KHZ) /* 230 kHz is default */ + { + for (i=0; i < NLC2_SEGMENTS; i++) + { + CrIaCopyArrayItem (NLCBORDERS_ID, &utemp32, i); + rborder[i] = utemp32; + + CrIaCopyArrayItem (NLCCOEFF_A_ID, &ftemp, i); + A[i] = (double) ftemp; + + CrIaCopyArrayItem (NLCCOEFF_B_ID, &ftemp, i); + B[i] = (double) ftemp; + + CrIaCopyArrayItem (NLCCOEFF_C_ID, &ftemp, i); + C[i] = (double) ftemp; + } + } + else /* use the parameter setup for 100 kHz */ + { + for (i=0; i < NLC2_SEGMENTS; i++) + { + CrIaCopyArrayItem (NLCBORDERS_2_ID, &utemp32, i); + rborder[i] = utemp32; + + CrIaCopyArrayItem (NLCCOEFF_A_2_ID, &ftemp, i); + A[i] = (double) ftemp; + + CrIaCopyArrayItem (NLCCOEFF_B_2_ID, &ftemp, i); + B[i] = (double) ftemp; + + CrIaCopyArrayItem (NLCCOEFF_C_2_ID, &ftemp, i); + C[i] = (double) ftemp; + } + } + + /* CHEOPS-UBE-INST-TN-TBC Equation 4 */ + for (i=0; i < NLC2_SEGMENTS; i++) + { + if (i == 0) + { + /* do nothing */ + } + else + { + C[i] = C[i] - B[i] * rborder[i-1] + A[i] * rborder[i-1]*rborder[i-1]; + + B[i] = B[i] - 2. * A[i] * rborder[i-1]; + + A[i] = A[i]; + } + } + + /* CHEOPS-UBE-INST-TN-TBC Equation 5 */ + for (i=0; i < NLC2_SEGMENTS; i++) + { + rborder[i] = roundf((float)((double)rborder[i] * gain + bias)); + } + + /* CHEOPS-UBE-INST-TN-TBC Equation 10 */ + for (i=0; i < NLC2_SEGMENTS; i++) + { + C[i] = C[i] * gain0 + (double) bias0 - B[i] * bias * g0_div_g + A[i] * bias * bias * g0_div_gg; + + B[i] = B[i] * g0_div_g - 2. * A[i] * bias * g0_div_gg; + + A[i] = A[i] * g0_div_gg; + } + + /* apply NLC to each pixel */ + for (i=0; i < n; i++) + { + /* get the index of the right border of the interval the current value belongs to */ + rightBorderIndex = GetInterval16 (data[i], rborder); + + x = (double)data[i]; + + x = A[rightBorderIndex]*x*x + B[rightBorderIndex]*x + C[rightBorderIndex]; + + data[i] = (unsigned int)roundf((float)x); + } + + return; +} + + +unsigned int SumU32 (unsigned int *data, unsigned int len) +{ + unsigned int i; + unsigned int sum = 0; + + for (i=0; i < len; i++) + sum += data[i]; + + return sum; +} + + +void QuickPhotometry (struct ScienceBuf *frame, unsigned int *workbuffer, struct SibPhotometry *phot) +{ + int centNPix, ann1NPix, ann2NPix; + + unsigned short Strategy; + unsigned char Rcent, Rann1, Rann2; + unsigned int TlocX, TlocY, xoff, yoff; + + unsigned int Cent, Ann1, Ann2; + + /* get relevant data pool variables */ + CrIaCopy(SDPPHOTSTRAT_ID, &Strategy); + CrIaCopy(SDPPHOTRCENT_ID, &Rcent); + CrIaCopy(SDPPHOTRANN1_ID, &Rann1); + CrIaCopy(SDPPHOTRANN2_ID, &Rann2); + + /* get target location from data pool */ + CrIaCopy(TARGETLOCATIONX_ID, &TlocX); + CrIaCopy(TARGETLOCATIONY_ID, &TlocY); + + xoff = TlocX - 51200; /* centre in target location system is at 51200 */ + yoff = TlocY - 51200; + + phot->centrum = 0.0f; + phot->annulus1 = 0.0f; + phot->annulus2 = 0.0f; + + /* extract the circular area of interest for the center */ + centNPix = RingExtract32 ((unsigned int *)(frame->data), frame->xelements, frame->yelements, xoff, yoff, 0.0f, (float) Rcent, workbuffer); + + if (Strategy == STAT_MEAN) + { + Cent = SumU32 (workbuffer, centNPix); + } + else if (Strategy == STAT_MEDIAN) + { + Cent = (unsigned int) Median ((int *)workbuffer, centNPix); /* NOTE: uint -> int conversion is ok because our pixel values are 16 bit anyway */ + } + else + { + Cent = 0U; + } + + /* extract the ring for the annulus 1 */ + ann1NPix = RingExtract32 ((unsigned int *)(frame->data), frame->xelements, frame->yelements, xoff, yoff, (float) Rcent, (float) Rann1, workbuffer); + + if (Strategy == STAT_MEAN) + { + Ann1 = SumU32 (workbuffer, ann1NPix); + } + else if (Strategy == STAT_MEDIAN) + { + Ann1 = (unsigned int) Median ((int *)workbuffer, ann1NPix); + } + else + { + Ann1 = 0U; + } + + /* extract the ring for the annulus 2 */ + ann2NPix = RingExtract32 ((unsigned int *)(frame->data), frame->xelements, frame->yelements, xoff, yoff, (float) Rann1, (float) Rann2, workbuffer); + + if (Strategy == STAT_MEAN) + { + Ann2 = SumU32 (workbuffer, ann2NPix); + } + else if (Strategy == STAT_MEDIAN) + { + Ann2 = (unsigned int) Median ((int *)workbuffer, ann2NPix); + } + else + { + Ann2 = 0U; + } + + if (Strategy == STAT_MEAN) + { + if (centNPix > 0) + phot->centrum = (float) Cent / (float) centNPix; + if (ann1NPix > 0) + phot->annulus1 = (float) Ann1 / (float) ann1NPix; + if (ann2NPix > 0) + phot->annulus2 = (float) Ann2 / (float) ann2NPix; + } + else + { + phot->centrum = (float) Cent; + phot->annulus1 = (float) Ann1; + phot->annulus2 = (float) Ann2; + } + + return; +} diff --git a/CompressionEntity/src/SdpNlcPhot.h b/CompressionEntity/src/SdpNlcPhot.h new file mode 100644 index 0000000000000000000000000000000000000000..235101293893f4f9f3919f4098ab4060592d62b9 --- /dev/null +++ b/CompressionEntity/src/SdpNlcPhot.h @@ -0,0 +1,53 @@ +#ifndef SDPNLCPHOT_H +#define SDPNLCPHOT_H + +#include "SdpBuffers.h" /* for struct ScienceBuf and struct SibPhotometry */ + + +/* NLC2 indices for easier access of the coefficients stored in the NLCCOEFF_D array */ +#define NLCI_Bias0 0 +#define NLCI_Gain0 1 +#define NLCI_Rss 2 +#define NLCI_Rodss 3 +#define NLCI_Rrdss 4 +#define NLCI_Rogss 5 +#define NLCI_VssRss 6 +#define NLCI_VodVssRodss 7 +#define NLCI_VodVssRodss2 8 +#define NLCI_VrdVssRrdss 9 +#define NLCI_VrdVssRrdss2 10 +#define NLCI_VogVssRogss 11 +#define NLCI_VogVssRogss2 12 +#define NLCI_VogVssRogss3 13 +#define NLCI_VodxVrd 14 +#define NLCI_Vod2xVrd 15 +#define NLCI_VodxVrd2 16 +#define NLCI_Vod2xVrd2 17 +#define NLCI_VrdxVog 18 +#define NLCI_Vrd2xVog 19 +#define NLCI_VrdxVog2 20 +#define NLCI_Vrd2xVog2 21 +#define NLCI_VodxVog 22 +#define NLCI_Vod2xVog 23 +#define NLCI_VodxVog2 24 +#define NLCI_Vod2xVog2 25 +#define NLCI_Tccdmod 26 +#define NLCI_Spare 27 + + +int GetInterval28 (unsigned int value, unsigned int *rborder); + +int GetInterval16 (unsigned int value, unsigned int *rb); + +void NlcSplineCorr28 (unsigned int *data, unsigned int n); + +float NlcCalcGain (float Vss, float Vrd, float Vod, float Vog, float Tccd); + +void NlcSplineCorr16 (unsigned int *data, double bias, double bias0, double gain, double gain0, unsigned int n, unsigned char rf); + +unsigned int SumU32 (unsigned int *data, unsigned int len); + +void QuickPhotometry (struct ScienceBuf *frame, unsigned int *workbuffer, struct SibPhotometry *phot); + + +#endif diff --git a/CrFramework/CHANGELOG b/CrFramework/CHANGELOG new file mode 100644 index 0000000000000000000000000000000000000000..5ed8b029a267e03e3f9dfe5190d6646772a0088e --- /dev/null +++ b/CrFramework/CHANGELOG @@ -0,0 +1,5 @@ +***************************** +* Changelog for CrFramework * +***************************** + +* directory and files put here by RO on 8-MAR-2015 diff --git a/CrFramework/README b/CrFramework/README new file mode 100644 index 0000000000000000000000000000000000000000..352dd7b51aec6f379b40893a960d23d3ecb42498 --- /dev/null +++ b/CrFramework/README @@ -0,0 +1,9 @@ +- This package contains the source code and documentation of the C2 Implementation of the CORDET Framework +- The source code is released under GNU LGPLv3 +- The FwProfile is a product of P&P Software GmbH, @copyright P&P Software GmbH +- More information can be found on: http://pnp-software.com/cordetfw +- Please don't hesitate to contact us if you would like to know more about FW Profile: pnp-software@pnp-software.com + +The CORDET Framework and its C2 implementation are distributed in the hope that they will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. diff --git a/CrFramework/src/AppStartUp/CrFwAppResetProc.h b/CrFramework/src/AppStartUp/CrFwAppResetProc.h new file mode 100644 index 0000000000000000000000000000000000000000..2f3f3455650ab4837f0794fe59971ba64ae3befd --- /dev/null +++ b/CrFramework/src/AppStartUp/CrFwAppResetProc.h @@ -0,0 +1,52 @@ +/** + * @file + * @ingroup crOpenIfGroup + * Interface to the Application Reset Procedure. + * The Application Reset Procedure is started by the Application + * State Machine (see <code>CrFwAppSm.h</code>). + * It executes while the state machine is in state RESET. + * This procedure is responsible for resetting all + * the application components and for performing any other reset action + * for the application. + * The Application Reset Procedure is entirely application-specific. + * This header file declares a function to retrieve a pointer to the procedure + * descriptor. + * The implementation of this file provides an implementation of the procedure + * and is therefore application-specific. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_APP_RESET_PROC_H_ +#define CRFW_APP_RESET_PROC_H_ + +#include "FwSmConstants.h" +#include "FwPrConstants.h" +#include "CrFwConstants.h" + +/** + * Retrieve the singleton instance of the Application Reset Procedure. + * @return the singleton instance of the Application Reset Procedure. + */ +FwPrDesc_t CrFwAppSmGetAppResetProc(); + +#endif /* CRFW_APP_RESET_PROC_H_ */ diff --git a/CrFramework/src/AppStartUp/CrFwAppShutdownProc.h b/CrFramework/src/AppStartUp/CrFwAppShutdownProc.h new file mode 100644 index 0000000000000000000000000000000000000000..d30af6c2d474008c3fd8813d942dfbe7ac863603 --- /dev/null +++ b/CrFramework/src/AppStartUp/CrFwAppShutdownProc.h @@ -0,0 +1,52 @@ +/** + * @file + * @ingroup crOpenIfGroup + * Interface to the Application Shutdown Procedure. + * The Application Shutdown Procedure is started by the Application + * State Machine (see <code>CrFwAppSm.h</code>). + * It executes while the state machine is in state SHUTDOWN. + * This procedure is responsible for shutting down all + * the application components and for performing any other shutdown action + * for the application. + * The Application Shutdown Procedure is entirely application-specific. + * This header file declares a function to retrieve a pointer to the procedure + * descriptor. + * The implementation of this file provides an implementation of the procedure + * and is therefore application-specific. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_APP_SHUTDOWN_PROC_H_ +#define CRFW_APP_SHUTDOWN_PROC_H_ + +#include "FwSmConstants.h" +#include "FwPrConstants.h" +#include "CrFwConstants.h" + +/** + * Retrieve the singleton instance of the Application Shutdown Procedure. + * @return the singleton instance of the Application Shutdown Procedure. + */ +FwPrDesc_t CrFwAppSmGetAppShutdownProc(); + +#endif /* CRFW_APP_SHUTDOWN_PROC_H_ */ diff --git a/CrFramework/src/AppStartUp/CrFwAppSm.c b/CrFramework/src/AppStartUp/CrFwAppSm.c new file mode 100644 index 0000000000000000000000000000000000000000..bfb289bd04d4adefbc5570b45366ae101fefe4df --- /dev/null +++ b/CrFramework/src/AppStartUp/CrFwAppSm.c @@ -0,0 +1,249 @@ +/** + * @file + * + * Implementation of Application State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "CrFwAppSm.h" +#include "CrFwAppStartUpProc.h" +#include "CrFwAppResetProc.h" +#include "CrFwAppShutdownProc.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" +/* Include FW Profile files */ +#include "CrFwAppSmUserPar.h" + +/** State identifier for state START_UP in the application State Machine. */ +#define CR_FW_APP_STATE_START_UP 1 + +/** State identifier for state NORMAL in the application State Machine. */ +#define CR_FW_APP_STATE_NORMAL 2 + +/** State identifier for state RESET in the application State Machine. */ +#define CR_FW_APP_STATE_RESET 3 + +/** State identifier for state SHUTDOWN in the application State Machine. */ +#define CR_FW_APP_STATE_SHUTDOWN 4 + +/** Identifier for transition command "Reset" in the Application State Machine. */ +#define CR_FW_APP_TR_RESET CR_FW_APP_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+0 + +/** Identifier for transition command "Shutdown" in the Application State Machine. */ +#define CR_FW_APP_TR_SHUTDOWN CR_FW_APP_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+1 + +/** The singleton instance of the Application State Machine. */ +static FwSmDesc_t appSmDesc = NULL; + +/** + * Function which starts the Application Start-Up Procedure. + * This function is used as entry action for the START_UP state. + * @param smDesc the state machine descriptor + */ +static void StartAppStartUpPr(FwSmDesc_t smDesc); + +/** + * Function which starts the Application Reset Procedure. + * This function is used as entry action for the RESET state. + * @param smDesc the state machine descriptor + */ +static void StartAppResetPr(FwSmDesc_t smDesc); + +/** + * Function which starts the Application Shutdown Procedure. + * This function is used as entry action for the SHUTDOWN state. + * @param smDesc the state machine descriptor + */ +static void StartAppShutdownPr(FwSmDesc_t smDesc); + +/** + * Function which checks whether the Application Start-Up Procedure has terminated. + * This function acts as guard on the transition out of START_UP. + * @param smDesc the state machine descriptor + * @return 1 if the Application Start-Up Procedure has terminated, 0 otherwise + */ +static FwSmBool_t IsStartUpPrTerminated(FwSmDesc_t smDesc); + +/** + * Function which checks whether the Application Reset Procedure has terminated. + * This function acts as guard on the transition out of RESET. + * @param smDesc the state machine descriptor + * @return 1 if the Application Reset Procedure has terminated, 0 otherwise + */ +static FwSmBool_t IsResetPrTerminated(FwSmDesc_t smDesc); + +/** + * Function which checks whether the Application Shutdown Procedure has terminated. + * This function acts as guard on the transition out of SHUTDOWN. + * @param smDesc the state machine descriptor + * @return 1 if the Application Shutdown Procedure has terminated, 0 otherwise + */ +static FwSmBool_t IsShutdownPrTerminated(FwSmDesc_t smDesc); + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwAppSmMake() { + FwSmCounterS1_t nOfStates = 4; /* Number of states */ + FwSmCounterS1_t nOfChoicePseudoStates = 0; /* Number of choice pseudo-states */ + FwSmCounterS1_t nOfTrans = 6; /* Number of transitions */ + FwSmCounterS1_t nOfActions = 3; /* Number of actions */ + FwSmCounterS1_t nOfGuards = 3; /* Number of guards */ + + if (appSmDesc != NULL) + return appSmDesc; + + /* Create the application state machine */ + appSmDesc = FwSmCreate(nOfStates, nOfChoicePseudoStates, nOfTrans, nOfActions, nOfGuards); + + /* Configure the application state machine */ + FwSmAddState(appSmDesc, CR_FW_APP_STATE_START_UP, 1, &StartAppStartUpPr, NULL, NULL, CR_FW_APPSM_STARTUP_ESM); + FwSmAddState(appSmDesc, CR_FW_APP_STATE_NORMAL, 2, NULL, NULL, NULL, CR_FW_APPSM_NORMAL_ESM); + FwSmAddState(appSmDesc, CR_FW_APP_STATE_RESET, 1, &StartAppResetPr, NULL, NULL, CR_FW_APPSM_RESET_ESM); + FwSmAddState(appSmDesc, CR_FW_APP_STATE_SHUTDOWN, 1, &StartAppShutdownPr, NULL, NULL, CR_FW_APPSM_SHUTDOWN_ESM); + FwSmAddTransIpsToSta(appSmDesc, CR_FW_APP_STATE_START_UP, NULL); + FwSmAddTransStaToSta(appSmDesc, FW_TR_EXECUTE, CR_FW_APP_STATE_START_UP, CR_FW_APP_STATE_NORMAL, + NULL, &IsStartUpPrTerminated); + FwSmAddTransStaToSta(appSmDesc, CR_FW_APP_TR_RESET, CR_FW_APP_STATE_NORMAL, CR_FW_APP_STATE_RESET, + NULL, NULL); + FwSmAddTransStaToSta(appSmDesc, FW_TR_EXECUTE, CR_FW_APP_STATE_RESET, CR_FW_APP_STATE_NORMAL, + NULL, &IsResetPrTerminated); + FwSmAddTransStaToSta(appSmDesc, CR_FW_APP_TR_SHUTDOWN, CR_FW_APP_STATE_NORMAL, CR_FW_APP_STATE_SHUTDOWN, + NULL, NULL); + FwSmAddTransStaToFps(appSmDesc, FW_TR_EXECUTE, CR_FW_APP_STATE_SHUTDOWN, NULL, &IsShutdownPrTerminated); + + return appSmDesc; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwAppSmStart() { + FwSmStart(appSmDesc); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwAppSmExecute() { + FwSmExecute(appSmDesc); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwAppSmReset() { + FwSmMakeTrans(appSmDesc, CR_FW_APP_TR_RESET); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwAppSmShutdown() { + FwSmMakeTrans(appSmDesc, CR_FW_APP_TR_SHUTDOWN); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwAppSmIsStarted() { + return FwSmIsStarted(appSmDesc); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwAppSmIsInStartUp() { + return (FwSmGetCurState(appSmDesc) == CR_FW_APP_STATE_START_UP); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwAppSmIsInNormal() { + return (FwSmGetCurState(appSmDesc) == CR_FW_APP_STATE_NORMAL); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwAppSmIsInReset() { + return (FwSmGetCurState(appSmDesc) == CR_FW_APP_STATE_RESET); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwAppSmIsInShutdown() { + return (FwSmGetCurState(appSmDesc) == CR_FW_APP_STATE_SHUTDOWN); +} + +/*-----------------------------------------------------------------------------------------*/ +static void StartAppStartUpPr(FwSmDesc_t smDesc) { + (void)(smDesc); + FwPrStart(CrFwAppSmGetAppStartUpProc()); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void StartAppResetPr(FwSmDesc_t smDesc) { + (void)(smDesc); + FwPrStart(CrFwAppSmGetAppResetProc()); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void StartAppShutdownPr(FwSmDesc_t smDesc) { + (void)(smDesc); + FwPrStart(CrFwAppSmGetAppShutdownProc()); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static FwSmBool_t IsStartUpPrTerminated(FwSmDesc_t smDesc) { + (void)(smDesc); + return (FwPrIsStarted(CrFwAppSmGetAppStartUpProc()) == 0); +} + +/*-----------------------------------------------------------------------------------------*/ +static FwSmBool_t IsResetPrTerminated(FwSmDesc_t smDesc) { + (void)(smDesc); + return (FwPrIsStarted(CrFwAppSmGetAppResetProc()) == 0); +} + +/*-----------------------------------------------------------------------------------------*/ +static FwSmBool_t IsShutdownPrTerminated(FwSmDesc_t smDesc) { + (void)(smDesc); + return (FwPrIsStarted(CrFwAppSmGetAppShutdownProc()) == 0); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwAppSmGetEsmStartUp() { + return FwSmGetEmbSm(appSmDesc, CR_FW_APP_STATE_START_UP); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwAppSmGetEsmNormal() { + return FwSmGetEmbSm(appSmDesc, CR_FW_APP_STATE_NORMAL); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwAppSmGetEsmReset() { + return FwSmGetEmbSm(appSmDesc, CR_FW_APP_STATE_RESET); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwAppSmGetEsmShutdown() { + return FwSmGetEmbSm(appSmDesc, CR_FW_APP_STATE_SHUTDOWN); +} diff --git a/CrFramework/src/AppStartUp/CrFwAppSm.h b/CrFramework/src/AppStartUp/CrFwAppSm.h new file mode 100644 index 0000000000000000000000000000000000000000..d6c399e3551d08d884bfe1871c1979a72456ffd9 --- /dev/null +++ b/CrFramework/src/AppStartUp/CrFwAppSm.h @@ -0,0 +1,182 @@ +/** + * @file + * @ingroup appSmgroup + * Definition of Application State Machine. + * The Application State Machine implements the application start-up behaviour + * (see figures below). + * + * The Application State Machine is a singleton. + * Initially, after it has been started through function <code>FwSmStart</code>, + * it is in state START-UP. + * At entry into this state, the Application Start-Up Procedure is executed. + * This procedure is an adaptation point for the application (it is defined in + * <code>CrFwAppShutdownProc.c</code>). + * + * Normal operation takes place in state NORMAL. + * In particular, the services provided by an application to its users are only + * guaranteed to be available when the application is in state NORMAL and it is + * only from this state that the application makes use of the services provided by + * other applications. + * Thus, in state NORMAL, an application may assume that its service interfaces + * are all operational. + * + * When state NORMAL is entered or exited, a notification is sent to the users + * of the application services. + * The content of this notification is an adaptation point. + * + * An application can be reset by sending command Reset to its Application State + * Machine (this is done through function <code>::CrFwAppSmReset</code>). + * This causes a transition to state RESET where the Application Reset Procedure + * is executed. + * This procedure is an adaptation point for the application (it is defined in + * <code>CrFwAppResetProc.c</code>). + * + * Finally, the orderly shutdown of an application is performed by sending command + * Shutdown to the Application State Machine (this is done through function + * <code>::CrFwAppSmShutdown</code>). + * This triggers a transition to state SHUTDOWN where the Application Shutdown Procedure + * is executed. + * This procedure is an adaptation point for the application (it is defined in + * <code>CrFwAppShutdownProc.c</code>). + * + * Applications may define embedded state machines in the states + * of the Application State Machine. + * The embedded state machines are adaptation points for the framework. + * They are defined in <code>CrFwAppSmUserPar.h</code>. + * + * @image html ApplicationSM.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_APP_SM_H_ +#define CRFW_APP_SM_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Retrieve the singleton instance of the Application State Machine. + * The Application State Machine is a singleton. + * The first time this function is called, it creates the Application State + * Machine. + * Subsequently, it always returns the same instance. + * + * The first time this function is called, it returns the Application State Machine + * before it has been started. + * @return the descriptor of the Application State Machine or NULL + * if the state machine could not be created. + */ +FwSmDesc_t CrFwAppSmMake(); + +/** + * Start the Application State Machine. + * This function causes the Application State Machine to make the transition from + * its initial pseudo-state into its initial state START_UP. + */ +void CrFwAppSmStart(); + +/** + * Execute the Application State Machine. + * This function sends command <code>Execute</code> to the Application State Machine. + */ +void CrFwAppSmExecute(); + +/** + * Reset the Application State Machine. + * This function sends command <code>Reset</code> to the Application State Machine. + */ +void CrFwAppSmReset(); + +/** + * Shutdown the Application State Machine. + * This function sends command <code>Shutdown</code> to the Application State Machine. + */ +void CrFwAppSmShutdown(); + +/** + * Return true if the Application State Machine has been started. + * @return 1 if the Application State Machine has been started; 0 otherwise + */ +CrFwBool_t CrFwAppSmIsStarted(); + +/** + * Return true if the Application State Machine is in state START_UP. + * @return 1 if the Application State Machine is in state START_UP; 0 otherwise + */ +CrFwBool_t CrFwAppSmIsInStartUp(); + +/** + * Return true if the Application State Machine is in state NORMAL. + * @return 1 if the Application State Machine is in state NORMAL; 0 otherwise + */ +CrFwBool_t CrFwAppSmIsInNormal(); + +/** + * Return true if the Application State Machine is in state RESET. + * @return 1 if the Application State Machine is in state RESET; 0 otherwise + */ +CrFwBool_t CrFwAppSmIsInReset(); + +/** + * Return true if the Application State Machine is in state SHUTDOWN. + * @return 1 if the Application State Machine is in state SHUTDOWN; 0 otherwise + */ +CrFwBool_t CrFwAppSmIsInShutdown(); + +/** + * Return the state machine embedded in state START-UP (or NULL if no state machine + * is embedded in START-UP). + * @return the state machine embedded in state START-UP (or NULL if no state machine + * is embedded in START-UP) + */ +FwSmDesc_t CrFwAppSmGetEsmStartUp(); + +/** + * Return the state machine embedded in state NORMAL (or NULL if no state machine + * is embedded in NORMAL). + * @return the state machine embedded in state NORMAL (or NULL if no state machine + * is embedded in NORMAL) + */ +FwSmDesc_t CrFwAppSmGetEsmNormal(); + +/** + * Return the state machine embedded in state RESET (or NULL if no state machine + * is embedded in RESET). + * @return the state machine embedded in state RESET (or NULL if no state machine + * is embedded in RESET) + */ +FwSmDesc_t CrFwAppSmGetEsmReset(); + +/** + * Return the state machine embedded in state SHUTDOWN (or NULL if no state machine + * is embedded in SHUTDOWN). + * @return the state machine embedded in state SHUTDOWN (or NULL if no state machine + * is embedded in SHUTDOWN) + */ +FwSmDesc_t CrFwAppSmGetEsmShutdown(); + +#endif /* CRFW_APP_SM_H_ */ diff --git a/CrFramework/src/AppStartUp/CrFwAppStartUpProc.h b/CrFramework/src/AppStartUp/CrFwAppStartUpProc.h new file mode 100644 index 0000000000000000000000000000000000000000..11e30e2d8746f4b7aec8a75365317019ed84ae96 --- /dev/null +++ b/CrFramework/src/AppStartUp/CrFwAppStartUpProc.h @@ -0,0 +1,52 @@ +/** + * @file + * @ingroup crOpenIfGroup + * Interface to the Application Start-Up Procedure. + * The Application Start-Up Procedure is started by the Application + * State Machine (see <code>CrFwAppSm.h</code>). + * It executes while the state machine is in state START_UP. + * This procedure is responsible for creating, initializing and configuring all + * the application components and for performing any other initialization action + * for the application. + * The Application Start-Up Procedure is entirely application-specific. + * This header file declares a function to retrieve a pointer to the procedure + * descriptor. + * The implementation of this file provides an implementation of the procedure + * and is therefore application-specific. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_APP_START_UP_PROC_H_ +#define CRFW_APP_START_UP_PROC_H_ + +#include "FwSmConstants.h" +#include "FwPrConstants.h" +#include "CrFwConstants.h" + +/** + * Retrieve the singleton instance of the Application Start-Up Procedure. + * @return the singleton instance of the Application Start-Up Procedure. + */ +FwPrDesc_t CrFwAppSmGetAppStartUpProc(); + +#endif /* CRFW_APP_START_UP_PROC_H_ */ diff --git a/CrFramework/src/Aux/CrFwAux.c b/CrFramework/src/Aux/CrFwAux.c new file mode 100644 index 0000000000000000000000000000000000000000..a5979448c21c2d77db4e44bfc06a592815a376a7 --- /dev/null +++ b/CrFramework/src/Aux/CrFwAux.c @@ -0,0 +1,273 @@ +/** + * @file + * @ingroup auxGroup + * Implementation of Auxiliary Module. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "CrFwAux.h" +#include "OutCmp/CrFwOutCmp.h" +/* Include configuration files */ +#include "CrFwOutRegistryUserPar.h" +#include "CrFwOutFactoryUserPar.h" +#include "CrFwInFactoryUserPar.h" +#include "CrFwInStreamUserPar.h" +#include "CrFwOutStreamUserPar.h" +#include "CrFwOutManagerUserPar.h" + +/** Array of OutComponent descriptors. */ +static CrFwOutCmpKindDesc_t outCmpKindDesc[CR_FW_OUTCMP_NKINDS] = CR_FW_OUTCMP_INIT_KIND_DESC; + +/** Array of InCommand descriptors. */ +static CrFwInCmdKindDesc_t inCmdKindDesc[CR_FW_INCMD_NKINDS] = CR_FW_INCMD_INIT_KIND_DESC; + +/** Array of InReport service descriptors. */ +static CrFwInRepKindDesc_t inRepKindDesc[CR_FW_INREP_NKINDS] = CR_FW_INREP_INIT_KIND_DESC; + +/** Array of service descriptors. */ +static CrFwServDesc_t servDesc[CR_FW_OUTREGISTRY_NSERV] = CR_FW_OUTREGISTRY_INIT_SERV_DESC; + +/** The sizes of the packet queues in the InStream components. */ +static CrFwCounterU1_t inStreamPcktQueueSize[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_PQSIZE; + +/** The sizes of the packet queues in the OutStream components. */ +static CrFwCounterU1_t outStreamPcktQueueSize[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_PQSIZE; + +/** The sizes of the POCL in the OutManager components. */ +static CrFwCounterU1_t outManagerPoclSize[CR_FW_NOF_OUTMANAGER] = CR_FW_OUTMANAGER_POCLSIZE; + +/* -------------------------------------------------------------------------- */ +CrFwConfigCheckOutcome_t CrFwAuxConfigCheck() { + + if (CrFwAuxOutRegistryConfigCheck() == 0) + return crOutRegistryConfigParInconsistent; + + if (CrFwAuxOutFactoryConfigCheck() == 0) + return crOutFactoryConfigParInconsistent; + + if (CrFwAuxInFactoryInCmdConfigCheck() == 0) + return crInFactoryInCmdConfigParInconsistent; + + if (CrFwAuxInFactoryInRepConfigCheck() == 0) + return crInFactoryInRepConfigParInconsistent; + + return crConsistencyCheckSuccess; +} + +/* -------------------------------------------------------------------------- */ +CrFwBool_t CrFwAuxOutRegistryConfigCheck() { + CrFwCmdRepIndex_t i; + CrFwCmdRepKindIndex_t j; + CrFwCounterU1_t k; + CrFwServType_t servType; + CrFwServSubType_t servSubType; + CrFwBool_t found; + + if (CR_FW_OUTREGISTRY_N < 1) + return 0; + + for (i=0; i<(CR_FW_OUTREGISTRY_NSERV-1); i++) { + if (servDesc[i].servType > servDesc[i+1].servType) + /* The following can be dead code, depending on the specific + * instantiation of the FW Profile.*/ + return 0; + if (servDesc[i].servType == servDesc[i+1].servType) + if (servDesc[i].servSubType > servDesc[i+1].servSubType) + /* The following can be dead code, depending on the specific + * instantiation of the FW Profile.*/ + return 0; + } + + for (i=0; i<CR_FW_OUTREGISTRY_NSERV; i++) { + servType = servDesc[i].servType; + servSubType = servDesc[i].servSubType; + found = 0; + for (j=0; j<CR_FW_OUTCMP_NKINDS; j++) { + if (outCmpKindDesc[j].servType == servType) + if (outCmpKindDesc[j].servSubType == servSubType) { + found = 1; + break; + } + if (outCmpKindDesc[j].servType > servType) + break; + } + if (found == 0) + /* The following can be dead code, depending on the specific + * instantiation of the FW Profile.*/ + return 0; + } + + for (k=0; k<CR_FW_NOF_INSTREAM; k++) + /* The following can be dead code, depending on the specific + * instantiation of the FW Profile.*/ + if (inStreamPcktQueueSize[k]<1) + return 0; + + for (k=0; k<CR_FW_NOF_OUTSTREAM; k++) + /* The following can be dead code, depending on the specific + * instantiation of the FW Profile.*/ + if (outStreamPcktQueueSize[k]<1) + return 0; + + for (k=0; k<CR_FW_NOF_OUTMANAGER; k++) + /* The following can be dead code, depending on the specific + * instantiation of the FW Profile.*/ + if (outManagerPoclSize[k]<1) + return 0; + + return 1; +} + +/* -------------------------------------------------------------------------- */ +CrFwBool_t CrFwAuxOutFactoryConfigCheck() { + CrFwCmdRepIndex_t j; + CrFwCmdRepKindIndex_t i; + CrFwServType_t servType; + CrFwServSubType_t servSubType; + CrFwDiscriminant_t disc; + CrFwBool_t found; + + if (CR_FW_OUTFACTORY_MAX_NOF_OUTCMP < 1) + return 0; + + if (CR_FW_OUTCMP_NKINDS < 1) + return 0; + + for (i=0; i<(CR_FW_OUTCMP_NKINDS-1); i++) { + if (outCmpKindDesc[i].servType > outCmpKindDesc[i+1].servType) + return 0; + + if (outCmpKindDesc[i].servType == outCmpKindDesc[i+1].servType) + if (outCmpKindDesc[i].servSubType > outCmpKindDesc[i+1].servSubType) + return 0; + + if (outCmpKindDesc[i].servType == outCmpKindDesc[i+1].servType) + if (outCmpKindDesc[i].servSubType == outCmpKindDesc[i+1].servSubType) + if (outCmpKindDesc[i].discriminant > outCmpKindDesc[i+1].discriminant) + return 0; + + if (outCmpKindDesc[i].pcktLength < 1) + return 0; + } + + for (i=0; i<CR_FW_OUTCMP_NKINDS; i++) { + servType = outCmpKindDesc[i].servType; + servSubType = outCmpKindDesc[i].servSubType; + disc = outCmpKindDesc[i].discriminant; + found = 0; + for (j=0; j<CR_FW_OUTREGISTRY_NSERV; j++) { + if (servDesc[j].servType == servType) + if (servDesc[j].servSubType == servSubType) + if (servDesc[j].maxDiscriminant >= disc) { + found = 1; + break; + } + if (servDesc[j].servType > servType) + break; + } + if (found == 0) + return 0; + } + + return 1; +} + +/* -------------------------------------------------------------------------- */ +CrFwBool_t CrFwAuxInFactoryInCmdConfigCheck() { + CrFwCmdRepKindIndex_t i; + + if (CR_FW_INFACTORY_MAX_NOF_INCMD < 1) + return 0; + + if (CR_FW_OUTCMP_NKINDS < 1) + return 0; + + for (i=0; i<(CR_FW_INCMD_NKINDS-1); i++) { + if (inCmdKindDesc[i].servType > inCmdKindDesc[i+1].servType) + return 0; + + if (inCmdKindDesc[i].servType == inCmdKindDesc[i+1].servType) + if (inCmdKindDesc[i].servSubType > inCmdKindDesc[i+1].servSubType) + return 0; + + if (inCmdKindDesc[i].servType == inCmdKindDesc[i+1].servType) + if (inCmdKindDesc[i].servSubType == inCmdKindDesc[i+1].servSubType) + if (inCmdKindDesc[i].discriminant > inCmdKindDesc[i+1].discriminant) + return 0; + } + + for (i=0; i<CR_FW_INCMD_NKINDS; i++) { + if (inCmdKindDesc[i].servType > CR_FW_MAX_SERV_TYPE) + return 0; + + if (inCmdKindDesc[i].servSubType > CR_FW_MAX_SERV_SUBTYPE) + return 0; + + if (inCmdKindDesc[i].discriminant > CR_FW_MAX_DISCRIMINANT) + return 0; + } + + return 1; +} + +/* -------------------------------------------------------------------------- */ +CrFwBool_t CrFwAuxInFactoryInRepConfigCheck() { + CrFwCmdRepKindIndex_t i; + + if (CR_FW_INFACTORY_MAX_NOF_INREP < 1) + return 0; + + if (CR_FW_INREP_NKINDS < 1) + return 0; + + for (i=0; i<(CR_FW_INREP_NKINDS-1); i++) { + if (inRepKindDesc[i].servType > inRepKindDesc[i+1].servType) + return 0; + + if (inRepKindDesc[i].servType == inRepKindDesc[i+1].servType) + if (inRepKindDesc[i].servSubType > inRepKindDesc[i+1].servSubType) + return 0; + + if (inRepKindDesc[i].servType == inRepKindDesc[i+1].servType) + if (inRepKindDesc[i].servSubType == inRepKindDesc[i+1].servSubType) + if (inRepKindDesc[i].discriminant > inRepKindDesc[i+1].discriminant) + return 0; + } + + for (i=0; i<CR_FW_INREP_NKINDS; i++) { + if (inRepKindDesc[i].servType > CR_FW_MAX_SERV_TYPE) + return 0; + + if (inRepKindDesc[i].servSubType > CR_FW_MAX_SERV_SUBTYPE) + return 0; + + if (inRepKindDesc[i].discriminant > CR_FW_MAX_DISCRIMINANT) + return 0; + } + + return 1; +} diff --git a/CrFramework/src/Aux/CrFwAux.h b/CrFramework/src/Aux/CrFwAux.h new file mode 100644 index 0000000000000000000000000000000000000000..5bd6f71c7f9fef7697e9c5ebedfd9cfbba65e27e --- /dev/null +++ b/CrFramework/src/Aux/CrFwAux.h @@ -0,0 +1,164 @@ +/** + * @file + * @ingroup auxGroup + * Auxiliary module to check the static part of an application's configuration. + * The configuration of an application instantiated from the CORDET Framework is, + * for the most part, defined statically in files with names like: + * <code>CrFwXxxUserPar</code> where "Xxx" is the name of the framework component + * to which the configuration information applies. + * This module defines a set of functions which check the consistency of the + * configuration information in these configuration files. + * A function is defined for each configuration file and, additionally, + * function <code>::CrFwAuxConfigCheck</code> checks all the configuration files. + * + * <b>Mode of Use of the Aux Module</b> + * + * Applications would normally use the functions in this module during the + * application development phase to verify the correctness of the information + * in the configuration files. + * Once this correctness has been confirmed, the configuration checks can be + * omitted. + * It is therefore not expected that this module will be included in the final + * executable for an application. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_AUX_H_ +#define CRFW_AUX_H_ + +#include "CrFwConstants.h" + +/** Type for the outcome of the consistency check on the configuration parameters */ +typedef enum { + /** All configuration consistency checks have been passed */ + crConsistencyCheckSuccess = 1, + /** OutRegistry configuration parameters are inconsistent (see <code>CrFwAuxOutRegistryConfigCheck.h</code>) */ + crOutRegistryConfigParInconsistent = 2, + /** OutFactory configuration parameters are inconsistent (see <code>CrFwAuxOutFactoryConfigCheck.h</code>) */ + crOutFactoryConfigParInconsistent = 3, + /** InFactory configuration parameters for InCommands are inconsistent (see <code>CrFwAuxInFactoryInCmdConfigCheck.h</code>) */ + crInFactoryInCmdConfigParInconsistent = 4, + /** InFactory configuration parameters for InReports are inconsistent (see <code>CrFwAuxInFactoryInRepConfigCheck.h</code>) */ + crInFactoryInRepConfigParInconsistent = 5 +} CrFwConfigCheckOutcome_t; + +/** + * Check the configuration of an application. + * This function calls all the configuration check functions and verifies that + * they all return true (to signify: "no configuration error detected"). + * The function returns false as soon as it encounters a configuration check function + * which returns false. + * @return a value from <code>CrFwConfigCheckOutcome_t</code> indicating which configuration + * check has failed. + */ +CrFwConfigCheckOutcome_t CrFwAuxConfigCheck(); + +/** + * Check the configuration of the OutRegistry component. + * The following checks are performed on the configuration data in + * <code>CrFwOutRegistryUserPar.h</code>: + * - CR_FW_OUTREGISTRY_N is greater than zero + * - The service types are listed in increasing order in the service descriptor + * initializer (<code>CR_FW_OUTREGISTRY_INIT_SERV_DESC</code>) + * - The service sub-types within a type are listed in increasing order in the service + * descriptor initializer (<code>CR_FW_OUTREGISTRY_INIT_SERV_DESC</code>) + * - The service types, sub-types and discriminant values defined in the + * <code>#CR_FW_OUTREGISTRY_INIT_SERV_DESC</code> initializer are consistent with + * service type, sub-types and discriminant values defined in the + * <code>#CR_FW_OUTCMP_INIT_KIND_DESC</code>. + * - The size of the InStream packet queue is greater than zero. + * - The size of the OutStream packet queue is greater than zero. + * - The size of the Pending OutComponent List (POCL) is greater than zero. + * . + * @return true if no errors are detected in the configuration data; + * false otherwise. + */ +CrFwBool_t CrFwAuxOutRegistryConfigCheck(); + +/** + * Check the configuration of the OutFactory component. + * The following checks are performed on the configuration data in + * <code>CrFwOutFactoryUserPar.h</code>: + * - CR_FW_OUTFACTORY_MAX_NOF_OUTCMP is greater than zero + * - CR_FW_OUTCMP_NKINDS is greater than zero + * - The service types are listed in increasing order in the service descriptor + * initializer (<code>CR_FW_OUTCMP_INIT_KIND_DESC</code>) + * - The service sub-types within a type are listed in increasing order in the service + * descriptor initializer (<code>CR_FW_OUTCMP_INIT_KIND_DESC</code>) + * - The discriminant values within a type/sub-type are listed in increasing order + * in the service descriptor initializer (<code>CR_FW_OUTCMP_INIT_KIND_DESC</code>) + * - The service types, sub-types and discriminant values defined in the + * <code>#CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer are consistent with + * service type, sub-types and discriminant values defined in the + * <code>#CR_FW_OUTREGISTRY_INIT_SERV_DESC</code>. + * - The packet lengths specified in <code>#CR_FW_OUTCMP_INIT_KIND_DESC</code> are + * greater than zero. + * . + * @return true if no errors are detected in the configuration data; + * false otherwise. + */ +CrFwBool_t CrFwAuxOutFactoryConfigCheck(); + +/** + * Check the configuration of the InCommand part of the InFactory component. + * The following checks are performed on the configuration data in + * <code>CrFwInFactoryUserPar.h</code>: + * - CR_FW_INFACTORY_MAX_NOF_INCMD is greater than zero + * - CR_FW_INCMD_NKINDS is greater than zero + * - The service types are listed in increasing order in the service descriptor + * initializer (<code>CR_FW_INCMD_INIT_KIND_DESC</code>) + * - The service sub-types within a type are listed in increasing order in the service + * descriptor initializer (<code>CR_FW_INCMD_INIT_KIND_DESC</code>) + * - The discriminant values within a type/sub-type are listed in increasing order + * in the service descriptor initializer (<code>CR_FW_INCMD_INIT_KIND_DESC</code>) + * - The values of the service types, sub-types and discriminant are lower than + * <code>#CR_FW_MAX_SERV_TYPE</code>, <code>#CR_FW_MAX_SERV_SUBTYPE</code> and + * <code>#CR_FW_MAX_DISCRIMINANT</code>. + * . + * @return true if no errors are detected in the configuration data; + * false otherwise. + */ +CrFwBool_t CrFwAuxInFactoryInCmdConfigCheck(); + +/** + * Check the configuration of the InReport part of the InFactory component. + * The following checks are performed on the configuration data in + * <code>CrFwInFactoryUserPar.h</code>: + * - CR_FW_INFACTORY_MAX_NOF_INREP is greater than zero + * - CR_FW_INREP_NKINDS is greater than zero + * - The service types are listed in increasing order in the service descriptor + * initializer (<code>CR_FW_INREP_INIT_KIND_DESC</code>) + * - The service sub-types within a type are listed in increasing order in the service + * descriptor initializer (<code>CR_FW_INREP_INIT_KIND_DESC</code>) + * - The discriminant values within a type/sub-type are listed in increasing order + * in the service descriptor initializer (<code>CR_FW_INREP_INIT_KIND_DESC</code>) + * - The values of the service types, sub-types and discriminant are lower than + * <code>#CR_FW_MAX_SERV_TYPE</code>, <code>#CR_FW_MAX_SERV_SUBTYPE</code> and + * <code>#CR_FW_MAX_DISCRIMINANT</code>. + * . + * @return true if no errors are detected in the configuration data; + * false otherwise. + */ +CrFwBool_t CrFwAuxInFactoryInRepConfigCheck(); + +#endif /* CRFW_AUX_H_ */ diff --git a/CrFramework/src/BaseCmp/CrFwBaseCmp.c b/CrFramework/src/BaseCmp/CrFwBaseCmp.c new file mode 100644 index 0000000000000000000000000000000000000000..b7460297b07ba5a686426ddd25d186ddc2b9c457 --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwBaseCmp.c @@ -0,0 +1,232 @@ +/** + * @file + * + * Implementation of Base State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "CrFwBaseCmp.h" +#include "CrFwInitProc.h" +#include "CrFwResetProc.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" +/* Include configuration files */ +#include "CrFwCmpData.h" + +/** The singleton instance of the Base State Machine. */ +static FwSmDesc_t baseCmpSmDesc = NULL; + +/** + * Function which runs the Component Initialization Procedure. + * This function is used as exit action for the CREATED state. + * @param smDesc the state machine descriptor + */ +static void RunCIP(FwSmDesc_t smDesc); + +/** + * Function which runs the Component Reset Procedure. + * This function is used as exit action for the INITIALIZED state. + * @param smDesc the state machine descriptor + */ +static void RunCRP(FwSmDesc_t smDesc); + +/** + * Function which starts the Component Execution Procedure. + * This function is used as entry action for the CONFIGURED state. + * @param smDesc the state machine descriptor + */ +static void StartCEP(FwSmDesc_t smDesc); + +/** + * Function which executes the Component Execution Procedure. + * This function is used as do-action for the CONFIGURED state. + * @param smDesc the state machine descriptor + */ +static void ExecCEP(FwSmDesc_t smDesc); + +/** + * Function which stops the Component Execution Procedure. + * This function is used as exit action for the CONFIGURED state. + * @param smDesc the state machine descriptor + */ +static void StopCEP(FwSmDesc_t smDesc); + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwBaseCmpMake() { + FwSmCounterS1_t nOfStates = 3; /* Number of states */ + FwSmCounterS1_t nOfChoicePseudoStates = 2; /* Number of choice pseudo-states */ + FwSmCounterS1_t nOfTrans = 9; /* Number of transitions */ + FwSmCounterS1_t nOfActions = 6; /* Number of actions */ + FwSmCounterS1_t nOfGuards = 1; /* Number of guards */ + FwSmCounterS1_t CPS_1 = 1; /* Identifier of first choice pseudo-state */ + FwSmCounterS1_t CPS_2 = 2; /* Identifier of second choice pseudo-state */ + + if (baseCmpSmDesc != NULL) + return baseCmpSmDesc; + + /* Create the base component state machine */ + baseCmpSmDesc = FwSmCreate(nOfStates, nOfChoicePseudoStates, nOfTrans, nOfActions, nOfGuards); + + /* Configure the base component state machine */ + FwSmAddState(baseCmpSmDesc, CR_FW_BASE_STATE_CREATED, 1, NULL, &RunCIP, NULL, NULL); + FwSmAddState(baseCmpSmDesc, CR_FW_BASE_STATE_INITIALIZED, 1, NULL, &RunCRP, NULL, NULL); + FwSmAddState(baseCmpSmDesc, CR_FW_BASE_STATE_CONFIGURED, 2, &StartCEP, &StopCEP, &ExecCEP, NULL); + FwSmAddChoicePseudoState(baseCmpSmDesc, CPS_1, 2); + FwSmAddChoicePseudoState(baseCmpSmDesc, CPS_2, 2); + FwSmAddTransIpsToSta(baseCmpSmDesc, CR_FW_BASE_STATE_CREATED, NULL); + FwSmAddTransStaToCps(baseCmpSmDesc, CR_FW_BASE_TR_INIT, CR_FW_BASE_STATE_CREATED, CPS_1, NULL, NULL); + FwSmAddTransCpsToSta(baseCmpSmDesc, CPS_1, CR_FW_BASE_STATE_INITIALIZED, NULL, &CrFwIsSmOutcomeOne); + FwSmAddTransCpsToSta(baseCmpSmDesc, CPS_1, CR_FW_BASE_STATE_CREATED, NULL, NULL); /* Else Transition */ + FwSmAddTransStaToCps(baseCmpSmDesc, CR_FW_BASE_TR_RESET, CR_FW_BASE_STATE_INITIALIZED, CPS_2, NULL, NULL); + FwSmAddTransCpsToSta(baseCmpSmDesc, CPS_2, CR_FW_BASE_STATE_CONFIGURED, NULL, &CrFwIsSmOutcomeOne); + FwSmAddTransCpsToSta(baseCmpSmDesc, CPS_2, CR_FW_BASE_STATE_INITIALIZED, NULL, NULL); /* Else Transition */ + FwSmAddTransStaToCps(baseCmpSmDesc, CR_FW_BASE_TR_RESET, CR_FW_BASE_STATE_CONFIGURED, CPS_2, &RunCRP, NULL); + FwSmAddTransStaToFps(baseCmpSmDesc, CR_FW_BASE_TR_SHUTDOWN, CR_FW_BASE_STATE_CONFIGURED, &CrFwBaseCmpDefShutdownAction, NULL); + + return baseCmpSmDesc; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwCmpInit(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, CR_FW_BASE_TR_INIT); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwCmpReset(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, CR_FW_BASE_TR_RESET); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwCmpShutdown(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, CR_FW_BASE_TR_SHUTDOWN); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwCmpExecute(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, FW_TR_EXECUTE); +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrDesc_t CrFwCmpGetInitPr(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return baseData->initProc; +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrDesc_t CrFwCmpGetResetPr(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return baseData->resetProc; +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrDesc_t CrFwCmpGetExecPr(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return baseData->execProc; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwInstanceId_t CrFwCmpGetInstanceId(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return baseData->instanceId; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwTypeId_t CrFwCmpGetTypeId(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return baseData->typeId; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwCmpIsStarted(FwSmDesc_t smDesc) { + return FwSmIsStarted(smDesc); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwCmpIsInCreated(FwSmDesc_t smDesc) { + return (FwSmGetCurState(smDesc) == CR_FW_BASE_STATE_CREATED); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwCmpIsInInitialized(FwSmDesc_t smDesc) { + return (FwSmGetCurState(smDesc) == CR_FW_BASE_STATE_INITIALIZED); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwCmpIsInConfigured(FwSmDesc_t smDesc) { + return (FwSmGetCurState(smDesc) == CR_FW_BASE_STATE_CONFIGURED); +} + +/*-----------------------------------------------------------------------------------------*/ +static void RunCIP(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + FwPrRun(baseData->initProc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void RunCRP(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + FwPrRun(baseData->resetProc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void StartCEP(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + FwPrStart(baseData->execProc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void StopCEP(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + FwPrStop(baseData->execProc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void ExecCEP(FwSmDesc_t smDesc) { + CrFwCmpData_t* baseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + FwPrExecute(baseData->execProc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwBaseCmpDefShutdownAction(FwSmDesc_t smDesc) { + CRFW_UNUSED(smDesc); + return; +} + + + diff --git a/CrFramework/src/BaseCmp/CrFwBaseCmp.h b/CrFramework/src/BaseCmp/CrFwBaseCmp.h new file mode 100644 index 0000000000000000000000000000000000000000..de8ca0518021ed7ab47a177d6aa948ab8b89c22e --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwBaseCmp.h @@ -0,0 +1,221 @@ +/** + * @file + * @ingroup baseCmpGroup + * Definition of Base Component. + * A Base Component implements the behaviour of the Base State Machine + * (see figures below). + * + * All components used in the framework are derived from the Base Component + * (i.e. all framework components are implemented by state machines which are + * derived from the Base State Machine). + * Hence, all framework components inherit the behaviour of the Base + * State Machine. + * + * The Base State Machine is a singleton. + * This header file defines the operation to create and access this singleton + * instance. + * + * A Base State Machine responds to three transition commands: Init, + * Reset and Shutdown. + * This header file defines functions to send these three commands to a Base Component + * or to one of its derived components. + * + * The Base State Machine uses three procedures, the + * Component Initialization Procedure, the Component Reset Procedure, + * and the Component Execution Procedure. + * The first two procedures are defined in <code>CrFwInitProc.h</code> and + * <code>CrFwResetProc</code>. + * The third procedure is defined as a dummy in <code>CrFwExecProc.h</code>. + * + * The Base Component defines the Instance Identifier and Type Identifier + * attributes. + * The Type Identifier identifies the type of a component. + * The Instance Identifier identifies an instance within a type. + * This module defines the functions to access the type and instance identifier of + * a Base Component or of a component derived from a Base Component. + * + * @image html BaseSM.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_BASE_CMP_H_ +#define CRFW_BASE_CMP_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Retrieve the singleton instance of the Base State Machine. + * The Base State Machine is a singleton. + * The first time this function is called, it creates the Base State Machine. + * Subsequently, it always returns the same instance. + * + * The first time this function is called, it returns the Base State Machine + * in state STOPPED. + * @return the descriptor of the Base State Machine or NULL + * if the state machine could not be created. + */ +FwSmDesc_t CrFwBaseCmpMake(); + +/** + * Initialize a framework component. + * This function sends command Init to a Base State Machine. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine to be initialized. + */ +void CrFwCmpInit(FwSmDesc_t smDesc); + +/** + * Reset a framework component. + * This function sends command Reset to a Base State Machine. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine to be reset. + */ +void CrFwCmpReset(FwSmDesc_t smDesc); + +/** + * Shutdown a framework component. + * This function sends command Shutdown to a Base State Machine. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine to be shutdown. + */ +void CrFwCmpShutdown(FwSmDesc_t smDesc); + +/** + * Execute a framework component. + * This function sends command Execute to a Base State Machine. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine to be executed. + */ +void CrFwCmpExecute(FwSmDesc_t smDesc); + +/** + * Function which performs the Shutdown Action for the Base State Machine. + * This implementation of the Shutdown Action returns without doing anything. + * + * This action is an adaptation point of the framework. + * Components which extend the Base Component may want to override this function + * to implement their own shutdown behaviour. + * @param smDesc the descriptor of the Base State Machine. + */ +void CrFwBaseCmpDefShutdownAction(FwSmDesc_t smDesc); + +/** + * Return the descriptor of the Initialization Procedure of the argument component. + * Each component derived from the Base Component has an Initialization Procedure. + * This function returns the descriptor of the Initialization Procedure of the + * argument component. + * @param smDesc the descriptor of the Base State Machine. + * @return the descriptor of the Initialization Procedure + */ +FwPrDesc_t CrFwCmpGetInitPr(FwSmDesc_t smDesc); + +/** + * Return the descriptor of the Reset Procedure of the argument component. + * Each component derived from the Base Component has a Reset Procedure. + * This function returns the descriptor of the Reset Procedure of the + * argument component. + * @param smDesc the descriptor of the Base State Machine. + * @return the descriptor of the Reset Procedure + */ +FwPrDesc_t CrFwCmpGetResetPr(FwSmDesc_t smDesc); + +/** + * Return the descriptor of the Execution Procedure of the argument component. + * Each component derived from the Base Component has an Execution Procedure. + * This function returns the descriptor of the Execution Procedure of the + * argument component. + * @param smDesc the descriptor of the Base State Machine. + * @return the descriptor of the Reset Procedure + */ +FwPrDesc_t CrFwCmpGetExecPr(FwSmDesc_t smDesc); + +/** + * Return the instance identifier of the argument component. + * Each component derived from the Base Component has an Instance Identifier + * which identifies a certain instance of a component within all instances of + * the same type. + * This function returns the value of the Instance Identifier. + * @param smDesc the descriptor of the Base State Machine. + * @return the instance identifier + */ +CrFwInstanceId_t CrFwCmpGetInstanceId(FwSmDesc_t smDesc); + +/** + * Return the type identifier of the argument component. + * Each component belongs to a type. + * This function returns the value of the Type Identifier. + * @param smDesc the descriptor of the Base State Machine. + * @return the instance identifier + */ +CrFwTypeId_t CrFwCmpGetTypeId(FwSmDesc_t smDesc); + +/** + * Return true if the state machine of the argument component has been started. + * This function checks whether the Base State Machine has been started. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine. + * @return 1 if the argument state machine has been started; 0 otherwise + */ +CrFwBool_t CrFwCmpIsStarted(FwSmDesc_t smDesc); + +/** + * Return true if the argument component is in state CREATED. + * This function checks whether the Base State Machine is in state CREATED. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine. + * @return 1 if the argument state machine is in state CREATED; 0 otherwise + */ +CrFwBool_t CrFwCmpIsInCreated(FwSmDesc_t smDesc); + +/** + * Return true if the argument component is in state INITIALIZED. + * This function checks whether the Base State Machine is in state INITIALIZED. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine. + * @return 1 if the argument state machine is in state INITIALIZED; 0 otherwise + */ +CrFwBool_t CrFwCmpIsInInitialized(FwSmDesc_t smDesc); + +/** + * Return true if the argument component is in state CONFIGURED. + * This function checks whether the Base State Machine is in state CONFIGURED. + * This function can be used either on a Base State Machine or on a state + * machine that has been derived from a Base State Machine. + * @param smDesc the descriptor of the Base State Machine. + * @return 1 if the argument state machine is in state CONFIGURED; 0 otherwise + */ +CrFwBool_t CrFwCmpIsInConfigured(FwSmDesc_t smDesc); + +#endif /* CRFW_BASE_CMP_H_ */ diff --git a/CrFramework/src/BaseCmp/CrFwDummyExecProc.c b/CrFramework/src/BaseCmp/CrFwDummyExecProc.c new file mode 100644 index 0000000000000000000000000000000000000000..570e5627e39386d3cd774ce4f43a34a866bff4a2 --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwDummyExecProc.c @@ -0,0 +1,73 @@ +/** + * @file + * + * Implementation of Dummy Component Execution Procedure. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +#include "CrFwInitProc.h" +#include "CrFwBaseCmp.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* FW Profile Files */ +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** The singleton instance of the CIP. */ +static FwPrDesc_t dummyExecPrDesc = NULL; + +/* ----------------------------------------------------------------------------------------------------------------- */ +void CwFwBaseCmpDummyExecAction(FwPrDesc_t prDesc) { + CRFW_UNUSED(prDesc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrDesc_t CrFwBaseCmpGetDummyExecProc() { + const FwPrCounterS1_t nOfANodes = 1; /* Number of action nodes */ + const FwPrCounterS1_t nOfDNodes = 0; /* Number of decision nodes */ + const FwPrCounterS1_t nOfFlows = 2; /* Number of control flows */ + const FwPrCounterS1_t nOfActions = 1; /* Number of actions */ + const FwPrCounterS1_t nOfGuards = 1; /* Number of guards */ + const FwPrCounterS1_t N1 = 1; /* Identifier of first action node */ + + if (dummyExecPrDesc != NULL) + return dummyExecPrDesc; + + /* Create the execution procedure */ + dummyExecPrDesc = FwPrCreate(nOfANodes, nOfDNodes, nOfFlows, nOfActions, nOfGuards); + + /* Configure the initialization procedure */ + FwPrAddActionNode(dummyExecPrDesc, N1, &CwFwBaseCmpDummyExecAction); + FwPrAddFlowIniToAct(dummyExecPrDesc, N1, NULL); + FwPrAddFlowActToAct(dummyExecPrDesc, N1, N1, &CrFwWaitOnePrCycle); + + return dummyExecPrDesc; +} + + + + + diff --git a/CrFramework/src/BaseCmp/CrFwDummyExecProc.h b/CrFramework/src/BaseCmp/CrFwDummyExecProc.h new file mode 100644 index 0000000000000000000000000000000000000000..dfa7d6019f8229b44adee38904acad7cd18f0118 --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwDummyExecProc.h @@ -0,0 +1,69 @@ +/** + * @file + * @ingroup baseCmpGroup + * Dummy Component Execution Procedure (CEP) for the Base Component. + * The CEP is one of the procedures which implement the behaviour of the + * Base Component (see <code>CrFwBaseCmp.h</code>). + * This procedure is an adaptation point in the Base Component. + * The implementation provided in this file is the default defined + * at the level of the Base Component. + * Components which extend the Base Component may override it and define + * their own implementation. + * + * The CORDET Framework does not define a generic CEP. + * This implementation therefore defines a dummy CEP which can be used + * by components which do not need a CEP. + * This dummy CEP (see figure below) has one single action node which + * executes a dummy action every time the procedure is executed. + * The dummy action can be overridden. + * + * The Dummy CEP (like the Base Component) is a singleton. + * This header file gives access to the singleton instance of the Dummy CEP. + * + * @image html DummyExecution.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_DUMMY_EXEC_PROC_H_ +#define CRFW_DUMMY_EXEC_PROC_H_ + +#include "FwSmConstants.h" +#include "FwPrConstants.h" +#include "CrFwConstants.h" + +/** + * Retrieve the singleton instance of the Dummy CEP. + * This function returns the descriptor of the Dummy CEP. + * Note that no data are attached to the descriptor as it is returned by this + * function. + * @return the descriptor of the CEP or NULL if the procedure could not be created. + */ +FwPrDesc_t CrFwBaseCmpGetDummyExecProc(); + +/** + * Dummy action executed in the single node of the Dummy Execution Procedure. + * This dummy action returns without doing anything. + * @param prDesc the procedure descriptor + */ +void CwFwBaseCmpDummyExecAction(FwPrDesc_t prDesc); + +#endif /* CRFW_DUMMY_EXEC_PROC_H_ */ diff --git a/CrFramework/src/BaseCmp/CrFwInitProc.c b/CrFramework/src/BaseCmp/CrFwInitProc.c new file mode 100644 index 0000000000000000000000000000000000000000..2b314596ce70f45eb299b95dce4cf73c1dee9cf1 --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwInitProc.c @@ -0,0 +1,91 @@ +/** + * @file + * + * Implementation of Component Initialization Procedure. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include framework files */ +#include "CrFwInitProc.h" +#include "CrFwBaseCmp.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* Include configuration files */ +#include "CrFwCmpData.h" +/* Include FW Profile files */ +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** The singleton instance of the CIP. */ +static FwPrDesc_t initPrDesc = NULL; + +/*-----------------------------------------------------------------------------------------*/ +void CrFwBaseCmpDefInitCheck(FwPrDesc_t prDesc) { + CrFwCmpData_t* prData = (CrFwCmpData_t*)FwPrGetData(prDesc); + prData->outcome = 1; + return; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwBaseCmpDefInitAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* prData = (CrFwCmpData_t*)FwPrGetData(prDesc); + prData->outcome = 1; + return; +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrDesc_t CrFwCmpGetInitProc() { + const FwPrCounterS1_t nOfANodes = 2; /* Number of action nodes */ + const FwPrCounterS1_t nOfDNodes = 1; /* Number of decision nodes */ + const FwPrCounterS1_t nOfFlows = 5; /* Number of control flows */ + const FwPrCounterS1_t nOfActions = 2; /* Number of actions */ + const FwPrCounterS1_t nOfGuards = 1; /* Number of guards */ + const FwPrCounterS1_t N1 = 1; /* Identifier of first action node */ + const FwPrCounterS1_t N2 = 2; /* Identifier of second action node */ + const FwPrCounterS1_t D1 = 1; /* Identifier of first decision node */ + + if (initPrDesc != NULL) + return initPrDesc; + + /* Create the initialization procedure */ + initPrDesc = FwPrCreate(nOfANodes, nOfDNodes, nOfFlows, nOfActions, nOfGuards); + + /* Configure the initialization procedure */ + FwPrAddActionNode(initPrDesc, N1, &CrFwBaseCmpDefInitCheck); + FwPrAddActionNode(initPrDesc, N2, &CrFwBaseCmpDefInitAction); + FwPrAddDecisionNode(initPrDesc, D1, 2); + FwPrAddFlowIniToAct(initPrDesc, N1, NULL); + FwPrAddFlowActToDec(initPrDesc, N1, D1, NULL); + FwPrAddFlowDecToAct(initPrDesc, D1, N2, &CrFwIsPrOutcomeOne); + FwPrAddFlowDecToFin(initPrDesc, D1, NULL); /* Else branch */ + FwPrAddFlowActToFin(initPrDesc, N2, NULL); + + return initPrDesc; +} + + + + + diff --git a/CrFramework/src/BaseCmp/CrFwInitProc.h b/CrFramework/src/BaseCmp/CrFwInitProc.h new file mode 100644 index 0000000000000000000000000000000000000000..06fe20d36a1df98add5b371efa44f5ffa8a83cfd --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwInitProc.h @@ -0,0 +1,125 @@ +/** + * @file + * @ingroup baseCmpGroup + * Component Initialization Procedure (CIP) for the Base Component. + * The CIP is one of the procedures which implement the behaviour of the + * Base Component (see <code>CrFwBaseCmp.h</code>). + * The CIP is shown as an activity diagram in the left-hand side of the + * figure below. + * + * The CIP (like the Base Component) is a singleton. + * This header file gives access to the singleton instance of the CIP. + * This header file also gives access to the functions which implement the + * two actions of the CIP. + * These actions represent adaptation points of the framework and they are + * therefore made externally accessible so that derived component may override + * them. + * + * All components derived from the Base Component need an own version of + * the CIP. + * They obtain it by extending the CIP instance defined in this file. + * @image html InitializationAndReset.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INIT_PROC_H_ +#define CRFW_INIT_PROC_H_ + +#include "FwSmConstants.h" +#include "FwPrConstants.h" +#include "CrFwConstants.h" + +/** + * Retrieve the singleton instance of the CIP. + * This function returns the descriptor of the CIP. + * Note that no data are attached to the descriptor as it is returned by this + * function. + * The CIP descriptor returned by this function is therefore not ready to be + * executed. + * It can only be executed after the procedure data have been loaded into it. + * @return the descriptor of the CIP or NULL if the procedure could not be created. + */ +FwPrDesc_t CrFwCmpGetInitProc(); + +/** + * Function which performs the default Initialization Check of the CIP. + * This function implements one of the actions of the CIP. + * In general, the Initialization Check for a component checks that all + * parameters required for the component initialization have legal values. + * + * The Initialization Check has an outcome. + * This function assumes the procedure data to be of type <code>::CrFwCmpData_t</code>. + * It uses the <code>outcome</code> field of this data structure to store the + * outcome of the initialization check. + * If the outcome of the Initialization Check is "check successful", then the + * outcome field is set equal to 1. + * If the outcome of the Initialization Check is "check failed", then the + * outcome field is set equal to 0. + * + * This function implements the Initialization Check for the Base Component which + * always returns an outcome of "check successful" (i.e. always sets the outcome field to 1). + * + * This action is an adaptation point for the framework. + * Components which extend the Base Component (and which therefore must also extend + * the CIP) may want to override this function to implement their own initialization + * behaviour). + * @param prDesc the CIP descriptor + */ +void CrFwBaseCmpDefInitCheck(FwPrDesc_t prDesc); + +/** + * Function which performs the default Initialization Action of the CIP. + * This function implements one of the actions of the CIP. + * In general, the Initialization Action for a component creates all data structures + * required by the component and performs other initialization actions as required. + * + * The Initialization Action has an outcome. + * This function assumes the procedure data to be of type <code>::CrFwCmpData_t</code>. + * It uses the <code>outcome</code> field of this data structure to store the + * outcome of the initialization action. + * If the outcome of the Initialization Action is "action successful", then the + * outcome field is set equal to 1. + * If the outcome of the Initialization Action is "action failed", then the + * outcome field is set equal to 0. + * + * This function assumes the procedure data to be of type <code>::CrFwCmpData_t</code>. + * It uses the <code>outcome</code> field of this data structure to store the + * outcome of the initialization action (a value of "true" means that the + * initialization action was successful). + * + * This function implements the Initialization Action for the Base Component + * which does nothing and always returns an outcome of "action successful" (i.e. + * always sets the outcome field to 1). + * + * This action is an adaptation point of the framework. + * Components which extend the Base Component (and which therefore must also extend + * the CIP) may want to override this function to implement their own initialization + * behaviour). + * + * Traceability information (this information is intended to be processed automatically): + * - CrFwBaseCmpDefInitCheck, AP, A4.1-2 + * . + * @param prDesc the CIP descriptor + */ +void CrFwBaseCmpDefInitAction(FwPrDesc_t prDesc); + +#endif /* CRFW_INIT_PROC_H_ */ diff --git a/CrFramework/src/BaseCmp/CrFwResetProc.c b/CrFramework/src/BaseCmp/CrFwResetProc.c new file mode 100644 index 0000000000000000000000000000000000000000..d269488fd028102d80546051223938fae1abab3f --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwResetProc.c @@ -0,0 +1,88 @@ +/** + * @file + * + * Implementation of Component Reset Procedure. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +#include "CrFwResetProc.h" +#include "CrFwBaseCmp.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" +#include "CrFwCmpData.h" + +/** The singleton instance of the CRP. */ +static FwPrDesc_t resetPrDesc = NULL; + +/*-----------------------------------------------------------------------------------------*/ +void CrFwBaseCmpDefConfigCheck(FwPrDesc_t prDesc) { + CrFwCmpData_t* prData = (CrFwCmpData_t*)FwPrGetData(prDesc); + prData->outcome = 1; + return; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwBaseCmpDefConfigAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* prData = (CrFwCmpData_t*)FwPrGetData(prDesc); + prData->outcome = 1; + return; +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrDesc_t CrFwCmpGetResetProc() { + FwPrCounterS1_t nOfANodes = 2; /* Number of action nodes */ + FwPrCounterS1_t nOfDNodes = 1; /* Number of decision nodes */ + FwPrCounterS1_t nOfFlows = 5; /* Number of control flows */ + FwPrCounterS1_t nOfActions = 2; /* Number of actions */ + FwPrCounterS1_t nOfGuards = 1; /* Number of guards */ + FwPrCounterS1_t N1 = 1; /* Identifier of first action node */ + FwPrCounterS1_t N2 = 2; /* Identifier of second action node */ + FwPrCounterS1_t D1 = 1; /* Identifier of first decision node */ + + if (resetPrDesc != NULL) + return resetPrDesc; + + /* Create the initialization procedure */ + resetPrDesc = FwPrCreate(nOfANodes, nOfDNodes, nOfFlows, nOfActions, nOfGuards); + + /* Configure the initialization procedure */ + FwPrAddActionNode(resetPrDesc, N1, &CrFwBaseCmpDefConfigCheck); + FwPrAddActionNode(resetPrDesc, N2, &CrFwBaseCmpDefConfigAction); + FwPrAddDecisionNode(resetPrDesc, D1, 2); + FwPrAddFlowIniToAct(resetPrDesc, N1, NULL); + FwPrAddFlowActToDec(resetPrDesc, N1, D1, NULL); + FwPrAddFlowDecToAct(resetPrDesc, D1, N2, &CrFwIsPrOutcomeOne); + FwPrAddFlowDecToFin(resetPrDesc, D1, NULL); /* Else branch */ + FwPrAddFlowActToFin(resetPrDesc, N2, NULL); + + return resetPrDesc; +} + + + + + diff --git a/CrFramework/src/BaseCmp/CrFwResetProc.h b/CrFramework/src/BaseCmp/CrFwResetProc.h new file mode 100644 index 0000000000000000000000000000000000000000..314ab9f441287c303aa8518aa851141307075817 --- /dev/null +++ b/CrFramework/src/BaseCmp/CrFwResetProc.h @@ -0,0 +1,109 @@ +/** + * @file + * @ingroup baseCmpGroup + * Component Reset Procedure (CRP) for the Base Component. + * The CRP is one of the procedures which implement the behaviour of the + * Base Component (see <code>CrFwBaseCmp.h</code>). + * The CRP is shown as an activity diagram in the right-hand side of the + * figure below. + * + * The CRP (like the Base Component) is a singleton. + * This header file gives access to the singleton instance of the CRP. + * This header file also gives access to the functions which implement the + * two actions of the CRP. + * These actions represent adaptation points of the framework and they are + * therefore made externally accessible so that derived component may override + * them. + * + * All components derived from the Base Component need an own version of + * the CRP. + * They obtain it by extending the CRP instance defined in this file. + * @image html InitializationAndReset.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_RESET_PROC_H_ +#define CRFW_RESET_PROC_H_ + +#include "FwSmConstants.h" +#include "FwPrConstants.h" +#include "CrFwConstants.h" + +/** + * Retrieve the singleton instance of the CRP. + * This function returns the descriptor of the CRP. + * Note that no data are attached to the descriptor as it is returned by this + * function. + * The CRP descriptor returned by this function is therefore not ready to be + * executed. + * It can only be executed after the procedure data have been loaded into it. + * @return the descriptor of the CRP or NULL if the procedure could not be created. + */ +FwPrDesc_t CrFwCmpGetResetProc(); + +/** + * Function which performs the default Configuration Check of the CRP. + * This function implements one of the actions of the CRP. + * In general, the Configuration Check for a component checks that all + * parameters required for the component configuration have legal values. + * + * This function assumes the procedure data to be of type <code>::CrFwCmpData_t</code>. + * It uses the <code>outcome</code> field of this data structure to store the + * outcome of the configuration check. + * + * This function implements the Configuration Check for the Base Component + * which always returns an outcome of "check successful" (i.e. always sets the + * outcome check to TRUE). + * + * This action is an adaptation point for the framework. + * Components which extend the Base Component (and which therefore must also extend + * the CRP) may want to override this function to implement their own configuration + * behaviour). + * @param prDesc the CIP descriptor + */ +void CrFwBaseCmpDefConfigCheck(FwPrDesc_t prDesc); + +/** + * Function which performs the default Configuration Action of the CRP. + * This function implements one of the actions of the CRP. + * In general, the Configuration Action for a component initializes all data structures + * required by the component and performs other configuration actions as required. + * The configuration action has an outcome: it can either succeed or it can fail. + * + * This function assumes the procedure data to be of type <code>::CrFwCmpData_t</code>. + * It uses the <code>outcome</code> field of this data structure to store the + * outcome of the configuration action (a value of "true" means that the configuration + * action was successful). + * + * This function implements the Configuration Action for the Base Component + * which does nothing and always returns an outcome of "action successful" (i.e. + * always sets the outcome check to TRUE). + * + * This action is an adaptation point of the framework. + * Components which extend the Base Component (and which therefore must also extend + * the CRP) may want to override this function to implement their own configuration + * behaviour). + * @param prDesc the CRP descriptor + */ +void CrFwBaseCmpDefConfigAction(FwPrDesc_t prDesc); + +#endif /* CRFW_RESET_PROC_H_ */ diff --git a/CrFramework/src/CrFwConstants.h b/CrFramework/src/CrFwConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..6f219ce39df7ae3e9d3b026134dec03e767e47a3 --- /dev/null +++ b/CrFramework/src/CrFwConstants.h @@ -0,0 +1,628 @@ +/** + * @file + * Header file to define all invariant publicly available constants and types for the CORDET Framework. + * The invariant constants and types are those which are not intended to be + * modified by the user during the framework instantiation process. + * User-configurable constant and types are defined in <code>CrFwUserConstants.h</code>. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_CONSTANTS_H_ +#define CRFW_CONSTANTS_H_ + +#include "FwPrConstants.h" +#include "FwSmConstants.h" +#include "CrFwUserConstants.h" + +/** A macro that can be used to specify that a function parameter is not used */ +#define CRFW_UNUSED(x) (void)(x); + +/** Type used for boolean values (1 represent "true" and 0 represents "false"). */ +typedef int CrFwBool_t; + +/** Type for the index of a command or report in the InRegistry or OutRegistry. */ +typedef unsigned short CrFwCmdRepIndex_t; + +/** Type for packets (see <code>CrFwPckt.h</code>). Packets are treated as arrays of bytes. */ +typedef char* CrFwPckt_t; + +/** Enumerated type for command and reports */ +typedef enum { + /** Command type */ + crCmdType = 1, + /** Report type */ + crRepType = 2 +} CrFwCmdRepType_t; + +/** + * Type for a pointer to a function implementing the Update Action Operation for + * an InReport. + * The Update Action Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InReport descriptor + * as an argument and returns <code>void</code>. + */ +typedef void (*CrFwInRepUpdateAction_t)(FwPrDesc_t); + +/** + * Type for a pointer to a function implementing the Validity Check Operation for + * an InReport. + * The Validity Check Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InReport descriptor + * as an argument and returns true if the data in the InReport packet are valid + * and returns false otherwise. + */ +typedef CrFwBool_t (*CrFwInRepValidityCheck_t)(FwPrDesc_t); + +/** + * Type for a pointer to a function implementing the Validity Check Operation for + * an InReport. + * The Validity Check Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InReport procedure descriptor + * as an argument and returns true if the data in the InReport packet are valid + * and returns false otherwise. + */ +typedef CrFwBool_t (*CrFwInCmdValidityCheck_t)(FwPrDesc_t); + +/** + * Type for a pointer to a function implementing the Ready Check Operation for an + * InCommand. + * The Ready Check Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InCommand descriptor + * as an argument and returns true if the command is ready to start execution and + * false otherwise. + */ +typedef CrFwBool_t (*CrFwInCmdReadyCheck_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Start Action Operation for + * an InCommand. + * The Start Action Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InCommand descriptor + * as an argument and returns <code>void</code>. + * The Start Action has an outcome which it records in field <code>outcome</code> + * of <code>::CrFwCmpData_t</code>. + * The outcome is either '1' (to signify that the action was successful) or + * an integer different from '1' (to signify that the action failed -- + * in this case the outcome is a code which identifies the reason for the failure). + */ +typedef void (*CrFwInCmdStartAction_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Progress Action Operation for + * an InCommand. + * The Progress Action Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InCommand descriptor + * as an argument and returns <code>void</code>. + * The Progress Action has an outcome which it records in field <code>outcome</code> + * of <code>::CrFwCmpData_t</code>. + * The outcome is either '2' (to signify that command execution can continue), or + * '1' (to signify that command execution has been completed), or an integer different from + * '1' and '2' (to signify that the action failed -- in this case the outcome is + * a code which identifies the reason for the failure). + */ +typedef void (*CrFwInCmdProgressAction_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Termination Action Operation for + * an InCommand. + * The Termination Action Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InCommand descriptor + * as an argument and returns <code>void</code>. + * The Termination Action has an outcome which it records in field <code>outcome</code> + * of <code>::CrFwCmpData_t</code>. + * The outcome is either '1' (to signify that the action was successful) or + * an integer different from '1' (to signify that the action failed -- + * in this case the outcome is a code which identifies the reason for the failure). + */ +typedef void (*CrFwInCmdTerminationAction_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Abort Action Operation for + * an InCommand. + * The Abort Action Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the InCommand descriptor + * as an argument and returns <code>void</code>. + */ +typedef void (*CrFwInCmdAbortAction_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Enable Check Operation for an + * OutComponent. + * The Enable Check Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the OutComponent descriptor + * as an argument and returns true if the packet encapsulated by the OutComponent + * is enabled and false otherwise. + */ +typedef CrFwBool_t (*CrFwOutCmpEnableCheck_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Ready Check Operation for an + * OutComponent. + * The Ready Check Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the OutComponent descriptor + * as an argument and returns true if the packet encapsulated by the OutComponent + * is ready to be sent out and false otherwise. + */ +typedef CrFwBool_t (*CrFwOutCmpReadyCheck_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Repeat Check Operation for an + * OutComponent. + * The Repeat Check Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the OutComponent descriptor + * as an argument and returns true if the OutComponent must be sent to its destination + * again and false otherwise. + */ +typedef CrFwBool_t (*CrFwOutCmpRepeatCheck_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Update Operation for an + * OutComponent. + * This operation is one of the adaptation points of the framework. + * The operation updates the data which the OutComponent must carry to its + * destination. + * A function which implements this operation takes the OutComponent descriptor + * as an argument and returns void. + */ +typedef void (*CrFwOutCmpUpdate_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Serialize Operation for an + * OutComponent. + * This operation serializes the OutComponent to the packet associated to the + * OutComponent (see <code>::CrFwOutCmpData_t</code>). + * A function which implements this operation takes the OutComponent descriptor + * as an argument and returns void. + */ +typedef void (*CrFwOutCmpSerialize_t)(FwSmDesc_t); + +/** + * Type for a pointer to a function implementing the Packet Collect Operation of + * an InStream. + * The Packet Collect Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the packet source as its argument and + * returns a packet collected from the middleware interface associated to the packet + * source or NULL if no packet could be collected. + * The packet returned by this function must be created through function + * <code>::CrFwPcktMake</code> (release of the packet is the responsibility of the + * user of the InStream). + * + * If there is a need to verify whether a packet is available for collection through + * the Packet Collect Operation, this can be done using the Packet Available Check Operation. + * + */ +typedef CrFwPckt_t (*CrFwPcktCollect_t)(CrFwDestSrc_t); + +/** + * Type for a pointer to a function implementing the Packet Available Check Operation + * of an InStream. + * The Packet Available Check Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the packet source as its argument and + * returns 1 if a new packet is available at the middleware interface associated to the packet + * source or 0 if no packet is available. + * Hence, a return value of 1 implies that a call to the Packet Collect Operation will return + * one packet. + */ +typedef CrFwBool_t (*CrFwPcktAvailCheck_t)(CrFwDestSrc_t); + +/** + * Type for a pointer to a function implementing the Packet Hand-Over Operation of + * an OutStream. + * The Packet Hand-Over Operation is one of the adaptation points of the framework. + * A function which implements this operation takes the packet to be handed over + * to the middleware as an argument and returns either 1 if the hand-over was successful + * or 0 if the hand-over failed. + * + * The function must not modify the content of the packet. + * The argument of the function is a pointer to the packet. + * This pointer is "owned" by the caller and the function should not use after it has + * returned. + */ +typedef CrFwBool_t (*CrFwPcktHandover_t)(CrFwPckt_t pckt); + +/** Descriptor for a Packet Queue (PQ) in an OutStream or InStream. */ +struct CrFwPcktQueue { + /** The list of packets in the PQ. */ + CrFwPckt_t* pckt; + /** The size of the PQ (the same as the size of the <code>pckt</code> array) */ + CrFwCounterU1_t size; + /** The index of the oldest item in the PQ */ + CrFwCounterU1_t oldestItem; + /** Index of the next free slot in the PQ. */ + CrFwCounterU1_t nextFreeItem; + /** Flag indicating whether the PQ is empty */ + CrFwBool_t isEmpty; +}; + +/** Type used in the framework to represent a packet queue */ +typedef struct CrFwPcktQueue* CrFwPcktQueue_t; + +/** + * InReport kind descriptor type. + * An application supports a number of InReport kinds. + * An instance of this type describes one of the InReport kinds supported by an application. + */ +typedef struct { + /** The service type */ + CrFwServType_t servType; + /** The service sub-type */ + CrFwServSubType_t servSubType; + /** The discriminant value (or zero if no discriminant for this type/sub-type) */ + CrFwDiscriminant_t discriminant; + /** The pointer to the function implementing the Update Action Operation */ + CrFwInRepUpdateAction_t updateAction; + /** The pointer to the function implementing the Validity Check Operation */ + CrFwInRepValidityCheck_t isValid; + /** Component kind key (the product of: service type, service sub-type, and discriminant) */ + CrFwCmdRepKindKey_t kindKey; +} CrFwInRepKindDesc_t; + +/** + * InCommand kind descriptor type. + * An application supports a number of InCommand kinds. + * An instance of this type describes one of the InCommand kinds supported by an application. + */ +typedef struct { + /** The service type */ + CrFwServType_t servType; + /** The service sub-type */ + CrFwServSubType_t servSubType; + /** The discriminant value (or zero if no discriminant for this type/sub-type) */ + CrFwDiscriminant_t discriminant; + /** The pointer to the function implementing the Validity Check Operation */ + CrFwInCmdValidityCheck_t isValid; + /** The pointer to the function implementing the Ready Check Operation */ + CrFwInCmdReadyCheck_t isReady; + /** The pointer to the function implementing the Start Action Operation */ + CrFwInCmdStartAction_t startAction; + /** The pointer to the function implementing the Progress Action Operation */ + CrFwInCmdProgressAction_t progressAction; + /** The pointer to the function implementing the Termination Action Operation */ + CrFwInCmdTerminationAction_t terminationAction; + /** The pointer to the function implementing the Abort Action Operation */ + CrFwInCmdAbortAction_t abortAction; +} CrFwInCmdKindDesc_t; + +/** + * OutComponent kind descriptor type. + * An application supports a number of OutComponent kinds. + * An instance of this type describes one of the OutComponent kinds supported by an application. + */ +typedef struct { + /** The service type */ + CrFwServType_t servType; + /** The service sub-type */ + CrFwServSubType_t servSubType; + /** The discriminant value (or zero if no discriminant for this type/sub-type) */ + CrFwDiscriminant_t discriminant; + /** The command/report type of the out-going command or report */ + CrFwCmdRepType_t cmdRepType; + /** The length of the packet attached to the OutComponent */ + CrFwPcktLength_t pcktLength; + /** The pointer to the function implementing the Enable Check Operation */ + CrFwOutCmpEnableCheck_t isEnabled; + /** The pointer to the function implementing the Ready Check Operation */ + CrFwOutCmpReadyCheck_t isReady; + /** The pointer to the function implementing the Ready Check Operation */ + CrFwOutCmpRepeatCheck_t isRepeat; + /** The pointer to the function implementing the Update Operation */ + CrFwOutCmpUpdate_t update; + /** The pointer to the function implementing the Serialize Operation */ + CrFwOutCmpSerialize_t serialize; +} CrFwOutCmpKindDesc_t; + +/** + * Service descriptor type. + * An application supports a number of service types and, for each service type, it supports + * a number of sub-types. + * An instance of this type describes one of the [service type, service sub-type] pairs supported + * by an application. + */ +typedef struct { + /** The service type */ + CrFwServType_t servType; + /** The service sub-type */ + CrFwServSubType_t servSubType; + /** The maximum value of the discriminant (or zero if no discriminant for this type/sub-type) */ + CrFwDiscriminant_t maxDiscriminant; + /** Index of the next service type or zero when this is the last service type */ + CrFwCmdRepIndex_t nextServType; + /** The enable state for the service type (see <code>CrFwOutRegistry.h</code>) */ + CrFwBool_t isServTypeEnabled; + /** The enable state for the service sub-type (see <code>CrFwOutRegistry.h</code>) */ + CrFwBool_t isServSubTypeEnabled; + /** + * The enable state for the discriminant values (see <code>CrFwOutRegistry.h</code>). + * This is intended to be an array of bits such that each bit represents a discriminant + * value for the type/sub-type. + * If the bit is equal to 1, the discriminant value is enabled; otherwise it is disabled. + */ + unsigned char* isDiscriminantEnabled; +} CrFwServDesc_t; + +/** Type for the data describing an InManager */ +typedef struct InManagerData { + /** Pending Command/Report List (PCRL) for the InManager. */ + FwSmDesc_t* pcrl; + /** Number of successfully loaded InReports and InCommands */ + CrFwCounterU2_t nOfLoadedInCmp; + /** Number of InReports and InCommands currently in PCRL */ + CrFwCounterU1_t nOfInCmpInPcrl; + /** + * Next free position in the PCRL. + * This is the position at which the next InReport/InCommand loaded into the InManager + * will be inserted in the PCRL. + * If the PCRL is full, this field is equal to the PCRL size. + */ + CrFwCounterU1_t nextFreePcrlPos; +} CrFwInManagerData_t; + +/** Type for the data describing an OutManager */ +typedef struct OutManagerData { + /** Pending OutComponent List (POCL) for the OutManager. */ + FwSmDesc_t* pocl; + /** Number of successfully loaded OutComponents */ + CrFwCounterU2_t nOfLoadedOutCmp; + /** Number of OutComponents currently in POCL */ + CrFwCounterU1_t nOfOutCmpInPocl; + /** + * Next free position in the POCL. + * This is the position at which the next OutComponent loaded into the OutManager + * will be inserted in the POCL. + * If the POCL is full, this field is equal to the POCL size. + */ + CrFwCounterU1_t nextFreePoclPos; +} CrFwOutManagerData_t; + +/** Type for the data describing an InLoader */ +typedef struct InLoaderData { + /** InStream from which packets are to be retrieved in the next execution cycle. */ + FwSmDesc_t inStream; +} CrFwInLoaderData_t; + +/** Type for the data describing an InStream */ +typedef struct InStreamData { + /** Source associated to the InStream. */ + CrFwDestSrc_t src; + /** Packet queue associated to the InStream. */ + struct CrFwPcktQueue pcktQueue; + /** Array holding sequence counters for the groups associated to the InStream */ + CrFwSeqCnt_t* seqCnt; + /** Function which implements the Packet Collect Operation. */ + CrFwPcktCollect_t collectPckt; + /** Function which implements the Packet Available Check Operation. */ + CrFwPcktAvailCheck_t isPcktAvail; + /** The last packet to have been collected from the middleware */ + CrFwPckt_t pckt; +} CrFwInStreamData_t; + +/** Type for the data describing an OutStream */ +typedef struct OutStreamData { + /** Destination associated to the OutStream. */ + CrFwDestSrc_t dest; + /** Packet queue associated to the OutStream. */ + struct CrFwPcktQueue pcktQueue; + /** Array holding sequence counters for the groups associated to the OutStream */ + CrFwSeqCnt_t* seqCnt; + /** Function which hands over a packet from the OutStream to the middleware. */ + CrFwPcktHandover_t handoverPckt; + /** The packet to be sent out */ + CrFwPckt_t pckt; +} CrFwOutStreamData_t; + +/** Type for the data describing an InCommand */ +typedef struct InCmdData { + /** + * Index of the position in the pool of pre-allocated InCommands in the InFactory + * to which the InComponent has been allocated + */ + CrFwInFactoryPoolIndex_t factoryPoolIndex; + /** + * Index through which an InCommand is tracked by the InRegistry + * (see <code>CrFwInRegistry.h</code>) + */ + CrFwTrackingIndex_t trackingIndex; + /** Function which implements the Configuration Check for the InCommand */ + CrFwInCmdValidityCheck_t isValid; + /** Function which implements the Ready Check for the InCommand */ + CrFwInCmdReadyCheck_t isReady; + /** Function which implements the Start Action for the InCommand */ + CrFwInCmdStartAction_t startAction; + /** Function which implements the Progress Action for the InCommand */ + CrFwInCmdProgressAction_t progressAction; + /** Function which implements the Termination Action for the InCommand */ + CrFwInCmdTerminationAction_t terminationAction; + /** Function which implements the Abort Action for the InCommand */ + CrFwInCmdAbortAction_t abortAction; + /** Packet holding the InCommand */ + CrFwPckt_t pckt; +} CrFwInCmdData_t; + +/** Type for the data describing an InReport */ +typedef struct InRepData { + /** + * Index of the position in the pool of pre-allocated InReports in the InFactory + * to which the InComponent has been allocated + */ + CrFwInFactoryPoolIndex_t factoryPoolIndex; + /** + * Index through which an InReport is tracked by the InRegistry + * (see <code>CrFwInRegistry.h</code>) + */ + CrFwTrackingIndex_t trackingIndex; + /** Function which implements the Validity Check for the InReport */ + CrFwInRepValidityCheck_t isValid; + /** Function which implements the Update Action for the InReport */ + CrFwInRepUpdateAction_t updateAction; + /** Packet holding the InReport */ + CrFwPckt_t pckt; +} CrFwInRepData_t; + +/** Type for the data describing an OutComponent */ +typedef struct OutCmpData { + /** Index of out-going command or report (see <code>CrFwOutRegistry.h</code>) */ + CrFwCmdRepIndex_t index; + /** + * Index of the position in the pool of pre-allocated OutComponents in the OutFactory + * to which the OutComponent has been allocated + */ + CrFwOutFactoryPoolIndex_t factoryPoolIndex; + /** + * Index through which an out-going command or report is tracked by the OutRegistry + * (see <code>CrFwOutRegistry.h</code>) + */ + CrFwTrackingIndex_t trackingIndex; + /** Function which implements the Enable Check for the out-going command or report */ + CrFwOutCmpEnableCheck_t isEnabled; + /** Function which implements the Ready Check for the out-going command or report */ + CrFwOutCmpReadyCheck_t isReady; + /** Function which implements the Repeat Check for the out-going command or report */ + CrFwOutCmpRepeatCheck_t isRepeat; + /** Function which implements the Update Operation for the out-going command or report */ + CrFwOutCmpUpdate_t update; + /** Function which implements the Serialization Operation for the out-going command or report */ + CrFwOutCmpSerialize_t serialize; + /** Packet to which the out-going command or report is serialized */ + CrFwPckt_t pckt; +} CrFwOutCmpData_t; + +/** Type identifier for the OutStream components */ +#define CR_FW_OUTSTREAM_TYPE 1 + +/** Type identifier for the InStream components */ +#define CR_FW_INSTREAM_TYPE 2 + +/** Type identifier for the OutComponent components */ +#define CR_FW_OUTCMP_TYPE 3 + +/** Type identifier for the OutRegistry component */ +#define CR_FW_OUTREGISTRY_TYPE 4 + +/** Type identifier for the OutFactory component */ +#define CR_FW_OUTFACTORY_TYPE 5 + +/** Type identifier for the OutManager component */ +#define CR_FW_OUTMANAGER_TYPE 6 + +/** Type identifier for the OutLoader component */ +#define CR_FW_OUTLOADER_TYPE 7 + +/** Type identifier for the InFactory component */ +#define CR_FW_INFACTORY_TYPE 8 + +/** Type identifier for the InReport component */ +#define CR_FW_INREPORT_TYPE 9 + +/** Type identifier for the InCommand component */ +#define CR_FW_INCOMMAND_TYPE 10 + +/** Type identifier for the OutRegistry component */ +#define CR_FW_INREGISTRY_TYPE 11 + +/** Type identifier for the InManager component */ +#define CR_FW_INMANAGER_TYPE 12 + +/** Type identifier for the InLoader component */ +#define CR_FW_INLOADER_TYPE 13 + +/** Type identifier for the Application State Machine */ +#define CR_FW_APP_TYPE 14 + +/* -------------------------------------------------------------------------------------------------- */ + +/** Maximum number of transition commands defined on a framework component or framework state machine */ +#define CR_FW_MAX_NOF_TRANS_CMDS 4 + +/** State identifier for state CREATED in the Base State Machine. */ +#define CR_FW_BASE_STATE_CREATED 1 + +/** State identifier for state INITIALIZED in the Base State Machine. */ +#define CR_FW_BASE_STATE_INITIALIZED 2 + +/** State identifier for state CONFIGURED in the Base State Machine. */ +#define CR_FW_BASE_STATE_CONFIGURED 3 + +/** Identifier for transition command "Init" in the Base State Machine. */ +#define CR_FW_BASE_TR_INIT 1 + +/** Identifier for transition command "Reset" in the Base State Machine. */ +#define CR_FW_BASE_TR_RESET 2 + +/** Identifier for transition command "Shutdown" in the Base State Machine. */ +#define CR_FW_BASE_TR_SHUTDOWN 3 + +/** State identifier for state ACCEPTED in the InCommand State Machine. */ +#define CR_FW_INCMD_STATE_ACCEPTED 1 + +/** State identifier for state PROGRESS in the InCommand State Machine. */ +#define CR_FW_INCMD_STATE_PROGRESS 2 + +/** State identifier for state TERMINATED in the InCommand State Machine. */ +#define CR_FW_INCMD_STATE_TERMINATED 3 + +/** State identifier for state ABORTED in the InCommand State Machine. */ +#define CR_FW_INCMD_STATE_ABORTED 4 + +/** Identifier for transition command "Terminate" in the InCommand State Machine. */ +#define CR_FW_INCMD_TR_TERMINATE CR_FW_INCOMMAND_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+0 + +/** State identifier for state WAITING in the InStream State Machine. */ +#define CR_FW_INSTREAM_STATE_WAITING 1 + +/** State identifier for state PCKT_AVAIL in the InStream State Machine. */ +#define CR_FW_INSTREAM_STATE_PCKT_AVAIL 2 + +/** Identifier for transition command "GetPacket" in the InStream State Machine. */ +#define CR_FW_INSTREAM_TR_GET_PCKT CR_FW_INSTREAM_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+0 + +/** Identifier for transition command "PacketAvailable" in the InStream State Machine. */ +#define CR_FW_INSTREAM_TR_PACKET_AVAILABLE CR_FW_INSTREAM_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+1 + +/** State identifier for state LOADED in the OutComponent State Machine. */ +#define CR_FW_OUTCMP_STATE_LOADED 1 + +/** State identifier for state ABORTED in the OutComponent State Machine. */ +#define CR_FW_OUTCMP_STATE_ABORTED 2 + +/** State identifier for state PENDING in the OutComponent State Machine. */ +#define CR_FW_OUTCMP_STATE_PENDING 3 + +/** State identifier for state TERMINATED the OutComponent State Machine. */ +#define CR_FW_OUTCMP_STATE_TERMINATED 4 + +/** Identifier for transition command "Terminate" in the OutComponent State Machine. */ +#define CR_FW_OUTCMP_TR_TERMINATE CR_FW_OUTCMP_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+0 + +/** State identifier for state READY in the OutStream State Machine. */ +#define CR_FW_OUTSTREAM_STATE_READY 1 + +/** State identifier for state INITIALIZED in the OutStream State Machine. */ +#define CR_FW_OUTSTREAM_STATE_BUFFERING 2 + +/** Identifier for transition command "Send" in the OutStream State Machine. */ +#define CR_FW_OUTSTREAM_TR_SEND CR_FW_OUTSTREAM_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+0 + +/** Identifier for transition command "Reset" in the OutStream State Machine. */ +#define CR_FW_OUTSTREAM_TR_CONNECTION_AVAILABLE CR_FW_OUTSTREAM_TYPE*CR_FW_MAX_NOF_TRANS_CMDS+1 + +#endif /* CRFW_CONSTANTS_H_ */ diff --git a/CrFramework/src/CrFwRepErr.h b/CrFramework/src/CrFwRepErr.h new file mode 100644 index 0000000000000000000000000000000000000000..0c6ce885f709ecf9d3073e3f3e5e216d5e13df0e --- /dev/null +++ b/CrFramework/src/CrFwRepErr.h @@ -0,0 +1,157 @@ +/** + * @file + * @ingroup crOpenIfGroup + * Interface for reporting an error detected by a framework component. + * When a framework component encounters an error, it reports it by calling one of + * the functions defined by this header file (error report). + * + * An error report is defined by the following attributes: + * - The error code: a positive integer which identifies the type of + * error. + * - The source type identifier: the type identifier of the component which + * generated the error report. + * - The source instance identifier: the instance identifier of the component + * which generated the error report. + * - The error parameters: any additional parameters which are useful to + * characterize the circumstances in which the error arose. + * . + * The type and number of error parameters depends on the type of error which is being + * reported. + * This interface defines several error reporting functions, one for each set of + * error parameter types. + * + * In general, the implementation of this interface is entirely application-specific + * but a simple default implementation is provided in <code>CrFwRepErr.c</code>. + * This default implementation is primarily intended for testing and demonstration + * purposes. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_REPERR_H_ +#define CRFW_REPERR_H_ + +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Report an error which has no parameters attached to it. + * This function generate an error report without error parameters. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + */ +void CrFwRepErr(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId); + +/** + * Report an error which has one single parameter attached to it representing a command + * or report destination or source. + * This function generate an error report with one parameter. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + * @param destSrc the invalid destination or source + */ +void CrFwRepErrDestSrc(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, + CrFwDestSrc_t destSrc); + +/** + * Report an error which has one single parameter attached to it representing a command + * or report group. + * This function generate an error report with one parameter. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + * @param group the invalid group + */ +void CrFwRepErrGroup(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, + CrFwGroup_t group); + +/** + * Report an error which has two parameters attached to it representing expected and + * actual sequence counter values. + * This function generate an error report with two parameters. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + * @param expSeqCnt the expected sequence counter + * @param actSeqCnt the actual sequence counter + */ +void CrFwRepErrSeqCnt(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, + CrFwSeqCnt_t expSeqCnt, CrFwSeqCnt_t actSeqCnt); + +/** + * Report an error which has two parameters attached to it representing the instance identifier + * of a component other than the originator of the error report (the secondary instance + * identifier) and the outcome field of a component's data. + * This function generate an error report with two parameters. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + * @param secondaryInstanceId instance identifier of a component other than the originator of the error + * report + * @param outcome outcome field of a component's data + */ +void CrFwRepErrInstanceIdAndOutcome(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, + CrFwInstanceId_t instanceId, CrFwInstanceId_t secondaryInstanceId, CrFwOutcome_t outcome); + +/** + * Report an error which has two parameters attached to it representing the instance identifier + * of a component other than the originator of the error report (the secondary instance + * identifier) and a command or report destination. + * This function generate an error report with two parameters. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + * @param secondaryInstanceId instance identifier of a component other than the originator of the error + * report + * @param dest a command or report destination + */ +void CrFwRepErrInstanceIdAndDest(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, + CrFwInstanceId_t instanceId, CrFwInstanceId_t secondaryInstanceId, CrFwDestSrc_t dest); + +/** + * Report an error which has one parameter attached to it representing a command or report packet. + * This function generate an error report with one parameter. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + * @param pckt a packet holding a command or report + */ +void CrFwRepErrPckt(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, + CrFwInstanceId_t instanceId, CrFwPckt_t pckt); + +/** + * Report an error which has one parameter attached to it representing an report component. + * This function generate an error report with one parameter. + * @param errCode the error code + * @param instanceId the instance identifier of the component which raises the error report + * @param typeId the type identifier of the component which raises the error report + * @param rep the component holding the report which triggered the error + */ +void CrFwRepErrRep(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, + CrFwInstanceId_t instanceId, FwSmDesc_t rep); + + +#endif /* CRFW_REPERR_H_ */ diff --git a/CrFramework/src/CrFwRepInCmdOutcome.h b/CrFramework/src/CrFwRepInCmdOutcome.h new file mode 100644 index 0000000000000000000000000000000000000000..c41d93e312314fc882d17be5f9cf51f645e8b830 --- /dev/null +++ b/CrFramework/src/CrFwRepInCmdOutcome.h @@ -0,0 +1,162 @@ +/** + * @file + * @ingroup crOpenIfGroup + * Interface for reporting the outcome of the processing of an InCommand. + * The InCommand arrives at the framework interface as a packet. + * Its processing can have one of the following outcomes: + * - Creation Failure: the InCommand cannot be created because there aren't + * enough memory resources + * - Acceptance Failure: the command has failed its Acceptance Check + * - Acceptance Success: the command has been accepted + * - Start Failure: the Start Action of the command has failed + * - Start Success: the Start Action of the command has been successful + * - Progress Failure: the Progress Action of the command has failed + * - Progress Success: the Progress Action of the command has been successful + * - Termination Failure: the Termination Action of the command has failed + * - Termination Success: the Termination Action of the command has been successful + * . + * The command outcome is reported either by the InLoader or by the InCommand itself. + * This interface declares functions through which these components can report the + * outcome of an InCommand. + * + * The InCommand outcome report generated by the functions declared in this file + * is defined by the following attributes: + * - The outcome type: a positive integer which identifies the type of + * outcome. + * - The instance identifier: the instance identifier of the InCommand whose + * outcome is being reported. + * - The service type: the service type of the InCommand whose + * outcome is being reported. + * - The service sub-type: the service sub-type of the InCommand whose + * outcome is being reported. + * - The discriminant: the discriminant of the InCommand whose + * outcome is being reported. + * - The failure code: an integer parameter which identifies the type of failure + * (only applicable for 'failed' outcomes). + * - The InCommand component representing the command whose outcome is being reported + * - The packet carrying the InCommand (only for the case that the InCommand could not + * be created). + * . + * In general, the implementation of this interface is entirely application-specific + * but a simple default implementation is provided in <code>CrFwInCmdOutcome.c</code>. + * This default implementation is primarily intended for testing and demonstration + * purposes. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_REPINCMDOUTCOME_H_ +#define CRFW_REPINCMDOUTCOME_H_ + +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Enumerated type for the outcome of the processing of an incoming command. + * An incoming command goes through several processing stages. + * At the end of each stage, an outcome report is generated by either function + * <code>::CrFwRepInCmdOutcome</code> or <code>::CrFwRepInCmdOutcomeCreFail</code>. + * The outcome of the processing of the incoming command is determined as follows: + * - The InLoader (see <code>CrFwBaseCmp.h</code>) receives the packet encapsulating the + * incoming command and attempts to create an InCommand component to hold the command. + * If the attempt fails (either because there are not enough resources to build the + * InCommand or because its type/sub-type/discriminant are not recognized), the + * processing of the InCommand is terminated with outcome "Creation Failure" + * - If the InCommand was successfully created, the InLoader checks whether the InCommand + * was successfully configured. If this is not the case (because its content was invalid), + * its processing is terminated with outcome "Acceptance Failure". + * - If the InCommand was successfully configured, the InLoader attempts to load it in an + * InManager (see <code>CrFwInManager.h</code>). If the load operation fails, the + * processing of the InCommand is terminaed with outcome "Load Failure". + * If, instead, the load operation succeeds, the outcome report "Acceptance Success" + * is generated. + * - When the execution of the InCommand starts, the InCommand performs a Start Check + * for the InCommand (see <code>CrFwInCmd.h</code>). Depending on the success or failure + * of this Start Check, an outcome of either "Start Success" or "Start Failure" is generated + * by the InCommand component. + * - When the execution of a step of the InCommand is completed, an outcome of either + * "Progress Success" or "Progress Failure" is generated by the InCommand component. + * - When the execution of a the InCommand has terminated, an outcome of either + * "Termination Success" or "Termination Failure" is generated by the InCommand component. + * . + */ +typedef enum { + /** Acceptance failure */ + crCmdAckAccFail = 1, + /** Acceptance success */ + crCmdAckAccSucc = 2, + /** Start failure */ + crCmdAckStrFail = 3, + /** Start success */ + crCmdAckStrSucc = 4, + /** Progress failure */ + crCmdAckPrgFail = 5, + /** Progress success */ + crCmdAckPrgSucc = 6, + /** Termination failure */ + crCmdAckTrmFail = 7, + /** Termination success */ + crCmdAckTrmSucc = 8, + /** Creation failure */ + crCmdAckCreFail = 9, + /** Load failure */ + crCmdAckLdFail = 10 +} CrFwRepInCmdOutcome_t; + +/** + * Report the outcome of the processing of an InCommand. + * The last parameter of this function is the InCommand whose outcome is being reported. + * This is a pointer variable. The owner of the pointer is the caller of the function. + * The function can use it in read-only mode to access the values of the command parameters. + * + * @param outcome the outcome of the InCommand processing + * @param instanceId the instance identifier of the InCommand + * @param servType the service type of the InCommand + * @param servSubType the service sub-type of the InCommand + * @param disc the discriminant of the InCommand + * @param failCode the failure code (don't care in case of a "successful" outcome) + * @param inCmd the InCommand component whose outcome is being reported + */ +void CrFwRepInCmdOutcome(CrFwRepInCmdOutcome_t outcome, CrFwInstanceId_t instanceId, CrFwServType_t servType, + CrFwServSubType_t servSubType, CrFwDiscriminant_t disc, CrFwOutcome_t failCode, FwSmDesc_t inCmd); + +/** + * Report the a "creation failure" outcome for the processing of a packet carrying an InCommand. + * The "creation failure" outcome is declared when a packet carrying an InCommand is received + * but it is not possible to create an InCommand component to encapsulate it. + * The failure to create the InCommand may be due either to a lack of resources in the application or to + * the fact that the command kind as given by its [type, sub-type, discriminant] is illegal. + * The last parameter of this function is the packet which carries the incoming command for which no InCommand + * component could be created. + * This is a pointer variable. The owner of the pointer is the caller of the function. + * The function can use it in read-only mode to access the values of the command parameters. + * + * @param outcome the outcome of the packet processing (always equal to crCmdAckCreFail in + * this version of the framework) + * @param failCode the failure code + * @param pckt the packet carrying the InCommand + */ +void CrFwRepInCmdOutcomeCreFail(CrFwRepInCmdOutcome_t outcome, CrFwOutcome_t failCode, CrFwPckt_t pckt); + +#endif /* CRFW_REPINCMDOUTCOME_H_ */ diff --git a/CrFramework/src/CrFwTime.h b/CrFramework/src/CrFwTime.h new file mode 100644 index 0000000000000000000000000000000000000000..93812a6bec4bc097c5c1aaaa61cbf2d0160f126f --- /dev/null +++ b/CrFramework/src/CrFwTime.h @@ -0,0 +1,50 @@ +/** + * @file + * @ingroup crOpenIfGroup + * Interface through which framework components access the current time. + * Framework component need access to the current time to time-stamp out-going + * command and report packets. + * + * The implementation of this interface is entirely application-specific. + * A simple default implementation is provided in <code>CrFwTime.c</code>. + * This default implementation is primarily intended for testing and demonstration + * purposes. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_TIME_H_ +#define CRFW_TIME_H_ + +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Return the current time. + * This function generate an error report without error parameters. + * @return the current time. + */ +CrFwTimeStamp_t CrFwGetCurrentTime(); + +#endif /* CRFW_TIME_H_ */ diff --git a/CrFramework/src/InCmd/CrFwInCmd.c b/CrFramework/src/InCmd/CrFwInCmd.c new file mode 100644 index 0000000000000000000000000000000000000000..b6c7941d587a3ec77ae72ae2222d20b628381232 --- /dev/null +++ b/CrFramework/src/InCmd/CrFwInCmd.c @@ -0,0 +1,413 @@ +/** + * @file + * @ingroup inCmdGroup + * Implementation of OutComponent component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "OutStream/CrFwOutStream.h" +#include "OutCmp/CrFwOutCmp.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "OutFactory/CrFwOutFactory.h" +#include "Pckt/CrFwPckt.h" +#include "CrFwRepInCmdOutcome.h" +/* Include FW Profile files */ +#include "FwPrConfig.h" +#include "FwPrDCreate.h" +#include "FwSmConfig.h" +#include "FwSmDCreate.h" +#include "FwPrCore.h" + +/** Base OutComponent from which all other InCommands are derived. */ +static FwSmDesc_t baseInCmdSmDesc = NULL; + +/** + * Entry action in state ABORTED. + * @param smDesc the descriptor of the InCommand state machine + */ +static void DoAbortAction(FwSmDesc_t smDesc); + +/** + * Entry and do action in state PROGRESS. + * @param smDesc the descriptor of the InCommand state machine + */ +static void DoProgressAction(FwSmDesc_t smDesc); + +/** + * Transition action on the transition from ACCEPTED to CPS1. + * @param smDesc the descriptor of the InCommand state machine + */ +static void DoStartAction(FwSmDesc_t smDesc); + +/** + * Transition action on the transition from PROGRESS to CPS2. + * @param smDesc the descriptor of the InCommand state machine + */ +static void DoTerminationAction(FwSmDesc_t smDesc); + +/** + * Transition action on the transition from CPS1 to ABORTED which + * reports the failure of the Start Action. + * @param smDesc the descriptor of the InCommand state machine + */ +static void ReportStartFailed(FwSmDesc_t smDesc); + +/** + * Transition action on the transition from CPS2 to ABORTED which + * reports the failure of the Termination Action. + * @param smDesc the descriptor of the InCommand state machine + */ +static void ReportTerminationFailed(FwSmDesc_t smDesc); + +/** + * Transition action on the transition from CPS3 to ABORTED which + * reports the failure of the Progress Action. + * @param smDesc the descriptor of the InCommand state machine + */ +static void ReportProgressFailed(FwSmDesc_t smDesc); + +/** + * Transition action on the transition from CPS1 to PROGRESS. + * @param smDesc the descriptor of the InCommand state machine + */ +static void ReportStartSuccess(FwSmDesc_t smDesc); + +/** + * Transition action on the transition from CPS2 to TERMINATED. + * @param smDesc the descriptor of the InCommand state machine + */ +static void ReportTerminationSuccess(FwSmDesc_t smDesc); + +/** + * Guard on the transition from ACCEPTED to CPS1. + * @param smDesc the descriptor of the InCommand state machine + * @return the value of the Ready Check Operation of the InCommand + */ +static FwSmBool_t IsReady(FwSmDesc_t smDesc); + +/** + * Guard on transition from PROGRESS to ABORTED. + * @param smDesc the descriptor of the InCommand state machine + * @return 1 if the <code>outcome</code> field is different from 1 and 2; false otherwise. + */ +static FwSmBool_t IsSmOutcomeNotTwo(FwSmDesc_t smDesc); + +/* --------------------------------------------------------------------------------- */ +FwSmDesc_t CrFwInCmdMakeBase() { + FwSmCounterS1_t nOfStates = 4; /* Number of states */ + FwSmCounterS1_t nOfChoicePseudoStates = 2; /* Number of choice pseudo-states */ + FwSmCounterS1_t nOfTrans = 8; /* Number of transitions */ + FwSmCounterS1_t nOfActions = 9; /* Number of actions */ + FwSmCounterS1_t nOfGuards = 4; /* Number of guards */ + FwSmCounterS1_t CPS_1 = 1; /* Identifier of first choice pseudo-state */ + FwSmCounterS1_t CPS_2 = 2; /* Identifier of second choice pseudo-state */ + FwSmDesc_t esm; + + if (baseInCmdSmDesc != NULL) + return baseInCmdSmDesc; + + /* Create and configure the base InCommand */ + + /* Extend the Base Component */ + baseInCmdSmDesc = FwSmCreateDer(CrFwBaseCmpMake()); + /* Create the InCommand SM and then embed it in state CONFIGURED of the Base Component */ + esm = FwSmCreate(nOfStates, nOfChoicePseudoStates, nOfTrans, nOfActions, nOfGuards); + FwSmAddState(esm, CR_FW_INCMD_STATE_ACCEPTED, 1, NULL, NULL, NULL, NULL); + FwSmAddState(esm, CR_FW_INCMD_STATE_PROGRESS, 2, &DoProgressAction, NULL, &DoProgressAction, NULL); + FwSmAddState(esm, CR_FW_INCMD_STATE_TERMINATED, 0, NULL, NULL, NULL, NULL); + FwSmAddState(esm, CR_FW_INCMD_STATE_ABORTED, 0, &DoAbortAction, NULL, NULL, NULL); + FwSmAddChoicePseudoState(esm, CPS_1, 2); + FwSmAddChoicePseudoState(esm, CPS_2, 2); + FwSmAddTransIpsToSta(esm, CR_FW_INCMD_STATE_ACCEPTED, NULL); + FwSmAddTransStaToCps(esm, FW_TR_EXECUTE, CR_FW_INCMD_STATE_ACCEPTED, CPS_1, + &DoStartAction, &IsReady); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_INCMD_STATE_PROGRESS, &ReportStartSuccess, &CrFwIsSmOutcomeOne); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_INCMD_STATE_ABORTED, &ReportStartFailed, NULL); /* Else Guard */ + FwSmAddTransStaToCps(esm, CR_FW_INCMD_TR_TERMINATE, CR_FW_INCMD_STATE_PROGRESS, CPS_2, + &DoTerminationAction, &CrFwIsSmOutcomeOne); + FwSmAddTransStaToSta(esm, CR_FW_INCMD_TR_TERMINATE, CR_FW_INCMD_STATE_PROGRESS, CR_FW_INCMD_STATE_ABORTED, + &ReportProgressFailed, &IsSmOutcomeNotTwo); + FwSmAddTransCpsToSta(esm, CPS_2, CR_FW_INCMD_STATE_TERMINATED, &ReportTerminationSuccess, &CrFwIsSmOutcomeOne); + FwSmAddTransCpsToSta(esm, CPS_2, CR_FW_INCMD_STATE_ABORTED, &ReportTerminationFailed, NULL); /* Else Guard */ + + FwSmEmbed(baseInCmdSmDesc, CR_FW_BASE_STATE_CONFIGURED, esm); + return baseInCmdSmDesc; +} + +/* --------------------------------------------------------------------------------- */ +void CrFwInCmdTerminate(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, CR_FW_INCMD_TR_TERMINATE); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsInAccepted(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_INCMD_STATE_ACCEPTED); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsInProgress(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_INCMD_STATE_PROGRESS); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsInTerminated(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_INCMD_STATE_TERMINATED); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsInAborted(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_INCMD_STATE_ABORTED); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwInCmdConfigCheck(FwPrDesc_t prDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + if (cmpSpecificData->isValid(prDesc) == 1) + cmpData->outcome = 1; + else + cmpData->outcome = 0; +} + +/* --------------------------------------------------------------------------------- */ +FwSmCounterU3_t CrFwInCmdGetProgressStep(FwSmDesc_t smDesc) { + if (FwSmGetCurStateEmb(smDesc) == CR_FW_INCMD_STATE_PROGRESS) + return FwSmGetStateExecCnt(smDesc); + else + return 0; +} + + +/* --------------------------------------------------------------------------------- */ +FwSmBool_t IsReady(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return cmpSpecificData->isReady(smDesc); +} + +/* --------------------------------------------------------------------------------- */ +void ReportTerminationFailed(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + CrFwRepInCmdOutcome(crCmdAckTrmFail, cmpData->instanceId, + CrFwPcktGetServType(cmpSpecificData->pckt), + CrFwPcktGetServSubType(cmpSpecificData->pckt), + CrFwPcktGetDiscriminant(cmpSpecificData->pckt), + cmpData->outcome, smDesc); +} + +/* --------------------------------------------------------------------------------- */ +void ReportStartFailed(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + CrFwRepInCmdOutcome(crCmdAckStrFail, cmpData->instanceId, + CrFwPcktGetServType(cmpSpecificData->pckt), + CrFwPcktGetServSubType(cmpSpecificData->pckt), + CrFwPcktGetDiscriminant(cmpSpecificData->pckt), + cmpData->outcome, smDesc); +} + +/* --------------------------------------------------------------------------------- */ +void ReportProgressFailed(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + CrFwRepInCmdOutcome(crCmdAckPrgFail, cmpData->instanceId, + CrFwPcktGetServType(cmpSpecificData->pckt), + CrFwPcktGetServSubType(cmpSpecificData->pckt), + CrFwPcktGetDiscriminant(cmpSpecificData->pckt), + cmpData->outcome, smDesc); +} + +/* --------------------------------------------------------------------------------- */ +void ReportStartSuccess(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + if (CrFwPcktIsStartAck(cmpSpecificData->pckt) == 1) + CrFwRepInCmdOutcome(crCmdAckStrSucc, cmpData->instanceId, + CrFwPcktGetServType(cmpSpecificData->pckt), + CrFwPcktGetServSubType(cmpSpecificData->pckt), + CrFwPcktGetDiscriminant(cmpSpecificData->pckt), + cmpData->outcome, smDesc); +} + +/* --------------------------------------------------------------------------------- */ +void ReportTerminationSuccess(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + if (CrFwPcktIsTermAck(cmpSpecificData->pckt) == 1) + CrFwRepInCmdOutcome(crCmdAckTrmSucc, cmpData->instanceId, + CrFwPcktGetServType(cmpSpecificData->pckt), + CrFwPcktGetServSubType(cmpSpecificData->pckt), + CrFwPcktGetDiscriminant(cmpSpecificData->pckt), + cmpData->outcome, smDesc); +} + +/* --------------------------------------------------------------------------------- */ +static void DoAbortAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->abortAction(smDesc); +} + +/* --------------------------------------------------------------------------------- */ +static void DoProgressAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->progressAction(smDesc); + if (cmpData->outcome != 1) + if (cmpData->outcome != 2) + return; /* The Progress Action has failed */ + + if (CrFwPcktIsProgressAck(cmpSpecificData->pckt) == 1) + CrFwRepInCmdOutcome(crCmdAckPrgSucc, cmpData->instanceId, + CrFwPcktGetServType(cmpSpecificData->pckt), + CrFwPcktGetServSubType(cmpSpecificData->pckt), + CrFwPcktGetDiscriminant(cmpSpecificData->pckt), + cmpData->outcome, smDesc); +} + +/* --------------------------------------------------------------------------------- */ +static void DoStartAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->startAction(smDesc); +} + +/* --------------------------------------------------------------------------------- */ +static void DoTerminationAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->terminationAction(smDesc); +} + +/* --------------------------------------------------------------------------------- */ +static FwSmBool_t IsSmOutcomeNotTwo(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + if (cmpData->outcome != 2) + return 1; + + return 0; +} + +/* --------------------------------------------------------------------------------- */ +CrFwDestSrc_t CrFwInCmdGetSrc(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetSrc(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwGroup_t CrFwInCmdGetGroup(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetGroup(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwServType_t CrFwInCmdGetServType(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetServType(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwServType_t CrFwInCmdGetServSubType(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetServSubType(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwDiscriminant_t CrFwInCmdGetDiscriminant(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetDiscriminant(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsAcceptAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsAcceptAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsStartAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsStartAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsProgressAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsProgressAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwInCmdIsTermAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsTermAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwSeqCnt_t CrFwInCmdGetSeqCnt(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetSeqCnt(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +char* CrFwInCmdGetParStart(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetParStart(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwPcktLength_t CrFwInCmdGetParLength(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetParLength(cmpSpecificData->pckt); +} diff --git a/CrFramework/src/InCmd/CrFwInCmd.h b/CrFramework/src/InCmd/CrFwInCmd.h new file mode 100644 index 0000000000000000000000000000000000000000..fd8b54fb4bcbd5ba8adfbf122765395f4622825f --- /dev/null +++ b/CrFramework/src/InCmd/CrFwInCmd.h @@ -0,0 +1,244 @@ +/** + * @file + * @ingroup inMngGroup + * Definition of the InCommand Component of the framework. + * + * An InCommand encapsulates an incoming command in a service provider application. + * The InCommand is responsible for storing the attributes of an incoming command + * and for executing the conditional checks and actions associated to the command. + * The behaviour of an InCommand is defined by the InCommand State Machine + * (see figure below) embedded within state CONFIGURED of a Base Component State + * Machine. + * + * <b>Mode of Use of an InCommand Component</b> + * + * InCommands are created dynamically by the InLoader when it processes an incoming + * packet which holds a command. + * The InCommand component is created through a call to the factory function + * <code>::CrFwInFactoryMakeInCmd</code>. + * The InLoader loads the InCommand into an InManager who is then responsible for + * executing it and, eventually, for returning it to the InFactory. + * + * An InCommand encapsulates an incoming command of a certain kind. + * The "kind" of an incoming command is defined by the triplet: + * [service type, service sub-type, discriminant]. + * InCommands are adapted to a certain incoming command kind by modifying one + * or more of the following: + * - The Validity Check Operation + * - The Ready Check Operation + * - The Start Action Operation + * - The Progress Action Operation + * - The Termination Action Operation + * - The Abort Action Operation + * . + * These operations are statically defined for each kind of InCommand in + * <code>CrFwInFactoryUserPar.h</code>. + * + * This header file defines default values for all configurable operations listed + * above with the exception of the Configuration Check Operation for which the + * default is the function <code>::CrFwBaseCmpDefConfigCheck</code>. + * + * @image html InCommand.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INCMD_H_ +#define CRFW_INCMD_H_ + +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include configuration files */ +#include "Pckt/CrFwPcktQueue.h" +#include "CrFwUserConstants.h" +/* Include framework files */ +#include "CrFwConstants.h" + +/** + * Return the base InCommand from which all other InCommands are derived. + * The base InCommand is a singleton. + * The first time it is called, this function creates and configures the base InCommand instance. + * Subsequent calls return this same instance. + * This function is only intended to be used by the InFactory (see <code>CrFwInFactory.h</code>) + * and should not be used by applications. + * @return the singleton instance of the base InCommand + */ +FwSmDesc_t CrFwInCmdMakeBase(); + +/** + * Send command Terminate to the argument InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + */ +void CrFwInCmdTerminate(FwSmDesc_t smDesc); + +/** + * Return true if the argument InCommand is in state ACCEPTED. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if the argument InCommand is in state CONFIGURED, sub-state + * ACCEPTED; 0 otherwise + */ +CrFwBool_t CrFwInCmdIsInAccepted(FwSmDesc_t smDesc); + +/** + * Return true if the argument InCommand is in state PROGRESS. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if the argument InCommand is in state CONFIGURED, sub-state + * PROGRESS; 0 otherwise + */ +CrFwBool_t CrFwInCmdIsInProgress(FwSmDesc_t smDesc); + +/** + * Return true if the argument InCommand is in state TERMINATED. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if the argument InCommand is in state CONFIGURED, sub-state + * TERMINATED; 0 otherwise + */ +CrFwBool_t CrFwInCmdIsInTerminated(FwSmDesc_t smDesc); + +/** + * Return true if the argument InCommand is in state ABORTED. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if the argument InCommand is in state CONFIGURED, sub-state + * ABORTED; 0 otherwise + */ +CrFwBool_t CrFwInCmdIsInAborted(FwSmDesc_t smDesc); + +/** + * Configuration check for an InCommand. + * This function executes the Validity Check of the InCommand and sets the + * action outcome to 1 if the Validity Check returns true and sets it to + * zero if it returns false. + * This function is only intended to be used by the InFactory (see <code>CrFwInFactory.h</code>) + * and should not be used by applications. + * @param prDesc the descriptor of the InCommand Configuration Procedure + */ +void CrFwInCmdConfigCheck(FwPrDesc_t prDesc); + +/** + * Return the progress step of the InCommand. + * The progress step is equal to zero if the InCommand is in a state other than PROGRESS + * and is equal to the number of progress steps executed so far if the InCommand + * is in state PROGRESS. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the progress step + */ +FwSmCounterU3_t CrFwInCmdGetProgressStep(FwSmDesc_t smDesc); + +/** + * Return the source of the InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the source of the InCommand + */ +CrFwDestSrc_t CrFwInCmdGetSrc(FwSmDesc_t smDesc); + +/** + * Return the group of the InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the group of the InCommand + */ +CrFwGroup_t CrFwInCmdGetGroup(FwSmDesc_t smDesc); + +/** + * Return the type of the InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the type of the InCommand + */ +CrFwServType_t CrFwInCmdGetServType(FwSmDesc_t smDesc); + +/** + * Return the sub-type of the InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the sub-type of the InCommand + */ +CrFwServType_t CrFwInCmdGetServSubType(FwSmDesc_t smDesc); + +/** + * Return the discriminant of the InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the discriminant of the InCommand + */ +CrFwDiscriminant_t CrFwInCmdGetDiscriminant(FwSmDesc_t smDesc); + +/** + * Return the acknowledge level for command acceptance for the command encapsulated in the + * InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if command acceptance is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwInCmdIsAcceptAck(FwSmDesc_t smDesc); + +/** + * Return the acknowledge level for command start for the command encapsulated in the + * InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if command start is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwInCmdIsStartAck(FwSmDesc_t smDesc); + +/** + * Return the acknowledge level for command progress for the command encapsulated in the + * InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if command progress is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwInCmdIsProgressAck(FwSmDesc_t smDesc); + +/** + * Return the acknowledge level for command termination for the command encapsulated in the + * InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return 1 if command termination is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwInCmdIsTermAck(FwSmDesc_t smDesc); + +/** + * Return the sequence counter of the InCommand. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the sequence counter of the InCommand + */ +CrFwSeqCnt_t CrFwInCmdGetSeqCnt(FwSmDesc_t smDesc); + +/** + * Return the start address of the parameter area of the InCommand. + * The InCommand is encapsulated in a packet. + * The parameter area of the InCommand is the part of the packet which is reserved to the + * storage of the parameters of the InCommand. + * The parameter area consists of an uninterrupted sequence of bytes. + * The size of the parameter area is returned by function <code>::CrFwInCmdGetParLength</code>. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the start address of the InCommand parameter area. + */ +char* CrFwInCmdGetParStart(FwSmDesc_t smDesc); + +/** + * Return the length in bytes of the parameter area of the InCommand. + * The InCommand is encapsulated in a packet. + * The parameter area of the InCommand is the part of the packet which is reserved to the + * storage of the parameters of the InCommand. + * The parameter area consists of an uninterrupted sequence of bytes. + * The start address of the parameter area is returned by function <code>::CrFwInCmdGetParStart</code>. + * @param smDesc the descriptor of the Base State Machine of the InCommand + * @return the length in bytes of the InCommand parameter area + */ +CrFwPcktLength_t CrFwInCmdGetParLength(FwSmDesc_t smDesc); + +#endif /* CRFW_INCMD_H_ */ diff --git a/CrFramework/src/InFactory/CrFwInFactory.c b/CrFramework/src/InFactory/CrFwInFactory.c new file mode 100644 index 0000000000000000000000000000000000000000..5a9d4d824d408868ceec3f375fe84f6d888a61d2 --- /dev/null +++ b/CrFramework/src/InFactory/CrFwInFactory.c @@ -0,0 +1,547 @@ +/** + * @file + * + * Implementation of InFactory component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwInFactoryUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "OutCmp/CrFwOutCmp.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "InCmd/CrFwInCmd.h" +#include "InRep/CrFwInRep.h" +#include "InRep/CrFwInRepExecProc.h" +#include "InRegistry/CrFwInRegistry.h" +#include "CrFwInFactory.h" +/* Include FW Profile files */ +#include "FwPrConfig.h" +#include "FwPrDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwSmDCreate.h" +#include "FwPrCore.h" + +/** Array holding the keys of the InCommand kinds */ +static CrFwCmdRepKindKey_t inCmdKindKey[CR_FW_INCMD_NKINDS]; + +/** Array holding the keys of the InReport kinds */ +static CrFwCmdRepKindKey_t inRepKindKey[CR_FW_INREP_NKINDS]; + +/** Array of InCommand service descriptors (see <code>CrFwServDesc_t</code>). */ +static CrFwInCmdKindDesc_t inCmdKindDesc[CR_FW_INCMD_NKINDS] = CR_FW_INCMD_INIT_KIND_DESC; + +/** Array of InReport service descriptors (see <code>CrFwServDesc_t</code>). */ +static CrFwInRepKindDesc_t inRepKindDesc[CR_FW_INREP_NKINDS] = CR_FW_INREP_INIT_KIND_DESC; + +/** The pre-allocated InCommand instances */ +static FwSmDesc_t inCmd[CR_FW_INFACTORY_MAX_NOF_INCMD]; + +/** The pre-allocated InReport instances */ +static FwSmDesc_t inRep[CR_FW_INFACTORY_MAX_NOF_INREP]; + +/** The base data for the pre-allocated InCommand instances */ +static CrFwCmpData_t inCmdData[CR_FW_INFACTORY_MAX_NOF_INCMD]; + +/** The component-specific data for the pre-allocated InCommand instances */ +static CrFwInCmdData_t inCmdCmpSpecificData[CR_FW_INFACTORY_MAX_NOF_INCMD]; + +/** The base data for the pre-allocated InReport instances */ +static CrFwCmpData_t inRepData[CR_FW_INFACTORY_MAX_NOF_INREP]; + +/** The component-specific data for the pre-allocated InReport instances */ +static CrFwInRepData_t inRepCmpSpecificData[CR_FW_INFACTORY_MAX_NOF_INREP]; + +/** The in-use status of each pre-allocated InReport instance */ +static CrFwBool_t inRepInUse[CR_FW_INFACTORY_MAX_NOF_INREP]; + +/** The in-use status of each pre-allocated InCommand instance */ +static CrFwBool_t inCmdInUse[CR_FW_INFACTORY_MAX_NOF_INCMD]; + +/** The number of currently allocated InCommands */ +static CrFwInFactoryPoolIndex_t nOfAllocatedInCmd; + +/** The number of currently allocated InReports */ +static CrFwInFactoryPoolIndex_t nOfAllocatedInRep; + +/** + * The index of the next free position in the pool of pre-allocated InCommands + * instances (a value of <code>#CR_FW_INFACTORY_MAX_NOF_INCMD</code> indicates that all InCommand + * instances have been allocated and there are no free positions left) */ +static CrFwInFactoryPoolIndex_t nextInCmdFreePos; + +/** + * The index of the next free position in the pool of pre-allocated InReports + * instances (a value of <code>#CR_FW_INFACTORY_MAX_NOF_INREP</code> indicates that all InReport + * instances have been allocated and there are no free positions left) */ +static CrFwInFactoryPoolIndex_t nextInRepFreePos; + +/** The total number of InCommands or InCommand allocated since the InFactory was reset */ +static CrFwInstanceId_t nOfAllocatedInCmdSinceReset = 0; + +/** The total number of InReports or InCommand allocated since the InFactory was reset */ +static CrFwInstanceId_t nOfAllocatedInRepSinceReset = 0; + +/** The singleton instance of the InFactory */ +static FwSmDesc_t inFactory; + +/** The data for the InFactory singleton. */ +static CrFwCmpData_t inFactoryData; + +/** + * Initialization action for InFactory. + * This function: (a) allocates the memory for the InFactory data structures; + * (b) initializes the arrays of descriptors <code>::inCmdKindDesc</code> and + * <code>::inRepKindDesc</code>; and (c) initializes the component-specific + * field of the data structures for InCommands and InReports. + * The outcome of the initialization action is "success" in all cases except when + * a memory allocation operation fails. + * @param initPr the Initialization Procedure of the InFactory + */ +static void InFactoryInitAction(FwPrDesc_t initPr); + +/** + * Configuration action for InFactory. + * This function releases all the InCommands and InReports which are currently + * allocated. + * After this function has been called, any InCommand or InReport which is still in + * use within the application is no longer valid and should be discarded. + * + * This function also resets the counter used to initialize the instance + * identifiers of the InCommands and InReports created by the InFactory. + * After reset, the first InCommand or InReport made by the InFactory will have + * instance identifier set to 1. + * + * The outcome of the initialization action is always: "success" + * @param initPr the Initialization Procedure of the InFactory + */ +static void InFactoryConfigAction(FwPrDesc_t initPr); + +/** + * Shutdown action for InFactory. + * This function releases the memory which was allocated when the InFactory was + * initialized and it sets the number of allocated InCommands and InReports to zero. + * After this function has been called, any InCommand or InReport which is still in + * use within the application is no longer valid and should be discarded. + * @param smDesc the InFactory state machine + */ +static void InFactoryShutdownAction(FwSmDesc_t smDesc); + +/* ------------------------------------------------------------------------------------ */ +FwSmDesc_t CrFwInFactoryMake() { + FwPrDesc_t resetPr, execPr, initPr; + + if (inFactory != NULL) { + return inFactory; + } + + /* Extend the Base Component */ + inFactory = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the InFactory Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, &InFactoryConfigAction); + + /* Create the Initialization Procedure for the InFactory Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitAction, &InFactoryInitAction); + + /* Override the Shutdown Action for the InFactory Component */ + FwSmOverrideAction(inFactory, &CrFwBaseCmpDefShutdownAction, &InFactoryShutdownAction); + + /* Get the Dummy Execution Procedure for the InFactory Component */ + execPr = CrFwBaseCmpGetDummyExecProc(); + + /* Initialize the data for the requested SM */ + inFactoryData.outcome = 1; + inFactoryData.initProc = initPr; + inFactoryData.resetProc = resetPr; + inFactoryData.execProc = execPr; + inFactoryData.instanceId = 0; + inFactoryData.typeId = CR_FW_INFACTORY_TYPE; + + /* Attach the data to the InFactory state machine and to its procedures. */ + FwSmSetData(inFactory, &inFactoryData); + FwPrSetData(inFactoryData.initProc, &inFactoryData); + FwPrSetData(inFactoryData.resetProc, &inFactoryData); + + /* Start the InFactory */ + FwSmStart(inFactory); + + return inFactory; +} + +/* ------------------------------------------------------------------------------------ */ +FwSmDesc_t CrFwInFactoryMakeInCmd(CrFwPckt_t pckt) { + CrFwInFactoryPoolIndex_t j, k, freePos; + CrFwCmdRepKindIndex_t kindIndex; + CrFwCmdRepKindKey_t targetKey; + CrFwServType_t type; + CrFwServSubType_t subType; + CrFwDiscriminant_t discriminant; + + if (nextInCmdFreePos == CR_FW_INFACTORY_MAX_NOF_INCMD) { /* All positions are occupied */ + CrFwSetAppErrCode(crInCmdAllocationFail); + return NULL; + } + + type = CrFwPcktGetServType(pckt); + subType = CrFwPcktGetServSubType(pckt); + discriminant = CrFwPcktGetDiscriminant(pckt); + targetKey = (CrFwCmdRepKindKey_t)(type*CR_FW_MAX_DISCRIMINANT*CR_FW_MAX_SERV_SUBTYPE+subType*CR_FW_MAX_DISCRIMINANT+discriminant); + kindIndex = CrFwFindCmdRepKindIndex(inCmdKindKey, CR_FW_INCMD_NKINDS, targetKey); + if (kindIndex == CR_FW_INCMD_NKINDS) { + CrFwSetAppErrCode(crIllInCmdKind); + return NULL; + } + freePos = nextInCmdFreePos; + + inCmdData[freePos].instanceId = CrFwPcktGetCmdRepId(pckt); + + inCmdCmpSpecificData[freePos].abortAction = inCmdKindDesc[kindIndex].abortAction; + inCmdCmpSpecificData[freePos].startAction = inCmdKindDesc[kindIndex].startAction; + inCmdCmpSpecificData[freePos].progressAction = inCmdKindDesc[kindIndex].progressAction; + inCmdCmpSpecificData[freePos].terminationAction = inCmdKindDesc[kindIndex].terminationAction; + inCmdCmpSpecificData[freePos].isReady = inCmdKindDesc[kindIndex].isReady; + inCmdCmpSpecificData[freePos].isValid = inCmdKindDesc[kindIndex].isValid; + inCmdCmpSpecificData[freePos].factoryPoolIndex = freePos; + inCmdCmpSpecificData[freePos].pckt = pckt; + + /* Reset the InCommand */ + CrFwCmpReset(inCmd[freePos]); + + nOfAllocatedInCmd++; + inCmdInUse[freePos] = 1; + + /* Find the next free position in the pool of pre-allocated InCommand instances */ + k = (CrFwInFactoryPoolIndex_t)(freePos + 1); + for (j=0; j<(CR_FW_INFACTORY_MAX_NOF_INCMD-1); j++) { + if (k == CR_FW_INFACTORY_MAX_NOF_INCMD) + k = 0; + if (inCmdInUse[k] == 0) { + nextInCmdFreePos = k; + return (inCmd[freePos]); /* Next free position has been found */ + } + k = (CrFwInFactoryPoolIndex_t)(k + 1); + } + + nextInCmdFreePos = CR_FW_INFACTORY_MAX_NOF_INCMD; /* There are no free positions left */ + return (inCmd[freePos]); +} + +/* ------------------------------------------------------------------------------------ */ +FwSmDesc_t CrFwInFactoryMakeInRep(CrFwPckt_t pckt) { + CrFwInFactoryPoolIndex_t j, k, freePos; + CrFwCmdRepKindIndex_t kindIndex; + CrFwCmdRepKindKey_t targetKey; + CrFwServType_t type; + CrFwServSubType_t subType; + CrFwDiscriminant_t discriminant; + + if (nextInRepFreePos == CR_FW_INFACTORY_MAX_NOF_INREP) { /* All positions are occupied */ + CrFwSetAppErrCode(crInRepAllocationFail); + return NULL; + } + + type = CrFwPcktGetServType(pckt); + subType = CrFwPcktGetServSubType(pckt); + discriminant = CrFwPcktGetDiscriminant(pckt); + targetKey = (CrFwCmdRepKindKey_t)(type*CR_FW_MAX_DISCRIMINANT*CR_FW_MAX_SERV_SUBTYPE+subType*CR_FW_MAX_DISCRIMINANT+discriminant); + kindIndex = CrFwFindCmdRepKindIndex(inRepKindKey, CR_FW_INREP_NKINDS, targetKey); + if (kindIndex == CR_FW_INREP_NKINDS) { + CrFwSetAppErrCode(crIllInRepKind); + return NULL; + } + freePos = nextInRepFreePos; + + inRepCmpSpecificData[freePos].updateAction = inRepKindDesc[kindIndex].updateAction; + inRepCmpSpecificData[freePos].isValid = inRepKindDesc[kindIndex].isValid; + inRepCmpSpecificData[freePos].factoryPoolIndex = freePos; + inRepCmpSpecificData[freePos].pckt = pckt; + inRepData[freePos].instanceId = CrFwPcktGetCmdRepId(pckt); + + /* Reset the InReport */ + CrFwCmpReset(inRep[freePos]); + + nOfAllocatedInRep++; + inRepInUse[freePos] = 1; + + /* Find the next free position in the pool of pre-allocated InReport/InCommand instances */ + k = (CrFwInFactoryPoolIndex_t)(freePos + 1); + for (j=0; j<(CR_FW_INFACTORY_MAX_NOF_INREP-1); j++) { + if (k == CR_FW_INFACTORY_MAX_NOF_INREP) + k = 0; + if (inRepInUse[k] == 0) { + nextInRepFreePos = k; + return (inRep[freePos]); /* Next free position has been found */ + } + k = (CrFwInFactoryPoolIndex_t)(k + 1); + } + + nextInRepFreePos = CR_FW_INFACTORY_MAX_NOF_INREP; /* There are no free positions left */ + return (inRep[freePos]); +} + +/* ------------------------------------------------------------------------------------ */ +void CrFwInFactoryReleaseInCmd(FwSmDesc_t inCmdInstance) { + CrFwCmpData_t* inCmdInstanceData = (CrFwCmpData_t*)FwSmGetData(inCmdInstance); + CrFwInCmdData_t* cmpSpecificData = (CrFwInCmdData_t*)(inCmdInstanceData->cmpSpecificData); + CrFwInFactoryPoolIndex_t posToBeFreed; + + posToBeFreed = cmpSpecificData->factoryPoolIndex; + + if (inCmdInUse[posToBeFreed] == 1) { + inCmdInUse[posToBeFreed] = 0; + nOfAllocatedInCmd--; + nextInCmdFreePos = posToBeFreed; + CrFwPcktRelease(inCmdCmpSpecificData[posToBeFreed].pckt); + inCmdCmpSpecificData[posToBeFreed].pckt = NULL; + return; + } + CrFwSetAppErrCode(crInCmdRelErr); + + return; +} + +/* ------------------------------------------------------------------------------------ */ +void CrFwInFactoryReleaseInRep(FwSmDesc_t inRepInstance) { + CrFwCmpData_t* inRepInstanceData = (CrFwCmpData_t*)FwSmGetData(inRepInstance); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(inRepInstanceData->cmpSpecificData); + CrFwInFactoryPoolIndex_t posToBeFreed; + + posToBeFreed = cmpSpecificData->factoryPoolIndex; + + if (inRepInUse[posToBeFreed] == 1) { + inRepInUse[posToBeFreed] = 0; + nOfAllocatedInRep--; + nextInRepFreePos = posToBeFreed; + CrFwPcktRelease(inRepCmpSpecificData[posToBeFreed].pckt); + inRepCmpSpecificData[posToBeFreed].pckt = NULL; + return; + } + CrFwSetAppErrCode(crInRepRelErr); + + return; +} + +/* ------------------------------------------------------------------------------------ */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetNOfAllocatedInCmd() { + return nOfAllocatedInCmd; +} + +/* ------------------------------------------------------------------------------------ */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetMaxNOfInCmd() { + return CR_FW_INFACTORY_MAX_NOF_INCMD; +} + +/* ------------------------------------------------------------------------------------ */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetNOfAllocatedInRep() { + return nOfAllocatedInRep; +} + +/* ------------------------------------------------------------------------------------ */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetMaxNOfInRep() { + return CR_FW_INFACTORY_MAX_NOF_INREP; +} + +/*------------------------------------------------------------------------------------*/ +static void InFactoryInitAction(FwPrDesc_t initPr) { + CrFwCounterU2_t i; + CrFwCmdRepKindIndex_t j; + FwPrDesc_t inCmdInitPr, inCmdResetPr, inCmdExecPr; + FwPrDesc_t inRepInitPr, inRepResetPr, inRepExecPr; + CRFW_UNUSED(initPr); + + /* Create the pre-allocated InCommands */ + for (i=0; i<CR_FW_INFACTORY_MAX_NOF_INCMD; i++) { + /* Create the i-th InCommand as an extension of the Base OutComponent */ + inCmd[i] = FwSmCreateDer(CrFwInCmdMakeBase()); + + /* Create the Reset Procedure for the InCommand */ + inCmdResetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(inCmdResetPr, &CrFwBaseCmpDefConfigCheck, &CrFwInCmdConfigCheck); + inCmdData[i].resetProc = inCmdResetPr; + + /* Create the Initialization Procedure for the InCommand */ + inCmdInitPr = FwPrCreateDer(CrFwCmpGetInitProc()); + inCmdData[i].initProc = inCmdInitPr; + + /* Get the Execution Procedure for the InCommand */ + inCmdExecPr = CrFwBaseCmpGetDummyExecProc(); + inCmdData[i].execProc = inCmdExecPr; + + /* Set the component type */ + inCmdData[i].typeId = CR_FW_INCOMMAND_TYPE; + + /* Set the pointer to the component-specific data */ + inCmdData[i].cmpSpecificData = &inCmdCmpSpecificData[i]; + + /* Attach the data to the InCommand state machine and to its procedures. */ + FwSmSetData(inCmd[i], &inCmdData[i]); + FwSmSetData(FwSmGetEmbSm(inCmd[i], CR_FW_BASE_STATE_CONFIGURED), &inCmdData[i]); + FwPrSetData(inCmdData[i].initProc, &inCmdData[i]); + FwPrSetData(inCmdData[i].resetProc, &inCmdData[i]); + + /* Start and initialize the InCommand */ + FwSmStart(inCmd[i]); + CrFwCmpInit(inCmd[i]); + } + + /* Initialize the array holding the keys of the InCommand kinds */ + for (j=0; j<CR_FW_INCMD_NKINDS; j++) + inCmdKindKey[j] = (CrFwCmdRepKindKey_t)(inCmdKindDesc[j].servType*CR_FW_MAX_DISCRIMINANT*CR_FW_MAX_SERV_SUBTYPE + + inCmdKindDesc[j].servSubType*CR_FW_MAX_DISCRIMINANT+inCmdKindDesc[j].discriminant); + + /* Create the pre-allocated InReports */ + for (i=0; i<CR_FW_INFACTORY_MAX_NOF_INREP; i++) { + /* Create the i-th InReport as an extension of the Base OutComponent */ + inRep[i] = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the InReport */ + inRepResetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(inRepResetPr, &CrFwBaseCmpDefConfigCheck, &CrFwInRepConfigCheck); + inRepData[i].resetProc = inRepResetPr; + + /* Create the Initialization Procedure for the InReport */ + inRepInitPr = FwPrCreateDer(CrFwCmpGetInitProc()); + inRepData[i].initProc = inRepInitPr; + + /* Get the Execution Procedure for the InReport */ + inRepExecPr = CrFwInRepExecProcMake(); + inRepData[i].execProc = inRepExecPr; + + /* Set the component type */ + inRepData[i].typeId = CR_FW_INREPORT_TYPE; + + /* Set the pointer to the component-specific data */ + inRepData[i].cmpSpecificData = &inRepCmpSpecificData[i]; + + /* Attach the data to the InReport state machine and to its procedures. */ + FwSmSetData(inRep[i], &inRepData[i]); + FwPrSetData(inRepData[i].initProc, &inRepData[i]); + FwPrSetData(inRepData[i].resetProc, &inRepData[i]); + FwPrSetData(inRepData[i].execProc, &inRepData[i]); + + /* Start and initialize the InReport */ + FwSmStart(inRep[i]); + CrFwCmpInit(inRep[i]); + } + + /* Initialize the array holding the keys of the InReport kinds */ + for (j=0; j<CR_FW_INREP_NKINDS; j++) + inRepKindKey[j] = (CrFwCmdRepKindKey_t)(inRepKindDesc[j].servType*CR_FW_MAX_DISCRIMINANT*CR_FW_MAX_SERV_SUBTYPE + + inRepKindDesc[j].servSubType*CR_FW_MAX_DISCRIMINANT+inRepKindDesc[j].discriminant); + +} + +/*------------------------------------------------------------------------------------*/ +static void InFactoryConfigAction(FwPrDesc_t initPr) { + CrFwCounterU2_t i; + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(initPr); + + for (i=0; i<CR_FW_INFACTORY_MAX_NOF_INCMD; i++) + if (inCmdInUse[i] != 0) { + inCmdInUse[i] = 0; + CrFwPcktRelease(inCmdCmpSpecificData[i].pckt); + inCmdCmpSpecificData[i].pckt = NULL; + } + + for (i=0; i<CR_FW_INFACTORY_MAX_NOF_INREP; i++) + if (inRepInUse[i] == 1) { + inRepInUse[i] = 0; + CrFwPcktRelease(inRepCmpSpecificData[i].pckt); + inRepCmpSpecificData[i].pckt = NULL; + } + + nOfAllocatedInRep = 0; + nOfAllocatedInRepSinceReset = 0; + nextInRepFreePos = 0; + + nOfAllocatedInCmd = 0; + nOfAllocatedInCmdSinceReset = 0; + nextInCmdFreePos = 0; + + cmpData->outcome = 1; +} + +/*------------------------------------------------------------------------------------*/ +static void InFactoryShutdownAction(FwSmDesc_t smDesc) { + CrFwCounterU2_t i; + CRFW_UNUSED(smDesc); + + for (i=0; i<CR_FW_INFACTORY_MAX_NOF_INCMD; i++) { + /* Release memory allocated to InCommand Initialization Procedure */ + FwPrReleaseDer(inCmdData[i].initProc); + /* Release memory allocated to InCommand Reset Procedure */ + FwPrReleaseDer(inCmdData[i].resetProc); + /* Release memory allocated to InCommand */ + FwSmReleaseDer(FwSmGetEmbSm(inCmd[i],CR_FW_BASE_STATE_CONFIGURED)); + FwSmReleaseDer(inCmd[i]); + if (inCmdInUse[i] == 1) { + /* Mark all InCommand as not-in-use */ + inCmdInUse[i] = 0; + /* Release packet associated to InCommand */ + CrFwPcktRelease(inCmdCmpSpecificData[i].pckt); + } + } + + for (i=0; i<CR_FW_INFACTORY_MAX_NOF_INREP; i++) { + /* Release memory allocated to InReport Initialization Procedure */ + FwPrReleaseDer(inRepData[i].initProc); + /* Release memory allocated to InReport Reset Procedure */ + FwPrReleaseDer(inRepData[i].resetProc); + /* Release memory allocated to InReport Execution Procedure */ + FwPrRelease(inRepData[i].execProc); + /* Release memory allocated to InReport */ + FwSmReleaseDer(inRep[i]); + /* Mark all InReports as not-in-use */ + if (inRepInUse[i] == 1) { + inRepInUse[i] = 0; + /* Release packet associated to InRepor */ + CrFwPcktRelease(inRepCmpSpecificData[i].pckt); + } + } + + nOfAllocatedInRep = 0; + nOfAllocatedInCmd = 0; +} + + + + + + + + + + + diff --git a/CrFramework/src/InFactory/CrFwInFactory.h b/CrFramework/src/InFactory/CrFwInFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..d0ad535a4fabc36b844b15ccf8a102e864496f48 --- /dev/null +++ b/CrFramework/src/InFactory/CrFwInFactory.h @@ -0,0 +1,231 @@ +/** + * @file + * @ingroup inMngGroup + * Definition of the InFactory component. + * + * The InFactory component offers an interface through which incoming report components + * (InReports, see <code>CrFwInRep.h</code>) or incoming command components + * (InCommands, see <code>CrFwInCmd.h</code> be allocated and released. + * + * The InFactory is implemented as an extension of the Base Component of + * <code>CrFwBaseCmp.h</code>. + * The InFactory is a singleton component. + * + * This interface provides a function to create the InFactory, it provides + * functions to create an InReport or an InCommand of a specified kind, + * and it provides functions to release previously allocated InReports or + * InCommands. + * + * The InFactory maintains a pool of pre-allocated InReports and a pool + * of pre-allocated InCommands + * (the sizes of the pools are defined in <code>CrFwInFactoryUserPar.h</code>). + * Memory for the pools is allocated when the InFactory is initialized and is only + * released if the InFactory is shutdown. + * Items in the pool are marked as "in use" when they are allocated to an application + * and are marked as "not in use" when they are released. + * No memory allocation operations (<code>malloc/free</code>) are therefore performed + * when InReports or InCommands are allocated or released. + * When the InFactory is reset, all the items in the pool are marked as "not in use". + * + * <b>Mode of Use of an InFactory Component</b> + * + * The configuration of the InFactory component is defined statically in + * <code>CrFwInFactoryUserPar.h</code>. + * + * The InFactory is created with function <code>::CrFwInFactoryMake</code>. + * After being created, the InFactory must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the InFactory State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * After being configured, the InFactory is ready to manage the creation and release + * process for InReports and InCommands. + * An InReport is created with function <code>::CrFwInFactoryMakeInRep</code> and it + * is released with function <code>::CrFwInFactoryReleaseInRep</code>. + * Similarly, an InCommand is created with function <code>::CrFwInFactoryMakeInCmd</code> and it + * is released with function <code>::CrFwInFactoryReleaseInCmd</code>. + * + * An InReport wraps a packet holding an incoming report and an InCommand wraps a packet + * holding an incoming command. + * The packet holding the report or command is passed as an argument to the make function which + * creates the InReport or InCommand component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INFACTORY_H_ +#define CRFW_INFACTORY_H_ + +/* Include Framework files */ +#include "CrFwConstants.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmCore.h" + +/** + * Factory function for the singleton instance of the InFactory. + * The first time it is called, this function creates the InFactory singleton instance. + * Subsequent calls return the same instance. + * The first time this function is called, it returns the InFactory in state CREATED. + * @return the OutFactory singleton instance. + */ +FwSmDesc_t CrFwInFactoryMake(); + +/** + * Make function for a component encapsulating an incoming report (InReport). + * This function initializes and resets a component before returning it. + * Under nominal conditions, the component returned by this function is + * therefore in state CONFIGURED (but it could be in state INITIALIZED + * if the InReport's configuration check fails). + * + * An InReport encapsulates an incoming packet holding a report. + * The packet is passed as an argument to this function. + * The packet holds all the information about the incoming report. + * In particular, it holds the information about the report kind (as determined + * by the triplet: [service type, service sub-type, discriminant]). + * This function checks the report kind and, if it finds that it is illegal, + * it returns NULL and sets the application error code to: <code>::crIllInRepKind</code>). + * If instead the command is legal, this function uses it to configure the InReport. + * The configuration information is retrieved from <code>CrFwInFactoryUserPar</code>. + * + * If the allocation of the memory for the new InReport fails, the function + * returns NULL. + * Allocation memory failure results in the application error code being set + * to <code>crInRepAllocationFail</code>. + * + * When an InReport created by this function is no longer needed, + * it should be returned to the factory by calling <code>CrFwInRepReleaseInRep</code>. + * + * The instance identifier of the InReport created by this function is equal to + * the number of InReports created by the factory since it was last reset. + * + * If the InFactory is reset, then all the InReports which had been created + * by the factory are released. + * + * @param pckt the packet holding the InReport + * @return a new InReport or NULL if it was not possible to allocate the memory + * for the InReport. + */ +FwSmDesc_t CrFwInFactoryMakeInRep(CrFwPckt_t pckt); + +/** + * Make function for a component encapsulating an incoming command (InCommand). + * This function initializes and resets a component before returning it. + * Under nominal conditions, the component returned by this function is + * therefore in state CONFIGURED (but it could be in state INITIALIZED + * if the InCommand's configuration check fails). + * + * An InCommand encapsulates an incoming packet holding a command. + * The packet is passed as an argument to this function. + * The packet holds all the information about the incoming command. + * In particular, it holds the information about the command kind (as determined + * by the triplet: [service type, service sub-type, discriminant]). + * This function checks the command kind and, if it finds that it is illegal, + * it returns NULL and sets the application error code to: <code>::crIllInCmdKind</code>). + * If instead the command is legal, this function uses it to configure the InCommand. + * The configuration information is retrieved from <code>CrFwInFactoryUserPar</code>. + * + * If the allocation of the memory for the new InCommand fails, the function + * returns NULL. + * Allocation memory failure results in the application error code being set + * to <code>::crInCmdAllocationFail</code>. + * + * When an InCommand created by this function is no longer needed, + * it should be returned to the factory by calling <code>::CrFwInFactoryReleaseInCmd</code>. + * + * If the InFactory is reset, then all the InCommands which had been created + * by the factory are released. + * + * @param pckt the packet holding the InCommand + * @return a new InCommand or NULL if it was not possible to allocate the memory + * for the InCommand or if the packet type is not recognized. + */ +FwSmDesc_t CrFwInFactoryMakeInCmd(CrFwPckt_t pckt); + +/** + * Release function for an InReport. + * The argument of this function must be an InReport which was created using function + * <code>::CrFwInFactoryMakeInRep</code>. + * This function releases the memory which was allocated to the InReport. + * After this function is called, the InReport cannot be used. + * The function does not perform any checks on the existence or status of the + * InReport. + * An attempt to use an InReport which has been released will result in undefined behaviour. + * + * An attempt to release an InReport which had already been released, or to release a + * non-existent InReport will result in undefined behaviour and in the application + * error code being set to: <code>::crInRepRelErr</code>. + * + * @param inRepInstance the InReport to be released + */ +void CrFwInFactoryReleaseInRep(FwSmDesc_t inRepInstance); + +/** + * Release function for an InCommand. + * The argument of this function must be an InCommand which was created using function + * <code>::CrFwInFactoryMakeInCmd</code>. + * This function releases the memory which was allocated to the InCommand. + * After this function is called, the InCommand cannot be used. + * The function does not perform any checks on the existence or status of the + * InCommand. + * An attempt to use an InCommand which has been released will result in undefined behaviour. + * + * An attempt to release an InCommand which had already been released, or to release a + * non-existent InCommand will result in undefined behaviour and in the application + * error code being set to: <code>::crInCmdRelErr</code>. + * + * @param inCmdInstance the InCommand to be released + */ +void CrFwInFactoryReleaseInCmd(FwSmDesc_t inCmdInstance); + +/** + * Return the number of InReports which are currently allocated. + * This function returns the number of InReports which have been successfully + * allocated through calls to <code>::CrFwInFactoryMakeInRep</code> and have not yet been + * released through calls to <code>::CrFwInFactoryReleaseInRep</code>. + * @return the number of InReports which are currently allocated. + */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetNOfAllocatedInRep(); + +/** + * Return the maximum number of InReports which may be allocated at any one time. + * @return the maximum number of InReports which may be allocated at any one time + */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetMaxNOfInRep(); + +/** + * Return the number of InCommands which are currently allocated. + * This function returns the number of InCommands which have been successfully + * allocated through calls to <code>::CrFwInFactoryMakeInCmd</code> and have not yet been + * released through calls to <code>::CrFwInFactoryReleaseInCmd</code>. + * @return the number of InCommands which are currently allocated. + */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetNOfAllocatedInCmd(); + +/** + * Return the maximum number of InCommands which may be allocated at any one time. + * @return the maximum number of InCommands which may be allocated at any one time + */ +CrFwInFactoryPoolIndex_t CrFwInFactoryGetMaxNOfInCmd(); + +#endif /* CRFW_INFACTORY_H_ */ diff --git a/CrFramework/src/InLoader/CrFwInLoader.c b/CrFramework/src/InLoader/CrFwInLoader.c new file mode 100644 index 0000000000000000000000000000000000000000..7b60d45f1bc7c25eace6b5cb8da25e0ec058de18 --- /dev/null +++ b/CrFramework/src/InLoader/CrFwInLoader.c @@ -0,0 +1,259 @@ +/** + * @file + * + * Implementation of InManager State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwInLoaderUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "CrFwTime.h" +#include "CrFwInLoader.h" +#include "CrFwRepInCmdOutcome.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "Pckt/CrFwPcktQueue.h" +#include "InRegistry/CrFwInRegistry.h" +#include "InFactory/CrFwInFactory.h" +#include "InStream/CrFwInStream.h" +#include "InManager/CrFwInManager.h" +#include "InCmd/CrFwInCmd.h" +#include "OutStream/CrFwOutStream.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** The InLoader singleton */ +static FwSmDesc_t inLoader = NULL; + +/** The data structure for the InLoader */ +static CrFwCmpData_t inLoaderData; + +/** The component-specific data for the InLoader */ +static CrFwInLoaderData_t inLoaderCmpSpecificData; + +/** Pointer to function which checks the legality of the packet destination. */ +static CrFwInLoaderGetReroutingDest_t getReroutingDest = CR_FW_INLOADER_DET_REROUTING_DEST; + +/** Pointer to function which selects the InManager. */ +static CrFwInLoaderGetInManager_t getInManager = CR_FW_INLOADER_SEL_INMANAGER; + +/** + * Implement the logic of the InLoader Execution Procedure (see figure below). + * This function is executed every time the Execution Procedure of the InLoader + * is executed. + * @image html InLoaderExecution.png + * @param execPr the Execution Procedure of the InManager + */ +static void InLoaderExecAction(FwPrDesc_t execPr); + +/** + * Load the command or report encapsulated in the argument packet into an + * InManager. + * This function implements the logic shown in the figure. + * @image html InLoaderLoadCommandReport.png + * @param pckt the packet to be loaded in the InManager + */ +static void InLoaderLoadCmdRep(CrFwPckt_t pckt); + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwInLoaderMake() { + FwPrDesc_t resetPr, execPr, initPr; + + if (inLoader != NULL) { + return inLoader; /* The requested SM has already been created */ + } + + /* Create the requested SM as an extension of the base component SM */ + inLoader = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the InLoader Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + + /* Create the Initialization Procedure for the InLoader Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + + /* Create the Execution Procedure for the InLoader Component */ + execPr = FwPrCreateDer(CrFwBaseCmpGetDummyExecProc()); + FwPrOverrideAction(execPr, &CwFwBaseCmpDummyExecAction, &InLoaderExecAction); + + /* Initialize the data for the requested SM */ + inLoaderData.outcome = 1; + inLoaderData.initProc = initPr; + inLoaderData.resetProc = resetPr; + inLoaderData.execProc = execPr; + inLoaderData.instanceId = 0; + inLoaderData.typeId = CR_FW_INLOADER_TYPE; + inLoaderData.cmpSpecificData = &inLoaderCmpSpecificData; + + /* Attach the data to the InLoader state machine and to its procedures. */ + FwSmSetData(inLoader, &inLoaderData); + FwPrSetData(inLoaderData.initProc, &inLoaderData); + FwPrSetData(inLoaderData.resetProc, &inLoaderData); + FwPrSetData(inLoaderData.execProc, &inLoaderData); + + /* Start the InLoader */ + FwSmStart(inLoader); + + return inLoader; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwInLoaderSetInStream(FwSmDesc_t inStream) { + inLoaderCmpSpecificData.inStream = inStream; +} + +/*-----------------------------------------------------------------------------------------*/ +static void InLoaderExecAction(FwPrDesc_t prDesc) { + CrFwPckt_t pckt; + CrFwDestSrc_t pcktDest, reroutingDest; + FwSmDesc_t outStream; + CRFW_UNUSED(prDesc); + + /* Retrieve packet from InStream */ + pckt = CrFwInStreamGetPckt(inLoaderCmpSpecificData.inStream); + if (pckt == NULL) + return; + + /* Get packet destination and check whether it is the host application */ + pcktDest = CrFwPcktGetDest(pckt); + if (pcktDest == CR_FW_HOST_APP_ID) { + InLoaderLoadCmdRep(pckt); + return; + } + + /* Check whether packet should be re-routed to another destination */ + reroutingDest = getReroutingDest(pcktDest); + if (reroutingDest == 0) { /* destination is invalid */ + CrFwRepErrInstanceIdAndDest(crInLoaderInvDest, inLoaderData.typeId, inLoaderData.instanceId, + CrFwPcktGetCmdRepId(pckt), pcktDest); + CrFwPcktRelease(pckt); + return; + } + + /* Re-route packet and then release it */ + outStream = CrFwOutStreamGet(reroutingDest); + CrFwOutStreamSend(outStream, pckt); + CrFwPcktRelease(pckt); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void InLoaderLoadCmdRep(CrFwPckt_t pckt) { + FwSmDesc_t inCmp; + CrFwInstanceId_t instanceId = CrFwPcktGetCmdRepId(pckt); + CrFwServType_t servType = CrFwPcktGetServType(pckt); + CrFwServSubType_t servSubType = CrFwPcktGetServSubType(pckt); + CrFwDiscriminant_t disc = CrFwPcktGetDiscriminant(pckt); + CrFwCmdRepType_t cmdRepFlag = CrFwPcktGetCmdRepType(pckt); + CrFwCmpData_t* inCmpData; + CrFwInstanceId_t inManagerInstanceId; + CrFwBool_t inManagerLoadOutcome; + + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) { + inCmp = CrFwInFactoryMakeInCmd(pckt); + if (inCmp == NULL) { /* InCmd had invalid type or no more resources are available */ + CrFwRepInCmdOutcomeCreFail(crCmdAckCreFail, 0, pckt); + CrFwPcktRelease(pckt); + return; + } + } else { + inCmp = CrFwInFactoryMakeInRep(pckt); + if (inCmp == NULL) { /* InRep had invalid type or no more resources are available */ + CrFwRepErrPckt(crInLoaderCreFail, inLoaderData.typeId, inLoaderData.instanceId, pckt); + CrFwPcktRelease(pckt); + return; + } + } + + if (FwSmGetCurState(inCmp) != CR_FW_BASE_STATE_CONFIGURED) { /* InRep/InCmd has failed its validity check */ + inCmpData = FwSmGetData(inCmp); + if (cmdRepFlag == crRepType) { + CrFwRepErrRep(crInLoaderAccFail, inLoaderData.typeId, inLoaderData.instanceId, inCmp); + CrFwInFactoryReleaseInRep(inCmp); + return; + } else { + CrFwRepInCmdOutcome(crCmdAckAccFail, instanceId, servType, servSubType, disc, inCmpData->outcome, inCmp); + CrFwInFactoryReleaseInCmd(inCmp); + return; + } + } + + /* Select InManager */ + inManagerInstanceId = getInManager(servType, servSubType, disc, cmdRepFlag); + + /* Load InReport/InCommand in selected InManager */ + inManagerLoadOutcome = CrFwInManagerLoad(CrFwInManagerMake(inManagerInstanceId), inCmp); + if (inManagerLoadOutcome == 0) { /* Load operation has failed */ + if (cmdRepFlag == crRepType) { + CrFwRepErrRep(crInLoaderLdFail, inLoaderData.typeId, inLoaderData.instanceId,inCmp); + CrFwInFactoryReleaseInRep(inCmp); + return; + } else { + CrFwRepInCmdOutcome(crCmdAckLdFail, instanceId, servType, servSubType, disc, 0, inCmp); + CrFwInFactoryReleaseInCmd(inCmp); + return; + } + } else /* Load operation was successful */ + if (cmdRepFlag == crCmdType) + if (CrFwInCmdIsAcceptAck(inCmp) == 1) + CrFwRepInCmdOutcome(crCmdAckAccSucc, instanceId, servType, servSubType, disc, 0, inCmp); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwDestSrc_t CrFwInLoaderDefGetReroutingDestination(CrFwDestSrc_t pcktDest) { + return pcktDest; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwDestSrc_t CrFwInLoaderDefNoRerouting(CrFwDestSrc_t pcktDest) { + CRFW_UNUSED(pcktDest); + return 0; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwInstanceId_t CrFwInLoaderDefGetInManager(CrFwServType_t servType, CrFwServSubType_t servSubType, + CrFwDiscriminant_t discriminant, CrFwCmdRepType_t cmdRepFlag) { + CRFW_UNUSED(servType); + CRFW_UNUSED(servSubType); + CRFW_UNUSED(discriminant); + if (cmdRepFlag == crCmdType) + return 0; + else + return 1; +} diff --git a/CrFramework/src/InLoader/CrFwInLoader.h b/CrFramework/src/InLoader/CrFwInLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..5327b22a5a608bc8bfd5e32eaf40638e3d7a3cb0 --- /dev/null +++ b/CrFramework/src/InLoader/CrFwInLoader.h @@ -0,0 +1,212 @@ +/** + * @file + * @ingroup inMngGroup + * Definition of the InLoader component. + * + * The InLoader component is responsible for retrieving incoming packets which become available + * at an InStream (see <code>CrFwInStream.h</code>). + * + * The InLoader component is a singleton component. + * It is defined as an extension of the Base Component (see <code>CrFwBaseCmp.h</code>). + * It overrides its execution procedure with the InLoader Execution Procedure shown in the figure: + * @image html InLoaderExecution.png + * The Load/Command Report Procedure is shown in the next figure: + * @image html InLoaderLoadCommandReport.png + * + * Execution of the InLoader causes a query to be made on InStream to check whether a packet is + * available at that InStream. If a packet is available, it is collected and if it passes + * its acceptance check, it is loaded in an InManager. The selection of the InManager is an + * adaptation point implemented through a function pointer defined in + * <code>CrFwInLoaderUserPar.h</code>. + * + * The acceptance check is split into four sub-checks: + * -# The type/sub-type/discriminant of the incoming command or report is valid (i.e. it is + * defined in <code>CrFwInFactoryUserPar.h</code> and is therefore known to the application); + * -# The InFactory has sufficient resources to provide an InCommand or InReport component + * to hold the command or report encapsulated in the packet; + * -# The InCommand or InReport is successfully configured (i.e. it enters state CONFIGURED); + * -# The InCommand or InReport is successfully loaded in the InManager. + * . + * Sub-checks 1, 2 and 4 are fully implemented at framework level. + * Sub-check 3 is application-specific. + * It is called the <i>Validity Check</i> because it verifies the validity of the parameters of the + * incoming report or command and is implemented by a user-provided function which must conform + * to the prototype of function pointers <code>::CrFwInRepValidityCheck_t</code> for incoming + * reports or <code>::CrFwInCmdValidityCheck_t</code> for incoming commands. + * The functions implementing the validity checks are defined in <code>CrFwInFactoryUserPar.h</code>. + * + * Function <code>::InLoaderLoadCmdRep</code> in the InLoader is responsible for checking whether the + * sub-checks are passed. + * For incoming commands, failure to pass a sub-check is handled as follows: + * - Failure of sub-checks 1 and 2 is handled by calling function <code>::CrFwRepInCmdOutcomeCreFail</code> + * with outcome #crCmdAckCreFail. + * - Failure of sub-check 3 is handled by calling function <code>::CrFwRepInCmdOutcome</code> with + * outcome #crCmdAckAccFail. + * - Failure of sub-check 4 is handled by calling function <code>::CrFwRepInCmdOutcome</code> with + * outcome #crCmdAckLdFail. + * . + * If all sub-checks is passed, the incoming command is declared "accepted" and, if acknowledgement of + * successful acceptance for the command was required, function + * <code>::CrFwRepInCmdOutcome</code> is called with the outcome set to #crCmdAckAccSucc. + * + * For incoming reports, failure to pass a sub-check is treated as an error and is handled as follows: + * - Failure of sub-checks 1 and 2 is handled by calling function <code>::CrFwRepInCmdOutcomeCreFail</code> + * with failure code #crCmdAckCreFail. + * - Failure of sub-check 3 is handled by calling function <code>::CrFwRepErrRep</code> + * with failure code #crInLoaderAccFail. + * - Failure of sub-check 4 is handled by calling function <code>::CrFwRepErrRep</code> + * with failure code #crInLoaderLdFail. + * . + * + * <b>Mode of Use of an InLoader Component</b> + * + * The configuration of the InLoader components is defined statically in + * <code>CrFwInLoaderUserPar.h</code>. + * + * The InLoader singleton component is created with function <code>::CrFwInLoaderMake</code>. + * After being created, the InLoader must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the InManager State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * After an InLoader has been configured, it can be executed by means of function + * <code>FwSmExecute</code>. + * Execution of an InLoader causes its Execution Procedure (see figure above) to be + * executed. + * + * The InLoader should be executed either when it is known that a packet has arrived at an InStream + * or periodically to check whether a packet is available and, if it is, to process it. + * During one execution cycle, the InLoader processes one single packet from one single InStream. + * The target InStream is conceptually an argument of the execution command; in practice, the target + * InStream is passed to the InLoader through function <code>::CrFwInLoaderSetInStream</code>. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INLOADER_H_ +#define CRFW_INLOADER_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" +#include "Pckt/CrFwPcktQueue.h" + +/** + * Type for a pointer to the function which determines the re-routing destination of + * a packet. + * The function to determine the re-routing destination of a packet is one of the + * adaptation points of the framework. + * A function which implements this operation takes the packet destination as an + * argument and returns either zero (if the argument destination is invalid) or + * else it returns the destination to which the packet should be re-routed + * (if the argument destination is valid). + */ +typedef CrFwDestSrc_t (*CrFwInLoaderGetReroutingDest_t)(CrFwDestSrc_t); + +/** + * Type for a pointer to the function which selects the InManager where the InCommand + * or InReport must be loaded. + * The function to determine the re-routing destination of a packet is one of the + * adaptation points of the framework. + * A function which implements this operation takes as input the service type, service sub-type, + * and discriminant of the InReport/InCommand and a flag which indicates whether the + * item to be loaded in the InManaher encapsulates an InCommand or an InReport. + * The function returns the identifier of the selected InManager (see <code>::CrFwInManagerMake</code>). + */ +typedef CrFwInstanceId_t (*CrFwInLoaderGetInManager_t)(CrFwServType_t, CrFwServSubType_t, + CrFwDiscriminant_t, CrFwCmdRepType_t); + +/** + * Factory function to retrieve the state machine implementing the InLoader singleton + * component. + * The first time this function is called, it creates the InLoader State Machine singleton + * instance. + * Subsequent calls returns the same instance. + * + * The first time this function is called, it returns the InLoader State Machine + * after it has been started but before it has been initialized and + * configured. + * @return the descriptor of the InLoader State Machine or NULL + * if the state machine could not be created. + */ +FwSmDesc_t CrFwInLoaderMake(); + +/** + * Default implementation of the function which checks the legality of a destination and + * returns the re-routing destination. + * This default implementation always assumes that the argument destination is valid and + * it returns it unchanged. + * This default implementation is suitable for applications which are acting as gateways + * with one level of indirection (i.e. a situation where a packet is generated by application + * A for application B as its final destination, but the packet is sent to application C + * as a re-routing destination so that the packet travels from A to B and then from B to C). + * This function must conform to the prototype defined by <code>::CrFwInLoaderGetReroutingDest_t</code>. + * @param pcktDest the packet destination. + * @return the value of pcktDest. + */ +CrFwDestSrc_t CrFwInLoaderDefGetReroutingDestination(CrFwDestSrc_t pcktDest); + +/** + * Default implementation of the function which checks the legality of a destination and + * returns the re-routing destination. + * This default implementation always assumes that the argument destination is invalid and + * therefore it always returns zero. + * This default implementation is suitable for applications which do not perform + * any packet re-routing (i.e. applications where a packet is always sent to its final + * destination). + * This function must conform to the prototype defined by <code>::CrFwInLoaderGetReroutingDest_t</code>. + * @param pcktDest the packet destination. + * @return the value of pcktDest. + */ +CrFwDestSrc_t CrFwInLoaderDefNoRerouting(CrFwDestSrc_t pcktDest); + +/** + * Default implementation of the function which selects the InManager to which an + * incoming InReport or InCommand must be loaded. + * This default implementation returns 0 if the component to be loaded is an InCommand + * (namely if argument <code>cmdRepFlag</code> is equal to <code>::crCmdType</code>) and + * it returns 1 if the component to be loaded is an InReport (namely if argument + * <code>cmdRepFlag</code> is equal to <code>::crRepType</code>). + * This function must conform to the prototype defined by <code>::CrFwInLoaderGetInManager_t</code>. + * @param servType the service type of the incoming InCommand or InReport. + * @param servSubType the service sub-type of the incoming InCommand or InReport. + * @param discriminant the discriminant of the incoming InCommand or InReport. + * @param cmdRepFlag a flag indicating whether the item to be loaded is an InCommand or an InReport. + * @return the identifier of the InManager into which the incoming InCommand or InReport must be loaded. + */ +CrFwInstanceId_t CrFwInLoaderDefGetInManager(CrFwServType_t servType, CrFwServSubType_t servSubType, + CrFwDiscriminant_t discriminant, CrFwCmdRepType_t cmdRepFlag); + +/** + * Set the InStream from which the packets will be retrieved the next time the InLoader + * is executed. + * @param inStream the InStream from which the packets will be retrieved the next time + * the InLoader is executed. + */ +void CrFwInLoaderSetInStream(FwSmDesc_t inStream); + +#endif /* CRFW_INLOADER_H_ */ diff --git a/CrFramework/src/InManager/CrFwInManager.c b/CrFramework/src/InManager/CrFwInManager.c new file mode 100644 index 0000000000000000000000000000000000000000..0a022265349dc98a1fd1a401c53e7548ccb6f32d --- /dev/null +++ b/CrFramework/src/InManager/CrFwInManager.c @@ -0,0 +1,322 @@ +/** + * @file + * + * Implementation of InManager State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwInManagerUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwInManager.h" +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "CrFwTime.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "Pckt/CrFwPcktQueue.h" +#include "InRegistry/CrFwInRegistry.h" +#include "InFactory/CrFwInFactory.h" +#include "InCmd/CrFwInCmd.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** The sizes of the PCRL in the InManager components. */ +static CrFwCounterU2_t inManagerPcrlSize[CR_FW_NOF_INMANAGER] = CR_FW_INMANAGER_PCRLSIZE; + +/** The descriptors of the InManager State Machines. */ +static FwSmDesc_t inManagerDesc[CR_FW_NOF_INMANAGER]; + +/** The data structures for the InManager State Machines and their Procedures. */ +static CrFwCmpData_t inManagerData[CR_FW_NOF_INMANAGER]; + +/** The component-specific data for the InManager instances */ +static CrFwInManagerData_t inManagerCmpSpecificData[CR_FW_NOF_INMANAGER]; + +/** + * Initialization action for InManagers. + * This function allocates the memory for the InManager data structures and + * initializes them. + * The outcome of the initialization action is always "success" (the situation + * where the memory allocation fails is not handled). + * @param initPr the Initialization Procedure of the InManager + */ +static void InManagerInitAction(FwPrDesc_t initPr); + +/** + * Configuration action for InManagers. + * This function resets the PCRL, releases all InCommands and InReports in the PCRL + * and resets the counter of successfully loaded InReports or InCommands. + * The outcome of the initialization action is always: "success" + * @param initPr the Initialization Procedure of the InManager + */ +static void InManagerConfigAction(FwPrDesc_t initPr); + +/** + * Shutdown action for InManager. + * This function resets the PCRL and releases all InCommands and InReports in the PCRL. + * @param smDesc the InManager state machine + */ +static void InManagerShutdownAction(FwSmDesc_t smDesc); + +/** + * Implement the logic of the Execution Procedure (see figure below). + * This function is executed every time the Execution Procedure of the InManager + * is executed. + * @image html InManagerExecution.png + * @param execPr the Execution Procedure of the InManager + */ +static void InManagerExecAction(FwPrDesc_t execPr); + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwInManagerMake(CrFwInstanceId_t i) { + FwPrDesc_t resetPr, execPr, initPr; + + if (i >= CR_FW_NOF_INMANAGER) { + CrFwSetAppErrCode(crInManagerIllId); + return NULL; + } + + if (inManagerDesc[i] != NULL) { + return inManagerDesc[i]; /* The requested SM has already been created */ + } + + /* Create the requested SM as an extension of the base component SM */ + inManagerDesc[i] = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the InManager Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, &InManagerConfigAction); + + /* Create the Initialization Procedure for the InManager Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitAction, &InManagerInitAction); + + /* Create the Execution Procedure for the InManager Component */ + execPr = FwPrCreateDer(CrFwBaseCmpGetDummyExecProc()); + FwPrOverrideAction(execPr, &CwFwBaseCmpDummyExecAction, &InManagerExecAction); + + /* Override the Shutdown Action for the InManager Component */ + FwSmOverrideAction(inManagerDesc[i], &CrFwBaseCmpDefShutdownAction, &InManagerShutdownAction); + + /* Initialize the data for the requested SM */ + inManagerData[i].outcome = 1; + inManagerData[i].initProc = initPr; + inManagerData[i].resetProc = resetPr; + inManagerData[i].execProc = execPr; + inManagerData[i].instanceId = i; + inManagerData[i].typeId = CR_FW_INMANAGER_TYPE; + inManagerData[i].cmpSpecificData = &inManagerCmpSpecificData[i]; + + /* Attach the data to the InLoader state machine and to its procedures. */ + FwSmSetData(inManagerDesc[i], &inManagerData[i]); + FwPrSetData(inManagerData[i].initProc, &inManagerData[i]); + FwPrSetData(inManagerData[i].resetProc, &inManagerData[i]); + FwPrSetData(inManagerData[i].execProc, &inManagerData[i]); + + /* Start the InManager */ + FwSmStart(inManagerDesc[i]); + + return inManagerDesc[i]; +} + +/*-----------------------------------------------------------------------------------------*/ +static void InManagerExecAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwInManagerData_t* inManagerCSData = (CrFwInManagerData_t*)inManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = inManagerDataLocal->instanceId; + FwSmDesc_t inCmp; + CrFwCmpData_t* inCmpData; + CrFwCounterU2_t i; + CrFwInRegistryCmdRepState_t inCmpState; + + inManagerCSData->nextFreePcrlPos = 0; + for (i=0; i<inManagerPcrlSize[id]; i++) { + inCmp = inManagerCSData->pcrl[i]; + if (inCmp != NULL) { + FwSmExecute(inCmp); + inCmpData = (CrFwCmpData_t*)FwSmGetData(inCmp); + if (inCmpData->typeId == CR_FW_INREPORT_TYPE) { + inCmpState = crInRegistryTerminated; + } else { + CrFwInCmdTerminate(inCmp); + if (CrFwInCmdIsInAborted(inCmp)) + inCmpState = crInRegistryAborted; + else if (CrFwInCmdIsInTerminated(inCmp)) + inCmpState = crInRegistryTerminated; + else + inCmpState = crInRegistryPending; + } + if (inCmpState != crInRegistryPending) { + CrFwInRegistryUpdateState(inCmp, inCmpState); + /* Remove inCmp from PCRL */ + inManagerCSData->pcrl[i] = NULL; + inManagerCSData->nOfInCmpInPcrl--; + if (inCmpData->typeId == CR_FW_INREPORT_TYPE) + CrFwInFactoryReleaseInRep(inCmp); + else + CrFwInFactoryReleaseInCmd(inCmp); + } + } + } +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwInManagerLoad(FwSmDesc_t smDesc, FwSmDesc_t inCmp) { + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInManagerData_t* inManagerCSData = (CrFwInManagerData_t*)inManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = inManagerDataLocal->instanceId; + CrFwCounterU2_t i, freePos, size; + + freePos = inManagerCSData->nextFreePcrlPos; + size = inManagerPcrlSize[id]; + + /* Check if PCRL is already full */ + if (inManagerCSData->nOfInCmpInPcrl == size) { + CrFwRepErr(crInManagerPcrlFull, inManagerDataLocal->typeId, inManagerDataLocal->instanceId); + return 0; + } + + /* Check if this is the first load request after the OutManager was reset or after it was executed. + * If this is the case, find the first free position in the PCRL. + * NB: Since the for-loop is only entered if the PCRL is not full, it will always terminate + * through the break. This means that, when measuring branch coverage, the fall-through case + * at the for-loop will never occur. */ + if (freePos == 0) + for (i=0; i<size; i++) + if (inManagerCSData->pcrl[i] == NULL) { + freePos = i; + break; + } + + /* PCRL is not full --> load inCmp */ + inManagerCSData->pcrl[freePos] = inCmp; + inManagerCSData->nOfInCmpInPcrl++; + inManagerCSData->nOfLoadedInCmp++; + + /* Start tracking inCmp */ + CrFwInRegistryStartTracking(inCmp); + + /* Identify next free position in PCRL */ + for (i=freePos+1; i<size; i++) + if (inManagerCSData->pcrl[i] == NULL) { + inManagerCSData->nextFreePcrlPos = (CrFwCounterU1_t)i; + return 1; /* a free position has been found */ + } + + return 1; +} + +/*-----------------------------------------------------------------------------------------*/ +static void InManagerInitAction(FwPrDesc_t initPr) { + CrFwCounterU1_t i; + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwPrGetData(initPr); + CrFwInManagerData_t* inManagerCSData = (CrFwInManagerData_t*)inManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = inManagerDataLocal->instanceId; + inManagerCSData->pcrl = malloc(sizeof(FwSmDesc_t)*inManagerPcrlSize[id]); + for (i=0; i<inManagerPcrlSize[id]; i++) + inManagerCSData->pcrl[i] = NULL; + inManagerCSData->nOfInCmpInPcrl = 0; + inManagerDataLocal->outcome = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +static void InManagerConfigAction(FwPrDesc_t initPr) { + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwPrGetData(initPr); + CrFwInManagerData_t* inManagerCSData = (CrFwInManagerData_t*)inManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = inManagerDataLocal->instanceId; + CrFwCmpData_t* inCmpData; + CrFwCounterU1_t i; + + for (i=0; i<inManagerPcrlSize[id]; i++) { + if (inManagerCSData->pcrl[i] != NULL) { + inCmpData = (CrFwCmpData_t*)FwSmGetData(inManagerCSData->pcrl[i]); + if (inCmpData->typeId == CR_FW_INREPORT_TYPE) /* pending component is an InReport */ + CrFwInFactoryReleaseInRep(inManagerCSData->pcrl[i]); + else + CrFwInFactoryReleaseInCmd(inManagerCSData->pcrl[i]); + inManagerCSData->pcrl[i] = NULL; + } + } + inManagerCSData->nOfInCmpInPcrl = 0; + inManagerCSData->nOfLoadedInCmp = 0; + inManagerCSData->nextFreePcrlPos = 0; + inManagerDataLocal->outcome = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +static void InManagerShutdownAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInManagerData_t* inManagerCSData = (CrFwInManagerData_t*)inManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = inManagerDataLocal->instanceId; + CrFwCmpData_t* inCmpData; + CrFwCounterU1_t i; + + for (i=0; i<inManagerPcrlSize[id]; i++) { + if (inManagerCSData->pcrl[i] != NULL) { + inCmpData = (CrFwCmpData_t*)FwSmGetData(inManagerCSData->pcrl[i]); + if (inCmpData->typeId == CR_FW_INREPORT_TYPE) /* pending component is an InReport */ + CrFwInFactoryReleaseInRep(inManagerCSData->pcrl[i]); + else + CrFwInFactoryReleaseInCmd(inManagerCSData->pcrl[i]); + inManagerCSData->pcrl[i] = NULL; + } + } + free(inManagerCSData->pcrl); + inManagerCSData->nOfInCmpInPcrl = 0; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwInManagerGetNOfPendingInCmp(FwSmDesc_t smDesc) { + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInManagerData_t* inManagerCSData = (CrFwInManagerData_t*)inManagerDataLocal->cmpSpecificData; + return inManagerCSData->nOfInCmpInPcrl; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU2_t CrFwInManagerGetNOfLoadedInCmp(FwSmDesc_t smDesc) { + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInManagerData_t* inManagerCSData = (CrFwInManagerData_t*)inManagerDataLocal->cmpSpecificData; + return inManagerCSData->nOfLoadedInCmp; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwInManagerGetPCRLSize(FwSmDesc_t smDesc) { + CrFwCmpData_t* inManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInstanceId_t id = inManagerDataLocal->instanceId; + return (CrFwCounterU1_t)inManagerPcrlSize[id]; +} + diff --git a/CrFramework/src/InManager/CrFwInManager.h b/CrFramework/src/InManager/CrFwInManager.h new file mode 100644 index 0000000000000000000000000000000000000000..e9149425799dcd83970674b0a622418c47027d0e --- /dev/null +++ b/CrFramework/src/InManager/CrFwInManager.h @@ -0,0 +1,170 @@ +/** + * @file + * @ingroup inMngGroup + * Definition of the InManager component. + * + * The InManager component is responsible for maintaining a list of + * pending InReports (see <code>CrFwInRep.h</code>) and InCommands (see <code>CrFwInCmd.h</code>) + * and for repeatedly executing them until they are either aborted or terminated. + * + * The list of pending InReports or InCommands is called the Pending Command/Report List or PCRL. + * The PCRL has a fixed size which is defined statically in <code>CrFwInManagerUserPar.h</code>. + * + * The InManager is defined as an extension of the Base Component (see <code>CrFwBaseCmp.h</code>). + * It uses the Execution Procedure of the Base Component to process the pending InReport and InCommands. + * The InManager component processes the pending InReports or InCommands by sending them an Execute + * command. + * After each Execute command, the state of the pending item is reported to the InRegistry + * (see <code>CrFwInRegistry.h</code>). + * InReports or InCommands which have been aborted or have terminated are removed + * from the PCRL and are returned to the InFactory. + * The Execution Procedure of the InManager is shown in the figure below. + * + * <b>Mode of Use of an InManager Component</b> + * + * The configuration of the InManager components is defined statically in + * <code>CrFwInManagerUserPar.h</code>. + * + * An InManager component is created with function <code>::CrFwInManagerMake</code>. + * After being created, the InManager must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the InManager State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * Note that an application can have any number of InManagers. + * + * An InManager offers a Load operation (<code>::CrFwInManagerLoad</code>) through which + * an InReport or InCommand can be added to the PCRL. + * This operation is normally called by the InLoader (see <code>CrFwInLoader.h</code>). + * + * Note that there is no mechanism to “unload†a pending InReport or InCommand. + * The InManager autonomously returns an InReport or InCommand to its factory when the + * component has terminated or has been aborted. + * InReports are considered to have been terminated after they are executed once. + * InCommands are terminated if they are in state TERMINATED and they are aborted if + * they are in state ABORTED. + * + * After an InManager has been configured, it can be executed by means of function + * <code>FwSmExecute</code>. + * Execution of an InManager causes its Execution Procedure (see figure below) to be + * executed. + * + * When an InManager is reset or shutdown, its PCRL is reset (all pending InCommands and + * InReports are cleared and returned to theirs factories). + * + * @image html InManagerExecution.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INMANAGER_H_ +#define CRFW_INMANAGER_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" +#include "Pckt/CrFwPcktQueue.h" + +/** + * Factory function to retrieve the i-th InManager State Machine instance. + * The first time this function is called with a certain value of the argument i, it + * creates the i-th InManager State Machine instance. + * Subsequent calls returns the same instance. + * + * The InManager identifier i must be in the range: [0, <code>#CR_FW_NOF_INMANAGER</code>-1]. + * If the identifier is out of range, the function returns NULL and sets the application + * error code to: <code>::crInManagerIllId</code>. + * + * The first time this function is called with a certain value of i, it returns an + * InManager State Machine which has been started but which still needs to be initialized and + * configured. + * @param inManagerId the identifier of the InManager + * @return the descriptor of the InManager State Machine or NULL + * if the state machine could not be created or if the identifier i is out of range. + */ +FwSmDesc_t CrFwInManagerMake(CrFwInstanceId_t inManagerId); + +/** + * Load a new InReport or InCommand into the InManager. + * The behaviour implemented by this function is shown in the activity diagram below. + * If the PCRL is not full, the function identifies a free position in the PCRL where + * to store the InReport/InCommand. + * This function adds InReport/InCommand to the PCRL. The PCRL is flushed when the InManager + * is executed (i.e. it is flushed by function <code>::InManagerExecAction</code>). + * The algorithms to identify a free position in the PCRL and to process the PCRL + * entries when the InManager is executed are optimized for a situation where multiple + * load operations are performed before the InManager is executed. + * + * Additionally, these algorithms guarantee the following ordering constraint. + * Let InReports/InCommands C1 to Cn be successfully loaded into an InManager through a sequence + * of calls to function <code>::CrFwInManagerLoad</code> and assume that this sequence + * of load operations is not interrupted by an execution of the InManager. + * Under these conditions, when the InManager is executed next, the InReport/InCommand C1 to + * Cn will be processed in the order in which they have been loaded. + * + * The implementation of function <code>::CrFwInManagerLoad</code> is based on the + * internal variable <code>freePos</code>. This variable has the following + * characteristics: + * - it is initialized to point to the first entry in the PCRL; + * - after the execution of the load function, <code>freePos</code> either points to the next + * free position in the PCRL or is equal to the PCRL size if the PCRL is full; + * - after execution of the InManager, it is re-initialized to point to the first position + * in the PCRL. + * . + * @image html InManagerLoad.png + * @param smDesc the descriptor of the InManager State Machine. + * @param inCmp the descriptor of the InCommand or InReport to be loaded in the InManager + * @return 1 if the load operation was successful (the PCRL was not full and the + * InReport/InCommand was successfully loaded in the InManager) or 0 if + * the load operation has failed (the PCRL was full and the InReport/InCommand + * could not be loaded in the InManager). + */ +CrFwBool_t CrFwInManagerLoad(FwSmDesc_t smDesc, FwSmDesc_t inCmp); + +/** + * Return the number of InReport or InCommands currently in the PCRL of an InManager. + * @param smDesc the descriptor of the InManager State Machine. + * @return the number of OutComponents currently in the PCRL of an InManager. + */ +CrFwCounterU1_t CrFwInManagerGetNOfPendingInCmp(FwSmDesc_t smDesc); + + +/** + * Return the number of InReport or InCommands successfully loaded since the InManager + * was last reset. + * @param smDesc the descriptor of the InManager State Machine. + * @return the number of InReport or InCommands currently in the PCRL of an InManager. + */ +CrFwCounterU2_t CrFwInManagerGetNOfLoadedInCmp(FwSmDesc_t smDesc); + +/** + * Return the size of the PCRL of an InManager. + * @param smDesc the descriptor of the InManager State Machine. + * @return the size of the PCRL of an InManager. + */ +CrFwCounterU1_t CrFwInManagerGetPCRLSize(FwSmDesc_t smDesc); + +#endif /* CRFW_INMANAGER_H_ */ diff --git a/CrFramework/src/InRegistry/CrFwInRegistry.c b/CrFramework/src/InRegistry/CrFwInRegistry.c new file mode 100644 index 0000000000000000000000000000000000000000..582811a17d5a8ce232869dd70fd6ef21d08820b9 --- /dev/null +++ b/CrFramework/src/InRegistry/CrFwInRegistry.c @@ -0,0 +1,216 @@ +/** + * @file + * + * Implementation of InRegistry component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwInRegistryUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "OutCmp/CrFwOutCmp.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "CrFwInRegistry.h" +/* Include FW Profile files */ +#include "FwPrConfig.h" +#include "FwPrDCreate.h" +#include "FwSmConfig.h" +#include "FwSmDCreate.h" +#include "FwPrCore.h" + +/** + * An instance of this type holds the information about an incoming command or report + * which is being tracked by the OuRegistry. + */ +typedef struct { + /** The identifier of the incoming command or report */ + CrFwInstanceId_t instanceId; + /** The state of the incoming command or report */ + CrFwInRegistryCmdRepState_t state; +} CrFwTrackedState_t; + +/** Array to track the state of incoming commands or reports */ +static CrFwTrackedState_t cmdRepState[CR_FW_OUTREGISTRY_N]; + +/** The index of the most recent entry in <code>cmdRepState</code>. */ +static CrFwTrackingIndex_t cmdRepStateIndex = 0; + +/** The InRegistry singleton. */ +static FwSmDesc_t inRegistry = NULL; + +/** The data for the InRegistry singleton. */ +static CrFwCmpData_t inRegistryData; + +/** + * Configuration action for InRegistry. + * This function resets the queue of tracked commands and reports. + * The outcome of the configuration action is always: "successful" + * @param resetPr the Configuration Procedure of the InRegistry + */ +static void InRegistryConfigAction(FwPrDesc_t resetPr); + +/** + * Shutdown action for InRegistry. + * This function resets the queue of tracked commands and reports. + * @param smDesc the InRegistry state machine + */ +static void InRegistryShutdownAction(FwSmDesc_t smDesc); + +/*------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwInRegistryMake() { + FwPrDesc_t resetPr, execPr, initPr; + + if (inRegistry != NULL) { + return inRegistry; + } + + /* Extend the Base Component */ + inRegistry = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the OuRegistry Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, &InRegistryConfigAction); + + /* Create the Initialization Procedure for the OuRegistry Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + + /* Override the Shutdown Action for the InStream Component */ + FwSmOverrideAction(inRegistry, &CrFwBaseCmpDefShutdownAction, &InRegistryShutdownAction); + + /* Get the Dummy Execution Procedure for the InRegistry Component */ + execPr = CrFwBaseCmpGetDummyExecProc(); + + /* Initialize the data for the requested SM */ + inRegistryData.outcome = 1; + inRegistryData.initProc = initPr; + inRegistryData.resetProc = resetPr; + inRegistryData.execProc = execPr; + inRegistryData.instanceId = 0; + inRegistryData.typeId = CR_FW_INREGISTRY_TYPE; + + /* Attach the data to the InRegistry state machine and to its procedures. */ + FwSmSetData(inRegistry, &inRegistryData); + FwPrSetData(inRegistryData.initProc, &inRegistryData); + FwPrSetData(inRegistryData.resetProc, &inRegistryData); + + /* Start the InRegistry */ + FwSmStart(inRegistry); + + return inRegistry; +} + +/*------------------------------------------------------------------------------------*/ +void CrFwInRegistryStartTracking(FwSmDesc_t inCmp) { + CrFwCmpData_t* inCmpData = (CrFwCmpData_t*)FwSmGetData(inCmp); + CrFwInCmdData_t* inCmdCmpSpecificData; + CrFwInRepData_t* inRepCmpSpecificData; + + cmdRepState[cmdRepStateIndex].instanceId = inCmpData->instanceId; + cmdRepState[cmdRepStateIndex].state = crInRegistryPending; + if (inCmpData->typeId == CR_FW_INREPORT_TYPE) { + inRepCmpSpecificData = (CrFwInRepData_t*)(inCmpData->cmpSpecificData); + inRepCmpSpecificData->trackingIndex = cmdRepStateIndex; + } else { + inCmdCmpSpecificData = (CrFwInCmdData_t*)(inCmpData->cmpSpecificData); + inCmdCmpSpecificData->trackingIndex = cmdRepStateIndex; + } + + if (cmdRepStateIndex == (CR_FW_OUTREGISTRY_N-1)) + cmdRepStateIndex = 0; + else + cmdRepStateIndex++; +} + +/*------------------------------------------------------------------------------------*/ +void CrFwInRegistryUpdateState(FwSmDesc_t inCmp, CrFwInRegistryCmdRepState_t newState) { + CrFwCmpData_t* inCmpData = (CrFwCmpData_t*)FwSmGetData(inCmp); + CrFwInCmdData_t* inCmdCmpSpecificData; + CrFwInRepData_t* inRepCmpSpecificData; + CrFwTrackingIndex_t i; + + if (inCmpData->typeId == CR_FW_INREPORT_TYPE) { + inRepCmpSpecificData = (CrFwInRepData_t*)(inCmpData->cmpSpecificData); + i = inRepCmpSpecificData->trackingIndex; + } else { + inCmdCmpSpecificData = (CrFwInCmdData_t*)(inCmpData->cmpSpecificData); + i = inCmdCmpSpecificData->trackingIndex; + } + if (cmdRepState[i].instanceId == inCmpData->instanceId) { + cmdRepState[i].state = newState; + } +} + +/*------------------------------------------------------------------------------------*/ +CrFwInRegistryCmdRepState_t CrFwInRegistryGetState(CrFwInstanceId_t cmdRepId) { + CrFwTrackingIndex_t i; + CrFwTrackingIndex_t j; + + if (cmdRepStateIndex > 0) + i = (CrFwTrackingIndex_t)(cmdRepStateIndex-1); + else + i = (CR_FW_OUTREGISTRY_N-1); + + for (j=0; j<CR_FW_OUTREGISTRY_N; j++) { + if (cmdRepState[i].state == crInRegistryNoEntry) + break; + if (cmdRepState[i].instanceId == cmdRepId) { + return cmdRepState[i].state; + } else if (i == 0) + i = (CR_FW_OUTREGISTRY_N-1); + else + i--; + } + + return crInRegistryNotTracked; +} + +/*------------------------------------------------------------------------------------*/ +static void InRegistryConfigAction(FwPrDesc_t initPr) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(initPr); + CrFwCounterU2_t k; + + for (k=0; k<CR_FW_OUTREGISTRY_N; k++) + cmdRepState[k].state = crInRegistryNoEntry; + + cmdRepStateIndex = 0; + + cmpData->outcome = 1; +} + +/*------------------------------------------------------------------------------------*/ +static void InRegistryShutdownAction(FwSmDesc_t smDesc) { + CrFwCounterU2_t k; + CRFW_UNUSED(smDesc); + + for (k=0; k<CR_FW_OUTREGISTRY_N; k++) + cmdRepState[k].state = crInRegistryNoEntry; + + cmdRepStateIndex = 0; +} diff --git a/CrFramework/src/InRegistry/CrFwInRegistry.h b/CrFramework/src/InRegistry/CrFwInRegistry.h new file mode 100644 index 0000000000000000000000000000000000000000..0e4c493218635eadbb2d24333c75b7a466e2c9a8 --- /dev/null +++ b/CrFramework/src/InRegistry/CrFwInRegistry.h @@ -0,0 +1,151 @@ +/** + * @file + * @ingroup inMngGroup + * Definition of the InRegistry Component. + * + * An InRegistry acts as a registry for incoming commands or reports (namely for + * commands or reports which have been loaded into an InManager). + * The InRegistry is responsible for keeping track of the state of an incoming + * command or report. + * + * The InRegistry is a singleton component which is implemented as an extension + * of the Base Component of <code>CrFwBaseCmp.h</code>. + * + * The InRegistry maintains a list of the last N commands or reports to have been + * loaded in an InManager. + * The InRegistry maintains the state of each such command or report. + * The command's or report's state in the InRegistry can have one of the following values: + * - PENDING: the command or report is waiting to be executed + * - EXECUTING: the command has already been executed but has not yet completed + * execution + * - ABORTED: the command was aborted during execution + * - TERMINATED: the command or report has completed execution + * . + * Note that the states EXECUTING and ABORTED only apply to incoming commands (incoming + * reports are only executed once and then are terminated). + * + * The value of N (the maximum number of items which can be tracked by the InRegistry) + * is fixed and is an initialization parameter. + * + * The InRegistry uses the instance identifier of the incoming command or report + * as the key through which the command or report state is tracked. + * + * <b>Mode of Use of an InRegistry Component</b> + * + * The configuration of the InRegistry component is defined statically in + * <code>CrFwInRegistryUserPar.h</code>. + * + * The InRegistry component is a "final" component that does not normally need + * to be extended. + * + * An InRegistry component is created with function <code>::CrFwInRegistryMake</code>. + * After being created, the InRegistry must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the InRegistry State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INREGISTRY_H_ +#define CRFW_INREGISTRY_H_ + +/* Include configuration files */ +#include "CrFwInRegistryUserPar.h" +#include "CrFwUserConstants.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include framework files */ +#include "CrFwConstants.h" + +/** Enumerated type for the state of a command or report tracked by the InRegistry */ +typedef enum { + /** No entry yet in InRegistry */ + crInRegistryNoEntry = 0, + /** Incoming command or report is pending (waiting to be sent) */ + crInRegistryPending = 1, + /** Incoming command has been executed but has not yet completed execution */ + crInRegistryExecuting = 2, + /** Incoming command has been aborted */ + crInRegistryAborted = 3, + /** Incoming command or report has completed execution */ + crInRegistryTerminated = 4, + /** Incoming command or report is not tracked */ + crInRegistryNotTracked = 5 +} CrFwInRegistryCmdRepState_t; + +/** + * Factory function for the singleton instance of the InRegistry. + * The first time this function is called, it creates and configures the InRegistry. + * Subsequent calls returns the same singleton instance. + * The first time this function is called, it returns the InRegistry in state CREATED. + * + * If the creation or the configuration of the InRegistry fails, the function + * returns NULL. + * @return singleton instance of the InRegistry or NULL if the creation or configuration + * of the InRegistry failed. + */ +FwSmDesc_t CrFwInRegistryMake(); + +/** + * Ask the InRegistry to start tracking an incoming command or report. + * The InRegistry tracks the state of the last N incoming command or reports + * to have been loaded with this function. + * Initially, when this function is called, the incoming command or report is + * placed in state PENDING. + * + * This function runs the procedure in the left-hand + * side of the activity diagram shown in the figure. + * @image html RegistryStartTrackingAndUpdate.png + * @param inCmp the incoming command or report to be tracked + */ +void CrFwInRegistryStartTracking(FwSmDesc_t inCmp); + +/** + * Ask the InRegistry to update the state of an incoming command or report. + * If the argument component is not tracked by the InRegistry (perhaps because + * too many commands and reports have been added to the list of tracked components), + * nothing is done. + * This function runs the procedure in the right-hand + * side of the activity diagram shown in the figure. + * @image html RegistryStartTrackingAndUpdate.png + * @param inCmp the incoming command or report to be tracked + * @param newState the new state of the incoming command or report + */ +void CrFwInRegistryUpdateState(FwSmDesc_t inCmp, CrFwInRegistryCmdRepState_t newState); + +/** + * Query the InRegistry for the state of an incoming command or report. + * If the specified index does not correspond to any command or report being + * tracked by the InRegistry, a value of <code>::crInRegistryNotTracked</code> + * is returned. + * This function searches all locations in the InRegistry in sequence until it + * finds the incoming command or report. + * @param cmdRepId the instance identifier of the incoming command or report. + * @return the state of the incoming command or report (or <code>::crInRegistryNotTracked</code> + * if the command or report is not tracked) + */ +CrFwInRegistryCmdRepState_t CrFwInRegistryGetState(CrFwInstanceId_t cmdRepId); + +#endif /* CRFW_INREGISTRY_H_ */ diff --git a/CrFramework/src/InRep/CrFwInRep.c b/CrFramework/src/InRep/CrFwInRep.c new file mode 100644 index 0000000000000000000000000000000000000000..c7c543407ba4c0c8bd9732a2fc9d98d2552b0d13 --- /dev/null +++ b/CrFramework/src/InRep/CrFwInRep.c @@ -0,0 +1,121 @@ +/** + * @file + * + * Implementation of InReport component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "InRep/CrFwInRep.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "OutFactory/CrFwOutFactory.h" +#include "Pckt/CrFwPckt.h" +/* Include FW Profile files */ +#include "FwPrConfig.h" +#include "FwPrDCreate.h" +#include "FwSmConfig.h" +#include "FwSmDCreate.h" +#include "FwPrCore.h" + +/* --------------------------------------------------------------------------------- */ +CrFwDestSrc_t CrFwInRepGetSrc(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + return CrFwPcktGetSrc(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwGroup_t CrFwInRepGetGroup(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + return CrFwPcktGetGroup(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwServType_t CrFwInRepGetServType(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + return CrFwPcktGetServType(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwServType_t CrFwInRepGetServSubType(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + return CrFwPcktGetServSubType(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwDiscriminant_t CrFwInRepGetDiscriminant(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + return CrFwPcktGetDiscriminant(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwSeqCnt_t CrFwInRepGetSeqCnt(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + return CrFwPcktGetSeqCnt(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +char* CrFwInRepGetParStart(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetParStart(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwPcktLength_t CrFwInRepGetParLength(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetParLength(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwInRepConfigCheck(FwPrDesc_t prDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + if (cmpSpecificData->isValid(prDesc) == 1) + cmpData->outcome = 1; + else + cmpData->outcome = 0; +} + diff --git a/CrFramework/src/InRep/CrFwInRep.h b/CrFramework/src/InRep/CrFwInRep.h new file mode 100644 index 0000000000000000000000000000000000000000..07dadfdfc6a19f28817717548330ef4e75f5c059 --- /dev/null +++ b/CrFramework/src/InRep/CrFwInRep.h @@ -0,0 +1,148 @@ +/** + * @file + * @ingroup inMngGroup + * Definition of the InReport Component of the framework. + * + * An InReport encapsulates an incoming report in a service user application. + * The InReport is responsible for storing the attributes of an incoming report + * and for executing the conditional checks and actions associated to the report. + * The behaviour of an InReport is defined by the InReport State Machine + * (see figure below). + * + * <b>Mode of Use of an InReport Component</b> + * + * InReports are created dynamically by the InLoader when it processes an incoming + * packet which holds a report. + * The InReport component is created through a call to the factory function + * <code>::CrFwInFactoryMakeInRep</code>. + * The InLoader loads the InReport into an InManager who is then responsible for + * executing it and, eventually, for returning it to the InFactory. + * + * An InReport encapsulates an incoming report of a certain kind. + * The "kind" of an incoming command is defined by the triplet: + * [service type, service sub-type, discriminant]. + * InReports are adapted to a certain incoming report kind by modifying the + * implementation of the following operations: + * - Validity Check Operation + * - Update Action Operation + * . + * This operation is statically defined for each kind of InReport in + * <code>CrFwInFactoryUserPar.h</code>. + * This header file defines default values for the Update Action Operation. + * The default for the Configuration Check Operation is the function + * <code>::CrFwBaseCmpDefConfigCheck</code>. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INREP_H_ +#define CRFW_INREP_H_ + +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include configuration files */ +#include "Pckt/CrFwPcktQueue.h" +#include "CrFwUserConstants.h" +/* Include framework files */ +#include "CrFwConstants.h" + +/** + * Return the source of the InReport. + * @param smDesc the descriptor of the InRep State MachineStream + * @return the source of the InReport + */ +CrFwDestSrc_t CrFwInRepGetSrc(FwSmDesc_t smDesc); + +/** + * Return the group of the InReport. + * @param smDesc the descriptor of the InRep State MachineStream + * @return the group of the InReport + */ +CrFwGroup_t CrFwInRepGetGroup(FwSmDesc_t smDesc); + +/** + * Return the type of the InReport. + * @param smDesc the descriptor of the InRep State MachineStream + * @return the type of the InReport + */ +CrFwServType_t CrFwInRepGetServType(FwSmDesc_t smDesc); + +/** + * Return the sub-type of the InReport. + * @param smDesc the descriptor of the InRep State MachineStream + * @return the sub-type of the InReport + */ +CrFwServType_t CrFwInRepGetServSubType(FwSmDesc_t smDesc); + +/** + * Return the discriminant of the InReport. + * @param smDesc the descriptor of the InRep State MachineStream + * @return the discriminant of the InReport + */ +CrFwDiscriminant_t CrFwInRepGetDiscriminant(FwSmDesc_t smDesc); + +/** + * Return the sequence counter of the InReport. + * @param smDesc the descriptor of the InRep State MachineStream + * @return the sequence counter of the InReport + */ +CrFwSeqCnt_t CrFwInRepGetSeqCnt(FwSmDesc_t smDesc); + +/** + * Return the start address of the parameter area of the InReport. + * The InReport is encapsulated in a packet. + * The parameter area of the InReport is the part of the packet which is reserved to the + * storage of the parameters of the InReport. + * The parameter area consists of an uninterrupted sequence of bytes. + * The size of the parameter area is returned by function <code>::CrFwInRepGetParLength</code>. + * @param smDesc the descriptor of the Base State Machine of the InReport + * @return the start address of the InReport parameter area. + */ +char* CrFwInRepGetParStart(FwSmDesc_t smDesc); + +/** + * Return the length in bytes of the parameter area of the InReport. + * The InReport is encapsulated in a packet. + * The parameter area of the InReport is the part of the packet which is reserved to the + * storage of the parameters of the InReport. + * The parameter area consists of an uninterrupted sequence of bytes. + * The start address of the parameter area is returned by function <code>::CrFwInRepGetParStart</code>. + * @param smDesc the descriptor of the Base State Machine of the InReport + * @return the length in bytes of the InReport parameter area + */ +CrFwPcktLength_t CrFwInRepGetParLength(FwSmDesc_t smDesc); + +/** + * Configuration check for an InReport. + * This function executes the Validity Check of the InReport and sets the + * action outcome to 1 if the Validity Check returns true and sets it to + * zero if it returns false. + * + * This function is not intended to be called by applications. + * It is declared as a public function because it is needed by the + * InFactory (see <code>CrFwInFactory.h</code>). + * @param prDesc the descriptor of the InReport Configuration Procedure. + */ +void CrFwInRepConfigCheck(FwPrDesc_t prDesc); + +#endif /* CRFW_INREP_H_ */ diff --git a/CrFramework/src/InRep/CrFwInRepExecProc.c b/CrFramework/src/InRep/CrFwInRepExecProc.c new file mode 100644 index 0000000000000000000000000000000000000000..c6ce6f43b7a3111534e6adbc3a1c3a78af5dc921 --- /dev/null +++ b/CrFramework/src/InRep/CrFwInRepExecProc.c @@ -0,0 +1,79 @@ +/** + * @file + * + * Implementation of InReport Execution Procedure. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Configuration Files */ +#include "CrFwCmpData.h" +/* Framework Files */ +#include "CrFwInRepExecProc.h" +#include "CrFwInRep.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* FW Profile Files */ +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** + * Function implementing the action of the single node in the Report Execution Procedure. + * @param prDesc the procedure descriptor + */ +static void CwFwInRepExecAction(FwPrDesc_t prDesc); + +/*-----------------------------------------------------------------------------------------*/ +FwPrDesc_t CrFwInRepExecProcMake() { + const FwPrCounterS1_t nOfANodes = 1; /* Number of action nodes */ + const FwPrCounterS1_t nOfDNodes = 0; /* Number of decision nodes */ + const FwPrCounterS1_t nOfFlows = 2; /* Number of control flows */ + const FwPrCounterS1_t nOfActions = 1; /* Number of actions */ + const FwPrCounterS1_t nOfGuards = 0; /* Number of guards */ + const FwPrCounterS1_t N1 = 1; /* Identifier of first action node */ + FwPrDesc_t execProc; + + /* Create the execution procedure */ + execProc = FwPrCreate(nOfANodes, nOfDNodes, nOfFlows, nOfActions, nOfGuards); + + /* Configure the initialization procedure */ + FwPrAddActionNode(execProc, N1, &CwFwInRepExecAction); + FwPrAddFlowIniToAct(execProc, N1, NULL); + FwPrAddFlowActToFin(execProc, N1, NULL); + + return execProc; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static void CwFwInRepExecAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwInRepData_t* cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->updateAction(prDesc); + return; +} + + + + diff --git a/CrFramework/src/InRep/CrFwInRepExecProc.h b/CrFramework/src/InRep/CrFwInRepExecProc.h new file mode 100644 index 0000000000000000000000000000000000000000..147392270b4bb77ac1549b6d95772ed9a3a45ea1 --- /dev/null +++ b/CrFramework/src/InRep/CrFwInRepExecProc.h @@ -0,0 +1,52 @@ +/** + * @file + * @ingroup inMngGroup + * Execution Procedure for the InReport Component. + * This procedure has single node which executes the Update Action of the + * InReport (see figure below). + * This header file gives access to a make function which creates a new + * instance of the procedure. + * + * @image html InReportExecution.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INREP_EXEC_PROC_H_ +#define CRFW_INREP_EXEC_PROC_H_ + +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include framework files */ +#include "CrFwConstants.h" + +/** + * Create a new instance of the InReport Execution Procedure. + * This function returns the descriptor of newly created InReport Execution Procedure. + * Note that no data are attached to the descriptor as it is returned by this + * function. + * @return the descriptor of the InReport Execution Procedure or NULL if the + * procedure could not be created. + */ +FwPrDesc_t CrFwInRepExecProcMake(); + +#endif /* CRFW_INREP_EXEC_PROC_H_ */ diff --git a/CrFramework/src/InStream/CrFwInStream.c b/CrFramework/src/InStream/CrFwInStream.c new file mode 100644 index 0000000000000000000000000000000000000000..0691cd1273a7555676556f57e0348d5be381526c --- /dev/null +++ b/CrFramework/src/InStream/CrFwInStream.c @@ -0,0 +1,386 @@ +/** + * @file + * + * Implementation of InStream State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwInStreamUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "CrFwRepErr.h" +#include "CrFwTime.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "CrFwInStream.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "Pckt/CrFwPcktQueue.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** Base InStream from which all other InStreams are derived. */ +static FwSmDesc_t baseInStreamSmDesc = NULL; + +/** The sizes of the packet queues in the InStream components. */ +static CrFwCounterU1_t inStreamPcktQueueSize[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_PQSIZE; + +/** The number of groups associated to the InStream components. */ +static CrFwGroup_t inStreamNOfGroups[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_NOF_GROUPS; + +/** The functions implementing the packet hand-over operations for the InStream components. */ +static CrFwPcktCollect_t inStreamPcktCollect[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_PCKTCOLLECT; + +/** The functions implementing the packet available check operations for the InStream components. */ +static CrFwPcktAvailCheck_t inStreamPcktAvailCheck[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_PCKTAVAILCHECK; + +/** The functions implementing the initialization checks for the InStream components. */ +static FwPrAction_t inStreamInitCheck[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_INITCHECK; + +/** The functions implementing the initialization actions for the InStream components. */ +static FwPrAction_t inStreamInitAction[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_INITACTION; + +/** The functions implementing the configuration checks for the InStream components. */ +static FwPrAction_t inStreamConfigCheck[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_CONFIGCHECK; + +/** The functions implementing the configuration actions for the InStream components. */ +static FwPrAction_t inStreamConfigAction[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_CONFIGACTION; + +/** The functions implementing the shutdown actions for the InStream components. */ +static FwSmAction_t inStreamShutdownAction[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_SHUTDOWNACTION; + +/** The sources associated to the InStream components. */ +static CrFwDestSrc_t inStreamSrc[CR_FW_NOF_INSTREAM] = CR_FW_INSTREAM_SRC; + +/** The descriptors of the InStream State Machines. */ +static FwSmDesc_t inStreamDesc[CR_FW_NOF_INSTREAM]; + +/** The data structures for the InStream State Machines and their Procedures. */ +static CrFwCmpData_t inStreamData[CR_FW_NOF_INSTREAM]; + +/** The component-specific data for the InStream State Machines and their Procedures. */ +static CrFwInStreamData_t inStreamCmpSpecificData[CR_FW_NOF_INSTREAM]; + +/** + * Function which checks if the packet queue is empty. + * This function is used as guard for the transition into state WAITING. + * @param smDesc the state machine descriptor + * @return 1 if the packet queue is empty; zero otherwise. + */ +static int IsPcktQueueEmpty(FwSmDesc_t smDesc); + +/** + * Function which checks if a packet is available. + * This function is used as guard for the transition into state WAITING. + * @param smDesc the state machine descriptor + * @return 1 if the packet queue is empty; zero otherwise. + */ +static int IsPcktAvail(FwSmDesc_t smDesc); + +/** + * Function which performs Action A in the InStream State Machine. + * This function is used as a transition action in the InStream State Machine. + * @param smDesc the state machine descriptor + * @return 1 if the packet queue is empty; zero otherwise. + */ +static void DoActionA(FwSmDesc_t smDesc); + +/** + * Function which performs Action b in the InStream State Machine. + * This function is used as a transition action in the InStream State Machine. + * @param smDesc the state machine descriptor + * @return 1 if the packet queue is empty; zero otherwise. + */ +static void DoActionB(FwSmDesc_t smDesc); + + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwInStreamMake(CrFwInstanceId_t i) { + const FwSmCounterS1_t nOfStates = 2; /* Number of states */ + const FwSmCounterS1_t nOfChoicePseudoStates = 2; /* Number of choice pseudo-states */ + const FwSmCounterS1_t nOfTrans = 8; /* Number of transitions */ + const FwSmCounterS1_t nOfActions = 2; /* Number of actions */ + const FwSmCounterS1_t nOfGuards = 2; /* Number of guards */ + const FwSmCounterS1_t CPS_1 = 1; /* Identifier of first choice pseudo-state */ + const FwSmCounterS1_t CPS_2 = 2; /* Identifier of second choice pseudo-state */ + FwSmDesc_t esm; + FwPrDesc_t resetPr, execPr, initPr; + + if (i >= CR_FW_NOF_INSTREAM) { + CrFwSetAppErrCode(crInStreamIllId); + return NULL; + } + + /* If not yet done, create the base InStream SM */ + if (baseInStreamSmDesc == NULL) { + /* Extend the Base Component */ + baseInStreamSmDesc = FwSmCreateDer(CrFwBaseCmpMake()); + /* Create the InStream SM and then embed it in state CONFIGURED of the Base Component */ + esm = FwSmCreate(nOfStates, nOfChoicePseudoStates, nOfTrans, nOfActions, nOfGuards); + FwSmAddState(esm, CR_FW_INSTREAM_STATE_WAITING, 1, NULL, NULL, NULL, NULL); + FwSmAddState(esm, CR_FW_INSTREAM_STATE_PCKT_AVAIL, 2, NULL, NULL, NULL, NULL); + FwSmAddChoicePseudoState(esm, CPS_1, 2); + FwSmAddChoicePseudoState(esm, CPS_2, 2); + FwSmAddTransIpsToCps(esm, CPS_1, NULL); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_INSTREAM_STATE_PCKT_AVAIL, &DoActionB, &IsPcktAvail); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_INSTREAM_STATE_WAITING, NULL, NULL); /* Else Transition */ + FwSmAddTransStaToSta(esm, CR_FW_INSTREAM_TR_PACKET_AVAILABLE, CR_FW_INSTREAM_STATE_PCKT_AVAIL, + CR_FW_INSTREAM_STATE_PCKT_AVAIL, &DoActionB, NULL); + FwSmAddTransStaToCps(esm, CR_FW_INSTREAM_TR_PACKET_AVAILABLE, CR_FW_INSTREAM_STATE_WAITING, + CPS_2, &DoActionB, NULL); + FwSmAddTransStaToCps(esm, CR_FW_INSTREAM_TR_GET_PCKT, CR_FW_INSTREAM_STATE_PCKT_AVAIL, + CPS_2, &DoActionA, NULL); + FwSmAddTransCpsToSta(esm, CPS_2, CR_FW_INSTREAM_STATE_WAITING, NULL, &IsPcktQueueEmpty); + FwSmAddTransCpsToSta(esm, CPS_2, CR_FW_INSTREAM_STATE_PCKT_AVAIL, NULL, NULL); /* Else Transition */ + FwSmEmbed(baseInStreamSmDesc, CR_FW_BASE_STATE_CONFIGURED, esm); + } + + if (inStreamDesc[i] != NULL) { + return inStreamDesc[i]; /* The requested SM has already been created */ + } + + /* Create the requested SM as an extension of the base InStream SM */ + inStreamDesc[i] = FwSmCreateDer(baseInStreamSmDesc); + + /* Create the Reset Procedure for the InStream Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigCheck, inStreamConfigCheck[i]); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, inStreamConfigAction[i]); + + /* Create the Initialization Procedure for the InStream Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitCheck, inStreamInitCheck[i]); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitAction, inStreamInitAction[i]); + + /* Override the Shutdown Action for the InStream Component */ + FwSmOverrideAction(inStreamDesc[i], &CrFwBaseCmpDefShutdownAction, inStreamShutdownAction[i]); + + /* Get the Dummy Execution Procedure for the InStream Component */ + execPr = CrFwBaseCmpGetDummyExecProc(); + + /* Initialize the data for the requested InStream Component */ + inStreamData[i].outcome = 1; + inStreamData[i].initProc = initPr; + inStreamData[i].resetProc = resetPr; + inStreamData[i].execProc = execPr; + inStreamData[i].instanceId = i; + inStreamData[i].typeId = CR_FW_INSTREAM_TYPE; + inStreamCmpSpecificData[i].collectPckt = inStreamPcktCollect[i]; + inStreamCmpSpecificData[i].isPcktAvail = inStreamPcktAvailCheck[i]; + inStreamCmpSpecificData[i].src = inStreamSrc[i]; + inStreamData[i].cmpSpecificData = &inStreamCmpSpecificData[i]; + + /* Attach the data to the InStream state machine and to its procedures. + * The data is attached to the outer SM and to the SM embedded in state CONFIGURED + * and to the Initialization and Reset Procedures. */ + FwSmSetData(inStreamDesc[i], &inStreamData[i]); + FwSmSetData(FwSmGetEmbSm(inStreamDesc[i], CR_FW_BASE_STATE_CONFIGURED), &inStreamData[i]); + FwPrSetData(inStreamData[i].initProc, &inStreamData[i]); + FwPrSetData(inStreamData[i].resetProc, &inStreamData[i]); + + /* Start the InStream */ + FwSmStart(inStreamDesc[i]); + + return inStreamDesc[i]; +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwInStreamGet(CrFwDestSrc_t src) { + CrFwInstanceId_t i; + for (i=0; i<CR_FW_NOF_INSTREAM; i++) + if (inStreamCmpSpecificData[i].src == src) + return inStreamDesc[i]; + + CrFwSetAppErrCode(crInStreamUndefDest); + return NULL; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwInStreamIsInWaiting(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_INSTREAM_STATE_WAITING); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwInStreamIsInPcktAvail(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_INSTREAM_STATE_PCKT_AVAIL); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwPckt_t CrFwInStreamGetPckt(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + cmpSpecificData->pckt = NULL; + FwSmMakeTrans(smDesc, CR_FW_INSTREAM_TR_GET_PCKT); + return cmpSpecificData->pckt; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwInStreamPcktAvail(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, CR_FW_INSTREAM_TR_PACKET_AVAILABLE); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwDestSrc_t CrFwInStreamGetSrc(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + return cmpSpecificData->src; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwSeqCnt_t CrFwInStreamGetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + return cmpSpecificData->seqCnt[group]; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwInStreamSetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group, CrFwSeqCnt_t seqCnt) +{ + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + cmpSpecificData->seqCnt[group] = seqCnt; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwInStreamGetNOfPendingPckts(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + return CrFwPcktQueueGetNOfPckts(&(cmpSpecificData->pcktQueue)); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwGroup_t CrFwInStreamGetNOfGroups(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return inStreamNOfGroups[inStreamBaseData->instanceId]; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwInStreamGetPcktQueueSize(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + return CrFwPcktQueueGetSize(&(cmpSpecificData->pcktQueue)); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwInStreamDefConfigAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + CrFwGroup_t i; + + CrFwPcktQueueReset(&(cmpSpecificData->pcktQueue)); + cmpSpecificData->pckt = NULL; + for (i=0; i<inStreamNOfGroups[inStreamBaseData->instanceId]; i++) + cmpSpecificData->seqCnt[i] = 0; + inStreamData->outcome = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwInStreamDefShutdownAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + + CrFwPcktQueueShutdown(&(cmpSpecificData->pcktQueue)); + free(cmpSpecificData->seqCnt); + cmpSpecificData->seqCnt = NULL; + cmpSpecificData->pckt = NULL; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwInStreamDefInitAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + CrFwInstanceId_t i = inStreamBaseData->instanceId; + + cmpSpecificData->seqCnt = malloc(sizeof(CrFwSeqCnt_t)*inStreamNOfGroups[i]); + CrFwPcktQueueInit(&(cmpSpecificData->pcktQueue), inStreamPcktQueueSize[i]); +} + +/*-----------------------------------------------------------------------------------------*/ +static void DoActionA(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + cmpSpecificData->pckt = CrFwPcktQueuePop(&(cmpSpecificData->pcktQueue)); +} + +/*-----------------------------------------------------------------------------------------*/ +static void DoActionB(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + CrFwDestSrc_t src = cmpSpecificData->src; + CrFwPckt_t pckt; + CrFwSeqCnt_t seqCnt; + CrFwGroup_t group; + + while (cmpSpecificData->isPcktAvail(src)) { + pckt = cmpSpecificData->collectPckt(src); + if (!pckt) /* added by UVIE */ + return; + if (CrFwPcktGetDest(pckt) == CR_FW_HOST_APP_ID) { + seqCnt = CrFwPcktGetSeqCnt(pckt); + group = CrFwPcktGetGroup(pckt); + if (group < inStreamNOfGroups[inStreamBaseData->instanceId]) { + if (cmpSpecificData->seqCnt[group] != 0) + if ((cmpSpecificData->seqCnt[group]+1) != seqCnt) + CrFwRepErrSeqCnt(crInStreamSCErr, inStreamData->typeId, inStreamData->instanceId, + (cmpSpecificData->seqCnt[group]+1), seqCnt); + + cmpSpecificData->seqCnt[group] = seqCnt; + } else + CrFwRepErrGroup(crInStreamIllGroup, inStreamBaseData->typeId, + inStreamBaseData->instanceId, group); + } + + if (CrFwPcktQueuePush(&(cmpSpecificData->pcktQueue), pckt) == 0) { + CrFwRepErr(crInStreamPQFull, inStreamData->typeId, inStreamData->instanceId); + CrFwPcktRelease(pckt); + } + } +} + +/*-----------------------------------------------------------------------------------------*/ +static int IsPcktAvail(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + CrFwDestSrc_t src = cmpSpecificData->src; + return cmpSpecificData->isPcktAvail(src); +} + +/*-----------------------------------------------------------------------------------------*/ +static int IsPcktQueueEmpty(FwSmDesc_t smDesc) { + CrFwCmpData_t* inStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInStreamData_t* cmpSpecificData = (CrFwInStreamData_t*)inStreamBaseData->cmpSpecificData; + return CrFwPcktQueueIsEmpty(&(cmpSpecificData->pcktQueue)); +} + diff --git a/CrFramework/src/InStream/CrFwInStream.h b/CrFramework/src/InStream/CrFwInStream.h new file mode 100644 index 0000000000000000000000000000000000000000..8d328f0c5da2e46c187b487a8745f866bf6bd94f --- /dev/null +++ b/CrFramework/src/InStream/CrFwInStream.h @@ -0,0 +1,255 @@ +/** + * @file + * @ingroup inMngGroup + * Definition of the InStream component. + * + * An InStream is responsible for managing the collection of packets (representing + * incoming reports or incoming commands) from a certain packet source. + * An InStream is implemented by the InStream State Machine (see figures below) + * embedded within state CONFIGURED of a Base State Machine. + * + * The InStream State Machine has two states. State PCKT_AVAIL represents a situation + * where one or more packets have been collected from the middleware and are waiting + * to be processed by the application. + * State WAITING represents a situation where no packets are pending in the InStream. + * The packets in the InStream are stored in a <i>Packet Queue</i>. + * + * An application can instantiate several InStream Components. + * Each InStream instance has an identifier which uniquely identifies it + * within the set of InStream Components. + * This identifier is an integer in the range 0 to: <code>#CR_FW_NOF_INSTREAM</code>-1. + * An application should instantiated one InStream for each source of incoming commands + * or reports. + * + * <b>Mode of Use of an InStream Component</b> + * + * The configuration of the InStream components is defined statically in + * <code>CrFwInStreamUserPar.h</code>. + * + * An InStream component is created with function <code>::CrFwInStreamMake</code>. + * After being created, the InStream must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the InStream State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * After it has been configured, an InStream can process two transition commands: + * - A GetPacket command to retrieve one packet (representing either a command or a report) + * from the InStream's Packet Queue. The GetPacket command returns packets in the order in + * which they were collected from the middleware. + * This command is sent through function <code>::CrFwInStreamGetPckt</code>. + * - A PacketAvailable command to check whether any packets are available at the middleware + * interface and, if they are available, to collect them and store them in the InStream's Packet + * Queue. This command is sent with the <code>::CrFwInStreamPcktAvail</code> function. + * . + * @image html InStream.png + * The InStream State Machine runs the Packet Collect Procedure shown in the following figure: + * @image html PacketCollect.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_INSTREAM_H_ +#define CRFW_INSTREAM_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Configuration Files */ +#include "Pckt/CrFwPcktQueue.h" +#include "CrFwUserConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" + +/** + * Factory function to retrieve the i-th InStream State Machine instance. + * The first time this function is called with a certain value of the argument i, it + * creates the i-th InStream State Machine instance. + * Subsequent calls returns the same instance. + * + * The InStream identifier i must be in the range: [0, <code>#CR_FW_NOF_INSTREAM</code>-1]. + * If the identifier is out of range, the function returns NULL and sets the application + * error code to: <code>::crInStreamIllId</code>. + * + * The first time this function is called with a certain value of i, it returns an + * InStream State Machine which has been started but which must still be initialized + * and configured. + * @param inStreamId the identifier of the InStream + * @return the descriptor of the Base State Machine of the InStream or NULL + * if the state machine could not be created or if the identifier i is out of range. + */ +FwSmDesc_t CrFwInStreamMake(CrFwInstanceId_t inStreamId); + +/** + * Getter function for the InStream corresponding to the argument source. + * Nominally, each InStream is associated to a certain packet source. + * The binding between an InStream and its source is done statically in the + * configuration file <code>CrFwInStreamUserPar.h</code>. + * + * If the value of the source argument is illegal (i.e. if no + * InStream has been bound to it), this function returns NULL and sets the + * application error code to: <code>::crInStreamUndefDest</code>. + * + * This function should only be called after all InStreams have been built through + * calls to function <code>::CrFwInStreamMake</code>. + * If this pre-condition is not satisfied, execution of this function could result + * in an access to a NULL pointer. + * @param src the packet source associated to the InStream + * @return the descriptor of the InStream State Machine or NULL + * if the argument source was illegal or no InStream had been bound to it. + */ +FwSmDesc_t CrFwInStreamGet(CrFwDestSrc_t src); + +/** + * Retrieve a packet from the InStream. + * This function sends the GetPacket command to the InStream State Machine. + * If, at the time the function is called, the InStream is in state PCKT_AVAIL (i.e. if + * the InStream is configured and its packet queue is not empty), the function + * returns the oldest packet currently in the Packet Queue of the InStream; otherwise, the + * function return NULL. + * @param smDesc the descriptor of the Base State Machine of the InStream. + * @return pckt the oldest packet in the packet queue or NULL if there is no packet in + * the packet queue. + */ +CrFwPckt_t CrFwInStreamGetPckt(FwSmDesc_t smDesc); + +/** + * Query the middleware for available packets and collect them if they are available. + * This function sends the PacketAvailable command to the InStream State Machine. + * This command may be sent to the InStream by the middleware to signal + * the arrival of a new packet at the connection controlled by the InStream or + * it may be sent to poll the middleware and check whether any packets are + * available. If packets are available at the middleware, they are collected + * and stored in the InStream's Packet Queue. + * @param smDesc the descriptor of the Base State Machine of the InStream. + */ +void CrFwInStreamPcktAvail(FwSmDesc_t smDesc); + +/** + * Return true if the argument InStream is in state WAITING. + * @param smDesc the descriptor of the Base State Machine of the InStream. + * @return 1 if the argument InStream is in state CONFIGURED, sub-state WAITING; + * 0 otherwise. + */ +CrFwBool_t CrFwInStreamIsInWaiting(FwSmDesc_t smDesc); + +/** + * Return true if the argument InStream is in state PCKT_AVAIL. + * @param smDesc the descriptor of the Base State Machine of the InStream. + * @return 1 if the argument InStream is in state CONFIGURED, sub-state PCKT_AVAIL; + * 0 otherwise. + */ +CrFwBool_t CrFwInStreamIsInPcktAvail(FwSmDesc_t smDesc); + +/** + * Default configuration action for an InStream. + * This function resets the packet queue of the InStream. + * Configuration actions have an outcome (see <code>CrFwResetProc.h</code>). + * The outcome of this configuration action is always: "success". + * + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Configuration Actions. + * @param prDesc the descriptor of the Reset Procedure of the InStream + */ +void CrFwInStreamDefConfigAction(FwPrDesc_t prDesc); + +/** + * Default initialization action for an InStream. + * This function: (a) allocates the memory for the packet queue of the InStream; + * (b) allocates the memory for the array holding the sequence counters for the destination/source + * groups associated to the Instream; and (c) initializes all data structures implementing + * the InStream. + * Initialization actions have an outcome (see <code>CrFwResetProc.h</code>). + * The situation of where the memory allocation fails is not handled and + * therefore the outcome of this configuration action is always "success". + * + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Initialization Actions. + * @param prDesc the descriptor of the Initialization Procedure of the InStream + */ +void CrFwInStreamDefInitAction(FwPrDesc_t prDesc); + +/** + * Default shutdown action for an InStream. + * This function releases the memory allocated to the packet queue of the InStream + * and releases the memory allocated to the array holding the sequence counters. + * + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Shutdown Actions. + * @param smDesc the descriptor of the InStream State Machine + */ +void CrFwInStreamDefShutdownAction(FwSmDesc_t smDesc); + +/** + * Return the value of the sequence counter of the last packet successfully + * collected by the InStream for a group. + * If no packet has yet been collected for that group after the InStream was reset, the + * sequence counter is equal to zero. + * @param smDesc the descriptor of the InStream State Machine + * @param group the identifier of the group + * @return the InStream sequence counter + */ +CrFwSeqCnt_t CrFwInStreamGetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group); + +/** + * Overwrites the sequence counter value of the last packet for a group. + * Can be used to update the expected sequence counter value for the next + * packet. + * @param smDesc the descriptor of the InStream State Machine + * @param group the identifier of the group + * @param seqCnt the InStream sequence counter + */ +void CrFwInStreamSetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group, CrFwSeqCnt_t seqCnt); + +/** + * Return the number of packets currently in the packet queue of an InStream. + * @param smDesc the descriptor of the InStream State Machine + * @return the number of packets currently in the packet queue of the InStream. + */ +CrFwCounterU1_t CrFwInStreamGetNOfPendingPckts(FwSmDesc_t smDesc); + +/** + * Return the number of groups associated to the InStream. + * @param smDesc the descriptor of the Base State Machine of the InStream. + * @return the number of groups associated to the InStream. + */ +CrFwGroup_t CrFwInStreamGetNOfGroups(FwSmDesc_t smDesc); + +/** + * Return the size of the packet queue of the InStream. + * @param smDesc the descriptor of the InStream State Machine + * @return the size of the packet queue of the InStream. + */ +CrFwCounterU1_t CrFwInStreamGetPcktQueueSize(FwSmDesc_t smDesc); + +/** + * Get the currently defined packet source of an InStream. + * An InStream can receive packets from one (and only one) source. + * A source has an identifier of type <code>::CrFwDestSrc_t</code>. + * @param smDesc the descriptor of the Base State Machine of the InStream. + * @return src the source associated to the OutStream + */ +CrFwDestSrc_t CrFwInStreamGetSrc(FwSmDesc_t smDesc); + +#endif /* CRFW_INSTREAM_H_ */ diff --git a/CrFramework/src/OutCmp/CrFwOutCmp.c b/CrFramework/src/OutCmp/CrFwOutCmp.c new file mode 100644 index 0000000000000000000000000000000000000000..de9c0037c98312b558da6b608bc6388f4480fc58 --- /dev/null +++ b/CrFramework/src/OutCmp/CrFwOutCmp.c @@ -0,0 +1,408 @@ +/** + * @file + * + * Implementation of OutComponent component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "OutStream/CrFwOutStream.h" +#include "OutCmp/CrFwOutCmp.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "OutFactory/CrFwOutFactory.h" +#include "Pckt/CrFwPckt.h" +#include "CrFwTime.h" +/* Include FW Profile files */ +#include "FwPrConfig.h" +#include "FwPrDCreate.h" +#include "FwSmConfig.h" +#include "FwSmDCreate.h" +#include "FwPrCore.h" + +/** Base OutComponent from which all other OutComponents are derived. */ +static FwSmDesc_t baseOutCmpSmDesc = NULL; + +/** + * Transition action on the transition out of the LOADED state. + * This transition action executes the enable check and then + * sets the outcome as follows: + * - if the enable check returns "not enabled", the outcome is set to 0 + * - if the enable check returns "enabled" the outcome is set to 1 + * . + * The setting of the <code>isRepeat</code> flag is not done in this function. + * This flag will only be evaluated after the Repeat Check is performed and + * there is therefore no need to set it here. + * @param smDesc the descriptor of the OutComponent state machine + */ +void LoadedToCpsTransAction(FwSmDesc_t smDesc); + +/** + * Do action of the PENDING state (including behaviour of Send Packet Procedure). + * The outcome of the Repeat Check and of the Enable Check are stored in the outcome + * field of the component data as follows: + * - If the Enable Check reports 'Not Enabled', the outcome is set to zero + * - If the Enable Check reports 'Enabled' and the Repeat Check reports 'No Repeat', + * the outcome is set to 2 + * - In all other cases, the outcome is set to 1. + * . + * In order to understand why the logic in this function is equivalent to that of the + * specification, consider the outcome of executing and terminating the OutComponent + * for all possible values of the Ready Check, Repeat Check, Enable Check and validity + * statuses of the OutComponent's destination: + * - isReady==true, isRepeat==true, isEnabled==true, dest. is valid --> PENDING, outcome=1 + * - isReady=='any', isRepeat=='any', isEnabled==false, dest. is 'any' --> ABORTED, outcome=0 + * - isReady==true, isRepeat==false, isEnabled==true, dest. is valid --> TERMINATED, outcome=2 + * - isReady==true, isRepeat=='any', isEnabled==true, dest. is false --> TERMINATED, outcome=2 + * - isReady==false, isRepeat=='any', isEnabled==true, dest. is 'any' --> PENDING, outcome=1 + * . + * @image html SendPacket.png + * @param smDesc the descriptor of the OutComponent state machine + */ +void PendingDoAction(FwSmDesc_t smDesc); + +/** + * Entry action of the SENDING state (including behaviour of Send Packet Procedure). + * The outcome of the Repeat Check is stored in the outcome field of the component + * data (a value of '1' corresponds to: 'Repeat' and a value of '2' corresponds to: + * 'No Repeat'). + * + * In order to understand why the logic in this function is equivalent to that of the + * specification, consider the outcome of executing and terminating the OutComponent + * for all possible for all possible values of the Ready Check, Repeat Check, and + * validity statuses of the OutComponent's destination (recall that isRepeat and + * isEnabled are guaranteed to be true at entry): + * - isReady==true, isRepeat==true, dest. is valid --> PENDING, outcome=1 + * - isReady==true, isRepeat==false, dest. is valid --> TERMINATED, outcome=2 + * - isReady==false, isRepeat=='any', dest. is 'any' --> PENDING, outcome=1 + * - isReady==true, isRepeat=='any', dest. is not valid --> TERMINATED, outcome=2 + * . + * @image html SendPacket.png + * @param smDesc the descriptor of the OutComponent state machine + */ +void PendingEntryAction(FwSmDesc_t smDesc); + +/* --------------------------------------------------------------------------------- */ +FwSmDesc_t CrFwOutCmpMakeBase() { + FwSmCounterS1_t nOfStates = 4; /* Number of states */ + FwSmCounterS1_t nOfChoicePseudoStates = 1; /* Number of choice pseudo-states */ + FwSmCounterS1_t nOfTrans = 6; /* Number of transitions */ + FwSmCounterS1_t nOfActions = 3; /* Number of actions */ + FwSmCounterS1_t nOfGuards = 3; /* Number of guards */ + FwSmCounterS1_t CPS_1 = 1; /* Identifier of first choice pseudo-state */ + FwSmDesc_t esm; + + if (baseOutCmpSmDesc != NULL) + return baseOutCmpSmDesc; + + /* Create and configure the base OutComponent */ + + /* Extend the Base Component */ + baseOutCmpSmDesc = FwSmCreateDer(CrFwBaseCmpMake()); + /* Create the OutComponent SM and then embed it in state CONFIGURED of the Base Component */ + esm = FwSmCreate(nOfStates, nOfChoicePseudoStates, nOfTrans, nOfActions, nOfGuards); + FwSmAddState(esm, CR_FW_OUTCMP_STATE_LOADED, 1, NULL, NULL, NULL, NULL); + FwSmAddState(esm, CR_FW_OUTCMP_STATE_ABORTED, 0, NULL, NULL, NULL, NULL); + FwSmAddState(esm, CR_FW_OUTCMP_STATE_PENDING, 2, &PendingEntryAction, NULL, &PendingDoAction, NULL); + FwSmAddState(esm, CR_FW_OUTCMP_STATE_TERMINATED, 0, NULL, NULL, NULL, NULL); + FwSmAddChoicePseudoState(esm, CPS_1, 2); + FwSmAddTransIpsToSta(esm, CR_FW_OUTCMP_STATE_LOADED, NULL); + FwSmAddTransStaToCps(esm, FW_TR_EXECUTE, CR_FW_OUTCMP_STATE_LOADED, CPS_1, + &LoadedToCpsTransAction, NULL); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_OUTCMP_STATE_ABORTED, NULL, &CrFwIsSmOutcomeZero); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_OUTCMP_STATE_PENDING, NULL, &CrFwIsSmOutcomeOne); + FwSmAddTransStaToSta(esm, CR_FW_OUTCMP_TR_TERMINATE, CR_FW_OUTCMP_STATE_PENDING, + CR_FW_OUTCMP_STATE_TERMINATED, NULL, &CrFwIsSmOutcomeTwo); + FwSmAddTransStaToSta(esm, CR_FW_OUTCMP_TR_TERMINATE, CR_FW_OUTCMP_STATE_PENDING, + CR_FW_OUTCMP_STATE_ABORTED, NULL, &CrFwIsSmOutcomeZero); + FwSmEmbed(baseOutCmpSmDesc, CR_FW_BASE_STATE_CONFIGURED, esm); + + return baseOutCmpSmDesc; +} + +/* --------------------------------------------------------------------------------- */ +void CrFwOutCmpTerminate(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, CR_FW_OUTCMP_TR_TERMINATE); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsInLoaded(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_OUTCMP_STATE_LOADED); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsInAborted(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_OUTCMP_STATE_ABORTED); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsInPending(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_OUTCMP_STATE_PENDING); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsInTerminated(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_OUTCMP_STATE_TERMINATED); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpDefEnableCheck(FwSmDesc_t smDesc) { + return CrFwOutRegistryIsEnabled(smDesc); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwOutCmpDefSerialize(FwSmDesc_t smDesc) { + CrFwPckt_t pckt; + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + pckt = cmpSpecificData->pckt; + CrFwPcktSetCmdRepId(pckt,cmpData->instanceId); + + return; +} + +/* --------------------------------------------------------------------------------- */ +CrFwDestSrc_t CrFwOutCmpGetDest(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetDest(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwOutCmpSetDest(FwSmDesc_t smDesc, CrFwDestSrc_t dest) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + CrFwPcktSetDest(cmpSpecificData->pckt, dest); + return; +} + +/* --------------------------------------------------------------------------------- */ +CrFwGroup_t CrFwOutCmpGetGroup(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetGroup(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwOutCmpSetGroup(FwSmDesc_t smDesc, CrFwGroup_t group) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + CrFwPcktSetGroup(cmpSpecificData->pckt, group); + return; +} + +/* --------------------------------------------------------------------------------- */ +CrFwTimeStamp_t CrFwOutCmpGetTimeStamp(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetTimeStamp(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwOutCmpSetTimeStamp(FwSmDesc_t smDesc, CrFwTimeStamp_t timeStamp) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + CrFwPcktSetTimeStamp(cmpSpecificData->pckt, timeStamp); + return; +} + +/* --------------------------------------------------------------------------------- */ +CrFwServType_t CrFwOutCmpGetServType(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetServType(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwDestSrc_t CrFwOutCmpGetSrc(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetSrc(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwServType_t CrFwOutCmpGetServSubType(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetServSubType(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwDiscriminant_t CrFwOutCmpGetDiscriminant(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetDiscriminant(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwOutCmpSetDiscriminant(FwSmDesc_t smDesc, CrFwDiscriminant_t discriminant) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + CrFwPcktSetDiscriminant(cmpSpecificData->pckt, discriminant); +} + +/* --------------------------------------------------------------------------------- */ +void CrFwOutCmpSetAckLevel(FwSmDesc_t smDesc, CrFwBool_t accept, CrFwBool_t start, + CrFwBool_t progress, CrFwBool_t term) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + CrFwPcktSetAckLevel(cmpSpecificData->pckt,accept,start,progress,term); + return; +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsAcceptAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsAcceptAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsStartAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsStartAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsProgressAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsProgressAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwBool_t CrFwOutCmpIsTermAck(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktIsTermAck(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +void LoadedToCpsTransAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpData->outcome = (CrFwOutcome_t)cmpSpecificData->isEnabled(smDesc); + return; +} + +/* --------------------------------------------------------------------------------- */ +void PendingEntryAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + CrFwBool_t isReady; + CrFwBool_t isRepeat; + CrFwDestSrc_t dest; + FwSmDesc_t outStream; + + isReady = cmpSpecificData->isReady(smDesc); + if (isReady) { + cmpSpecificData->update(smDesc); + dest = CrFwPcktGetDest(cmpSpecificData->pckt); + outStream = CrFwOutStreamGet(dest); + if (outStream == NULL) { + CrFwRepErrDestSrc(crOutCmpSendPcktInvDest, cmpData->typeId, cmpData->instanceId, dest); + isRepeat = 0; + } else { + CrFwOutCmpSetTimeStamp(smDesc,CrFwGetCurrentTime()); + cmpSpecificData->serialize(smDesc); + CrFwOutStreamSend(outStream, cmpSpecificData->pckt); + isRepeat = cmpSpecificData->isRepeat(smDesc); + } + if (isRepeat == 1) + cmpData->outcome = 1; + else + cmpData->outcome = 2; + } +} + +/* --------------------------------------------------------------------------------- */ +void PendingDoAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + CrFwDestSrc_t dest; + FwSmDesc_t outStream; + CrFwBool_t isReady; + CrFwBool_t isRepeat; + CrFwBool_t isEnabled; + + isReady = cmpSpecificData->isReady(smDesc); + isEnabled = cmpSpecificData->isEnabled(smDesc); + + if (isReady == 1) + if (isEnabled ==1) { + cmpSpecificData->update(smDesc); + dest = CrFwPcktGetDest(cmpSpecificData->pckt); + outStream = CrFwOutStreamGet(dest); + if (outStream == NULL) { + CrFwRepErrDestSrc(crOutCmpSendPcktInvDest, cmpData->typeId, cmpData->instanceId, dest); + isRepeat = 0; + } else { + CrFwOutCmpSetTimeStamp(smDesc,CrFwGetCurrentTime()); + cmpSpecificData->serialize(smDesc); + CrFwOutStreamSend(outStream, cmpSpecificData->pckt); + isRepeat = cmpSpecificData->isRepeat(smDesc); + } + if (isRepeat == 0) { + cmpData->outcome = 2; + return; + } + } + + if (isEnabled == 0) { + cmpData->outcome = 0; + return; + } + + cmpData->outcome = 1; +} + +/* --------------------------------------------------------------------------------- */ +char* CrFwOutCmpGetParStart(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetParStart(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwPcktLength_t CrFwOutCmpGetParLength(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetParLength(cmpSpecificData->pckt); +} + +/* --------------------------------------------------------------------------------- */ +CrFwPcktLength_t CrFwOutCmpGetLength(FwSmDesc_t smDesc) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + return CrFwPcktGetLength(cmpSpecificData->pckt); +} diff --git a/CrFramework/src/OutCmp/CrFwOutCmp.h b/CrFramework/src/OutCmp/CrFwOutCmp.h new file mode 100644 index 0000000000000000000000000000000000000000..fa291893d19ee7bb26d25753e464fa425990b4f4 --- /dev/null +++ b/CrFramework/src/OutCmp/CrFwOutCmp.h @@ -0,0 +1,348 @@ +/** + * @file + * @ingroup outMngGroup + * Definition of the OutComponent Component of the framework. + * + * An OutComponent encapsulates an out-going command or an out-going report. + * The OutComponent is responsible for serializing the out-going command or report + * to a packet and sending the packet to an OutStream for dispatching to its + * destination. + * The behaviour of an OutComponent is defined by the OutComponent State Machine + * embedded in the CONFIGURED state of the Base State Machine and + * by the Send Packet Procedure (see figures below). + * + * <b>Mode of Use of an OutComponent Component</b> + * + * Applications create OutComponents dynamically through calls to the factory + * function <code>::CrFwOutFactoryMakeOutCmp</code>. + * OutComponents thus returned are expected to be in state CREATED (if this + * is not the case - perhaps because the OutComponent's configuration action + * has failed to complete successfully - the OutComponent will remain permanently + * pending and will never be sent to its destination). + * + * An OutComponent is used to encapsulate an out-going command or report of + * a certain kind. + * The "kind" of an out-going command or report is defined by the triplet: + * [service type, service sub-type, discriminant]. + * OutComponents are adapted to a certain kind of out-going report or command + * by modifying one or more of the following: + * - The Enable Check Operation + * - The Ready Check Operation + * - The Repeat Check Operation + * - The Update Action Operation + * - The Serialize Operation + * . + * These operations are statically defined for each kind of OutComponent in + * <code>CrFwOutFactoryUserPar.h</code>. + * + * This header file defines default values for all configurable operations listed + * above. + * The default implementations for the Enable Check, Ready Check and Repeat Check will + * often be suitable for many kinds of out-going reports or commands but + * dedicated implementations of the Serialize and Update Action will probably have to + * be provided for application-specific out-going reports or commands. + * + * @image html OutComponent.png + * <center>-</center> + * @image html SendPacket.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_OUTCMP_H_ +#define CRFW_OUTCMP_H_ + +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include configuration files */ +#include "Pckt/CrFwPcktQueue.h" +#include "CrFwUserConstants.h" +/* Include framework files */ +#include "OutRegistry/CrFwOutRegistry.h" +#include "CrFwConstants.h" + +/** + * Return the base OutComponent from which all other OutComponents are derived. + * The base OutComponent is a singleton. + * The first time it is called, this function creates and configures the base OutComponent instance. + * Subsequent calls return this same instance. + * This function is only intended to be used by the OutFactory (see <code>CrFwOutFactory.h</code>) + * and should not be used by applications. + * @return the singleton instance of the base OutComponent + */ +FwSmDesc_t CrFwOutCmpMakeBase(); + +/** + * Send command Terminate to the argument OutComponent. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + */ +void CrFwOutCmpTerminate(FwSmDesc_t smDesc); + +/** + * Return true if the argument OutComponent is in state LOADED. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return 1 if the argument OutComponent is in state CONFIGURED, sub-state + * LOADED; 0 otherwise + */ +CrFwBool_t CrFwOutCmpIsInLoaded(FwSmDesc_t smDesc); + +/** + * Return true if the argument OutComponent is in state ABORTED. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return 1 if the argument OutComponent is in state CONFIGURED, sub-state + * ABORTED; 0 otherwise + */ +CrFwBool_t CrFwOutCmpIsInAborted(FwSmDesc_t smDesc); + +/** + * Return true if the argument OutComponent is in state PENDING. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return 1 if the argument OutComponent is in state CONFIGURED, sub-state + * PENDING; 0 otherwise + */ +CrFwBool_t CrFwOutCmpIsInPending(FwSmDesc_t smDesc); + +/** + * Return true if the argument OutComponent is in state TERMINATED. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return 1 if the argument OutComponent is in state CONFIGURED, sub-state + * TERMINATED; 0 otherwise + */ +CrFwBool_t CrFwOutCmpIsInTerminated(FwSmDesc_t smDesc); + +/** + * Default implementation of the Enable Check Operation for an OutComponent. + * This function retrieves the enable status of the OutComponent from the OutRegistry + * (see <code>::CrFwOutRegistryIsEnabled</code>). + * + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Enable Check Operations. + * @param smDesc the descriptor of the Base State Machine of the OutComponent. + * @return 1 if the OutComponent is enabled, 0 if it is not enabled. + */ +CrFwBool_t CrFwOutCmpDefEnableCheck(FwSmDesc_t smDesc); + +/** + * Default implementation of the Serialize Operation for an OutComponent. + * This implementation writes to the packet encapsulated in the OutComponent all the + * following attributes of the out-going report or command: + * - The command or report identifier (this is set equal to the instance identifier + * of the OutComponent) + * . + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Serialize Operations. + * @param smDesc the descriptor of the Base State Machine of the OutComponent. + */ +void CrFwOutCmpDefSerialize(FwSmDesc_t smDesc); + +/** + * Return the destination of the OutComponent. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the destination of the OutComponent + */ +CrFwDestSrc_t CrFwOutCmpGetDest(FwSmDesc_t smDesc); + +/** + * Set the destination of the OutComponent. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @param dest the destination of the OutComponent + */ +void CrFwOutCmpSetDest(FwSmDesc_t smDesc, CrFwDestSrc_t dest); + +/** + * Return the group of the OutComponent. + * By default, the group of an OutComponent is set when the OutComponent is created + * by function <code>::CrFwOutFactoryMakeOutCmp</code> but its value can be overridden + * with function <code>::CrFwOutCmpSetGroup</code>. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the group of the OutComponent + */ +CrFwGroup_t CrFwOutCmpGetGroup(FwSmDesc_t smDesc); + +/** + * Set the group of the OutComponent. + * By default, the group of an OutComponent is set when the OutComponent is created + * by function <code>::CrFwOutFactoryMakeOutCmp</code> but its value can be overridden + * with this function. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @param group the group + * @return the group of the OutComponent + */ +void CrFwOutCmpSetGroup(FwSmDesc_t smDesc, CrFwGroup_t group); + +/** + * Return the time stamp attribute of the OutComponent. + * By default, the time stamp is set when the OutComponent is loaded into the OutLoader + * (see <code>::CrFwOutLoaderLoad</code>) but its value can be overridden with + * function <code>::CrFwOutCmpSetTimeStamp</code>. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the time stamp attribute of the OutComponent + */ +CrFwTimeStamp_t CrFwOutCmpGetTimeStamp(FwSmDesc_t smDesc); + +/** + * Set the time stamp attribute of the OutComponent. + * By default, the time stamp is set when the OutComponent is loaded into the OutLoader + * (see <code>::CrFwOutLoaderLoad</code>). + * This function can be used to override this default setting. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @param timeStamp the time stamp of the OutComponent + */ +void CrFwOutCmpSetTimeStamp(FwSmDesc_t smDesc, CrFwTimeStamp_t timeStamp); + +/** + * Return the source of the OutComponent. + * The source of the OutComponent is set when the OutComponent is + * created by function <code>::CrFwOutFactoryMakeOutCmp</code> and cannot be changed + * afterwards. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the source of the OutComponent + */ +CrFwDestSrc_t CrFwOutCmpGetSrc(FwSmDesc_t smDesc); + +/** + * Return the type of the OutComponent. + * The type of the OutComponent is set when the OutComponent is + * created by function <code>::CrFwOutFactoryMakeOutCmp</code> and cannot be changed + * afterwards. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the type of the OutComponent + */ +CrFwServType_t CrFwOutCmpGetServType(FwSmDesc_t smDesc); + +/** + * Return the sub-type of the OutComponent. + * The sub-type of the OutComponent is set when the OutComponent is + * created by function <code>::CrFwOutFactoryMakeOutCmp</code> and cannot be changed + * afterwards. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the sub-type of the OutComponent + */ +CrFwServType_t CrFwOutCmpGetServSubType(FwSmDesc_t smDesc); + +/** + * Return the discriminant of the OutComponent. + * The discriminant of the OutComponent is set when the OutComponent is + * created by function <code>::CrFwOutFactoryMakeOutCmp</code> but + * can subsequently be changed through function + * <code>::CrFwOutCmpSetDiscriminant</code>. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the discriminant of the OutComponent + */ +CrFwDiscriminant_t CrFwOutCmpGetDiscriminant(FwSmDesc_t smDesc); + +/** + * Set the discriminant of the OutComponent. + * The default value of the discriminant of the OutComponent is set when the OutComponent + * is created by function <code>::CrFwOutFactoryMakeOutCmp</code>. + * This function allows this default value to be changed. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @param discriminant the discriminant of the OutComponent + */ +void CrFwOutCmpSetDiscriminant(FwSmDesc_t smDesc, CrFwDiscriminant_t discriminant); + +/** + * Set the acknowledge level for the command encapsulated in the OutComponent. + * This function should only be called on OutComponents which encapsulate an + * out-going command (but no check is performed that this is actually the + * case). + * @param smDesc the descriptor of the Base State Machine of the OutComponent. + * @param accept 1 if acknowledge of command acceptance is desired, 0 otherwise. + * @param start 1 if acknowledge of command start is desired, 0 otherwise. + * @param progress 1 if acknowledge of command progress is desired, 0 otherwise. + * @param term 1 if acknowledge of command acceptance termination is desired, 0 otherwise. + */ +void CrFwOutCmpSetAckLevel(FwSmDesc_t smDesc, CrFwBool_t accept, CrFwBool_t start, + CrFwBool_t progress, CrFwBool_t term); + +/** + * Return the acknowledge level for command acceptance for the command encapsulated in the + * OutComponent. + * If the OutComponent does not hold a command, the behaviour of the function is undefined. + * @param smDesc the descriptor of the Base State Machine of the OutComponent. + * @return 1 if command acceptance is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwOutCmpIsAcceptAck(FwSmDesc_t smDesc); + +/** + * Return the acknowledge level for command start for the command encapsulated in the + * OutComponent. + * If the OutComponent does not hold a command, the behaviour of the function is undefined. + * @param smDesc the descriptor of the Base State Machine of the OutComponent. + * @return 1 if command start is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwOutCmpIsStartAck(FwSmDesc_t smDesc); + +/** + * Return the acknowledge level for command progress for the command encapsulated in the + * OutComponent. + * If the OutComponent does not hold a command, the behaviour of the function is undefined. + * @param smDesc the descriptor of the Base State Machine of the OutComponent. + * @return 1 if command progress is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwOutCmpIsProgressAck(FwSmDesc_t smDesc); + +/** + * Return the acknowledge level for command termination for the command encapsulated in the + * OutComponent. + * If the OutComponent does not hold a command, the behaviour of the function is undefined. + * @param smDesc the descriptor of the Base State Machine of the OutComponent. + * @return 1 if command termination is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwOutCmpIsTermAck(FwSmDesc_t smDesc); + +/** + * Return the start address of the parameter area of the OutComponent. + * The OutComponent is encapsulated in a packet. + * The parameter area of the OutComponent is the part of the packet which is reserved to the + * storage of the parameters of the OutComponent. + * The parameter area consists of an uninterrupted sequence of bytes. + * The size of the parameter area is returned by function <code>::CrFwOutCmpGetParLength</code>. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the start address of the OutComponent parameter area. + */ +char* CrFwOutCmpGetParStart(FwSmDesc_t smDesc); + +/** + * Return the length in bytes of the parameter area of the OutComponent. + * The OutComponent is encapsulated in a packet. + * The parameter area of the OutComponent is the part of the packet which is reserved to the + * storage of the parameters of the OutComponent. + * The parameter area consists of an uninterrupted sequence of bytes. + * The start address of the parameter area is returned by function <code>::CrFwOutCmpGetParStart</code>. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the length in bytes of the OutComponent parameter area + */ +CrFwPcktLength_t CrFwOutCmpGetParLength(FwSmDesc_t smDesc); + +/** + * Return the length in bytes of the packet to which the OutComponent is serialized. + * The length returned by this function covers both the packet header and the packet parameter area. + * The length of the packet parameter area is returned by function <code>::CrFwOutCmpGetParLength</code>. + * @param smDesc the descriptor of the Base State Machine of the OutComponent + * @return the length in bytes of the OutComponent packet + */ +CrFwPcktLength_t CrFwOutCmpGetLength(FwSmDesc_t smDesc); + +#endif /* CRFW_OUTCMP_H_ */ diff --git a/CrFramework/src/OutFactory/CrFwOutFactory.c b/CrFramework/src/OutFactory/CrFwOutFactory.c new file mode 100644 index 0000000000000000000000000000000000000000..b8cfdd2975b3b06c4dfa6ee45165a7bf3a90641a --- /dev/null +++ b/CrFramework/src/OutFactory/CrFwOutFactory.c @@ -0,0 +1,376 @@ +/** + * @file + * + * Implementation of OutFactory component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwOutFactoryUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "OutCmp/CrFwOutCmp.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "OutRegistry/CrFwOutRegistry.h" +#include "CrFwOutFactory.h" +#include "CrFwTime.h" +/* Include FW Profile files */ +#include "FwPrConfig.h" +#include "FwPrDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwSmDCreate.h" +#include "FwPrCore.h" + +/** Array holding the keys of the OutComponents kinds */ +static CrFwCmdRepKindKey_t outCmpKindKey[CR_FW_OUTCMP_NKINDS]; + +/** Array of service descriptors (see <code>CrFwServDesc_t</code>). */ +static CrFwOutCmpKindDesc_t outCmpKindDesc[CR_FW_OUTCMP_NKINDS] = CR_FW_OUTCMP_INIT_KIND_DESC; + +/** The pre-allocated OutComponent instances */ +static FwSmDesc_t outCmp[CR_FW_OUTFACTORY_MAX_NOF_OUTCMP]; + +/** The data for the pre-allocated OutComponent instances */ +static CrFwCmpData_t outCmpData[CR_FW_OUTFACTORY_MAX_NOF_OUTCMP]; + +/** The component-specific data for the pre-allocated OutReport instances */ +static CrFwOutCmpData_t outCmpSpecificData[CR_FW_OUTFACTORY_MAX_NOF_OUTCMP]; + +/** The in-use status of each pre-allocated OutComponent instance */ +static CrFwBool_t outCmpInUse[CR_FW_OUTFACTORY_MAX_NOF_OUTCMP]; + +/** The number of currently allocated OutComponents */ +static CrFwOutFactoryPoolIndex_t nOfAllocatedOutCmp; + +/** + * The index of the next free position in the pool of pre-allocated OutComponent instances + * (a value of CR_FW_OUTFACTORY_MAX_NOF_OUTCMP indicates that all OutComponent instances + * have been allocated and there are no free positions left) */ +static CrFwOutFactoryPoolIndex_t nextFreePos; + +/** The total number of OutComponents allocated since the OutFactory was reset */ +static CrFwInstanceId_t nOfAllocatedOutCmpSinceReset = 0; + +/** The singleton instance of the OutFactory */ +static FwSmDesc_t outFactory; + +/** The data for the OutFactory singleton. */ +static CrFwCmpData_t outFactoryData; + +/** The part of the command or report identifier which depends on the application identifier */ +static CrFwInstanceId_t apidInstanceId = CR_FW_HOST_APP_ID << (sizeof(CrFwInstanceId_t)*8-CR_FW_NBITS_APP_ID); + +/** The highest value of cmd/rep identifier (before overflowing into the application identifier bits) */ +static CrFwInstanceId_t maxInstanceId = (1 << (sizeof(CrFwInstanceId_t)*8-CR_FW_NBITS_APP_ID)); + +/** + * Initialization action for OutFactory. + * This function allocates the memory for the OutFactory data structures and + * initializes the array of descriptors <code>::outCmpKindDesc</code>. + * The outcome of the initialization action is "successful" in all cases except when + * the memory allocation operation fails. + * @param initPr the Initialization Procedure of the OutFactory + */ +static void OutFactoryInitAction(FwPrDesc_t initPr); + +/** + * Configuration action for OutFactory. + * This function releases all the OutComponents which are currently allocated. + * After this function has been called, any OutComponent which is still in + * use within the application is no longer valid and should be discarded. + * + * This function also resets the counter used to initialize the instance + * identifier of the OutComponents created by the OutFactory. + * After reset, the first OutComponent made by the OutFactory will have its + * instance identifier set to 1. + * + * The outcome of the initialization action is always: "successful" + * @param initPr the Initialization Procedure of the OutFactory + */ +static void OutFactoryConfigAction(FwPrDesc_t initPr); + +/** + * Shutdown action for OutFactory. + * This function releases the memory which was allocated when the OutFactory was + * initialized and it sets the number of allocated OutComponents to zero. + * After this function has been called, any OutComponent which is still in + * use within the application is no longer valid and should be discarded. + * @param smDesc the OutFactory state machine + */ +static void OutFactoryShutdownAction(FwSmDesc_t smDesc); + +/* ------------------------------------------------------------------------------------ */ +FwSmDesc_t CrFwOutFactoryMake() { + FwPrDesc_t resetPr, execPr, initPr; + + if (outFactory != NULL) { + return outFactory; + } + + /* Extend the Base Component */ + outFactory = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the OutFactory Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, &OutFactoryConfigAction); + + /* Create the Initialization Procedure for the OuFactory Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitAction, &OutFactoryInitAction); + + /* Override the Shutdown Action for the OuFactory Component */ + FwSmOverrideAction(outFactory, &CrFwBaseCmpDefShutdownAction, &OutFactoryShutdownAction); + + /* Get the Dummy Execution Procedure for the OuFactory Component */ + execPr = CrFwBaseCmpGetDummyExecProc(); + + /* Initialize the data for the requested SM */ + outFactoryData.outcome = 1; + outFactoryData.initProc = initPr; + outFactoryData.resetProc = resetPr; + outFactoryData.execProc = execPr; + outFactoryData.instanceId = 0; + outFactoryData.typeId = CR_FW_OUTFACTORY_TYPE; + + /* Attach the data to the OutFactory state machine and to its procedures. */ + FwSmSetData(outFactory, &outFactoryData); + FwPrSetData(outFactoryData.initProc, &outFactoryData); + FwPrSetData(outFactoryData.resetProc, &outFactoryData); + + /* Start the OuFactory */ + FwSmStart(outFactory); + + return outFactory; +} + +/* ------------------------------------------------------------------------------------ */ +FwSmDesc_t CrFwOutFactoryMakeOutCmp(CrFwServType_t type, CrFwServSubType_t subType, + CrFwDiscriminant_t discriminant, CrFwPcktLength_t length) { + CrFwOutFactoryPoolIndex_t j, k, freePos; + CrFwCmdRepKindIndex_t kindIndex; + CrFwCmdRepKindKey_t targetKey; + CrFwPckt_t pckt; + CrFwPcktLength_t len; + + if (nextFreePos == CR_FW_OUTFACTORY_MAX_NOF_OUTCMP) { /* All positions are occupied */ + CrFwSetAppErrCode(crOutCmpAllocationFail); + return NULL; + } + + targetKey = (CrFwCmdRepKindKey_t)(type*CR_FW_MAX_DISCRIMINANT*CR_FW_MAX_SERV_SUBTYPE+subType*CR_FW_MAX_DISCRIMINANT+discriminant); + kindIndex = CrFwFindCmdRepKindIndex(outCmpKindKey, CR_FW_OUTCMP_NKINDS, targetKey); + if (kindIndex == CR_FW_OUTCMP_NKINDS) { + CrFwSetAppErrCode(crIllOutCmpKind); + return NULL; + } + + if (length == 0) + len = outCmpKindDesc[kindIndex].pcktLength; + else + len = length; + + pckt = CrFwPcktMake(len); /* The packet length is assumed to be non-negative */ + if (pckt == NULL) { + CrFwSetAppErrCode(crOutCmpAllocationFail); + return NULL; + } + + freePos = nextFreePos; + outCmpSpecificData[freePos].index = CrFwOutRegistryGetCmdRepIndex(type,subType); + outCmpSpecificData[freePos].isEnabled = outCmpKindDesc[kindIndex].isEnabled; + outCmpSpecificData[freePos].isReady = outCmpKindDesc[kindIndex].isReady; + outCmpSpecificData[freePos].isRepeat = outCmpKindDesc[kindIndex].isRepeat; + outCmpSpecificData[freePos].serialize = outCmpKindDesc[kindIndex].serialize; + outCmpSpecificData[freePos].update= outCmpKindDesc[kindIndex].update; + outCmpSpecificData[freePos].factoryPoolIndex = freePos; + + CrFwPcktSetCmdRepType(pckt,outCmpKindDesc[kindIndex].cmdRepType); + CrFwPcktSetSrc(pckt,CR_FW_HOST_APP_ID); + CrFwPcktSetGroup(pckt,0); + CrFwPcktSetServType(pckt,type); + CrFwPcktSetServSubType(pckt,subType); + CrFwPcktSetDiscriminant(pckt,discriminant); + CrFwPcktSetSeqCnt(pckt,0); + + outCmpSpecificData[freePos].pckt = pckt; + + nOfAllocatedOutCmpSinceReset++; + if (nOfAllocatedOutCmpSinceReset == maxInstanceId) + nOfAllocatedOutCmpSinceReset = 0; + outCmpData[freePos].instanceId = (CrFwInstanceId_t)(apidInstanceId + nOfAllocatedOutCmpSinceReset); + + /* Reset the OutComponent */ + CrFwCmpReset(outCmp[freePos]); + + nOfAllocatedOutCmp++; + outCmpInUse[freePos] = 1; + + /* Find the next free position in the pool of pre-allocated OutComponent instances */ + k = (CrFwOutFactoryPoolIndex_t)(freePos + 1); + for (j=0; j<(CR_FW_OUTFACTORY_MAX_NOF_OUTCMP-1); j++) { + if (k == CR_FW_OUTFACTORY_MAX_NOF_OUTCMP) + k = 0; + if (outCmpInUse[k] == 0) { + nextFreePos = k; + return (outCmp[freePos]); /* Next free position has been found */ + } + k = (CrFwOutFactoryPoolIndex_t)(k + 1); + } + + nextFreePos = CR_FW_OUTFACTORY_MAX_NOF_OUTCMP; /* There are no free positions left */ + return (outCmp[freePos]); +} + +/* ------------------------------------------------------------------------------------ */ +void CrFwOutFactoryReleaseOutCmp(FwSmDesc_t outCmpInstance) { + CrFwCmpData_t* outCmpInstanceData = (CrFwCmpData_t*)FwSmGetData(outCmpInstance); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(outCmpInstanceData->cmpSpecificData); + CrFwOutFactoryPoolIndex_t posToBeFreed; + + posToBeFreed = cmpSpecificData->factoryPoolIndex; + if (outCmpInUse[posToBeFreed] == 1) { + outCmpInUse[posToBeFreed] = 0; + nOfAllocatedOutCmp--; + nextFreePos = posToBeFreed; + CrFwPcktRelease(outCmpSpecificData[posToBeFreed].pckt); + outCmpSpecificData[posToBeFreed].pckt = NULL; + return; + } + CrFwSetAppErrCode(crOutCmpRelErr); + + return; +} + +/* ------------------------------------------------------------------------------------ */ +CrFwOutFactoryPoolIndex_t CrFwOutFactoryGetNOfAllocatedOutCmp() { + return nOfAllocatedOutCmp; +} + +/* ------------------------------------------------------------------------------------ */ +CrFwOutFactoryPoolIndex_t CrFwOutFactoryGetMaxNOfOutCmp() { + return CR_FW_OUTFACTORY_MAX_NOF_OUTCMP; +} + +/* ------------------------------------------------------------------------------------ */ +CrFwInstanceId_t CrFwOutFactoryGetNOfInstanceId() { + return maxInstanceId; +} + +/*------------------------------------------------------------------------------------*/ +static void OutFactoryInitAction(FwPrDesc_t initPr) { + CrFwCounterU2_t i; + CrFwCmdRepKindIndex_t j; + FwPrDesc_t outCmpInitPr, outCmpResetPr, outCmpExecPr; + CRFW_UNUSED(initPr); + + /* Create the pre-allocated OutComponents */ + for (i=0; i<CR_FW_OUTFACTORY_MAX_NOF_OUTCMP; i++) { + /* Create the i-th OutCmp as an extension of the Base OutComponent */ + outCmp[i] = FwSmCreateDer(CrFwOutCmpMakeBase()); + + /* Create the Reset Procedure for the OutComponent */ + outCmpResetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + outCmpData[i].resetProc = outCmpResetPr; + + /* Create the Initialization Procedure for the OutComponent */ + outCmpInitPr = FwPrCreateDer(CrFwCmpGetInitProc()); + outCmpData[i].initProc = outCmpInitPr; + + /* Get the Dummy Execution Procedure for the OutComponent */ + outCmpExecPr = CrFwBaseCmpGetDummyExecProc(); + outCmpData[i].execProc = outCmpExecPr; + + /* Set the OutComponent type */ + outCmpData[i].typeId = CR_FW_OUTCMP_TYPE; + + /* Set the pointer to the component-specific data */ + outCmpData[i].cmpSpecificData = &outCmpSpecificData[i]; + + /* Attach the data to the OutComponent state machine and to its procedures. */ + FwSmSetData(outCmp[i], &outCmpData[i]); + FwSmSetData(FwSmGetEmbSm(outCmp[i], CR_FW_BASE_STATE_CONFIGURED), &outCmpData[i]); + FwPrSetData(outCmpData[i].initProc, &outCmpData[i]); + FwPrSetData(outCmpData[i].resetProc, &outCmpData[i]); + + /* Start and initialize the OutComponent */ + FwSmStart(outCmp[i]); + CrFwCmpInit(outCmp[i]); + } + + /* Initialize the array holding the keys of the OutCommand kinds */ + for (j=0; j<CR_FW_OUTCMP_NKINDS; j++) + outCmpKindKey[j] = (CrFwCmdRepKindKey_t)(outCmpKindDesc[j].servType*CR_FW_MAX_DISCRIMINANT*CR_FW_MAX_SERV_SUBTYPE + + outCmpKindDesc[j].servSubType*CR_FW_MAX_DISCRIMINANT+outCmpKindDesc[j].discriminant); +} + +/*------------------------------------------------------------------------------------*/ +static void OutFactoryConfigAction(FwPrDesc_t initPr) { + CrFwCounterU2_t i; + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(initPr); + + for (i=0; i<CR_FW_OUTFACTORY_MAX_NOF_OUTCMP; i++) + if (outCmpInUse[i] != 0) { + outCmpInUse[i] = 0; + CrFwPcktRelease(outCmpSpecificData[i].pckt); + outCmpSpecificData[i].pckt = NULL; + } + + + nOfAllocatedOutCmp = 0; + nOfAllocatedOutCmpSinceReset = 0; + nextFreePos = 0; + + cmpData->outcome = 1; +} + +/*------------------------------------------------------------------------------------*/ +static void OutFactoryShutdownAction(FwSmDesc_t smDesc) { + CrFwCounterU2_t i; + CRFW_UNUSED(smDesc); + + for (i=0; i<CR_FW_OUTFACTORY_MAX_NOF_OUTCMP; i++) { + /* Release memory allocated to OutComponent Initialization Procedure */ + FwPrReleaseDer(outCmpData[i].initProc); + /* Release memory allocated to OutComponent Reset Procedure */ + FwPrReleaseDer(outCmpData[i].resetProc); + /* Release memory allocated to OutComponent */ + FwSmReleaseDer(FwSmGetEmbSm(outCmp[i],CR_FW_BASE_STATE_CONFIGURED)); + FwSmReleaseDer(outCmp[i]); + /* Mark all OutComponents as not-in-use */ + outCmpInUse[i] = 0; + /* Release packet associated to OutComponent */ + if (outCmpSpecificData[i].pckt != NULL) + CrFwPcktRelease(outCmpSpecificData[i].pckt); + } + + nOfAllocatedOutCmp = 0; +} + diff --git a/CrFramework/src/OutFactory/CrFwOutFactory.h b/CrFramework/src/OutFactory/CrFwOutFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..723d832079385313f70bb56c112b537b1cb08621 --- /dev/null +++ b/CrFramework/src/OutFactory/CrFwOutFactory.h @@ -0,0 +1,218 @@ +/** + * @file + * @ingroup outMngGroup + * Definition of the OutFactory component. + * + * The OutFactory component offers an interface through which OutComponents + * (see <code>CrFwOutCmp.h</code>) can be allocated and released. + * Applications need OutComponents to encapsulate out-going commands or reports. + * This interface provides the factory functions through which an OutComponent + * can be created and released. + * + * The OutFactory is implemented as an extension of the Base Component of + * <code>CrFwBaseCmp.h</code>. + * The OutFactory is a singleton component. + * This interface provides a function to create the OutFactory and it provides + * a function to create an OutComponent of a specified kind. + * + * The OutFactory maintains a pool of pre-allocated OutComponents (the size of the pool + * is defined in <code>CrFwOutFactoryUserPar.h</code>). + * Memory for the pool is allocated when the OutFactory is initialized and is never + * released afterwards. + * Items in the pool are marked as "in use" when they are allocated to an application + * and are marked as "not in use" when they are released. + * When the OutFactory is reset, all the items in the pool are marked as "not in use". + * No memory allocation operations (<code>malloc/free</code>) are therefore performed when + * OutComponents are allocated or released. + * + * <b>Mode of Use of an OutFactory Component</b> + * + * The configuration of the OutFactory component is defined statically in + * <code>CrFwOutFactoryUserPar.h</code>. + * + * The OutFactory is created with function <code>::CrFwOutFactoryMake</code>. + * After being created, the OutFactory must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the OutFactory State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * After being configured, the OutFactory is ready to manage the creation and release + * process for OutComponents. + * An OutComponent is created with function <code>::CrFwOutFactoryMakeOutCmp</code> and it + * is released with function <code>::CrFwOutFactoryReleaseOutCmp</code>. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_OUTFACTORY_H_ +#define CRFW_OUTFACTORY_H_ + +/* Include Framework files */ +#include "CrFwConstants.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmCore.h" + +/** + * Factory function for the singleton instance of the OutFactory. + * The first time it is called, this function creates the OutFactory singleton instance. + * Subsequent calls return the same instance. + * The first time this function is called, it returns the OutFactory in state CREATED. + * @return the OutFactory singleton instance. + */ +FwSmDesc_t CrFwOutFactoryMake(); + +/** + * Make function for an OutComponent. + * This function returns an OutComponent in state CONFIGURED. + * The OutComponent is reset before being returned to the caller of this + * function (its State Execution Counter is guaranteed to be equal to zero). + * + * The caller specifies the kind of OutComponent it wishes by specifying its type, sub-type, + * discriminant and the packet length. + * Of these four parameters, the first three (type, sub-type, and discriminant) are mandatory whereas + * for the last one (length) a dummy value of zero is possible. + * Given the type, sub-type and discriminant, the function looks for a matching entry in the + * <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer. + * If no matching entry is found (i.e. if no entry is found with the same values of type, sub-type + * and discriminant), then the function sets the application error code to <code>crOutCmpAllocationFail</code> + * and returns a value of NULL. + * If instead a matching entry is found, two options are possible: + * - If the length parameter is set to zero, then the function creates and returns an OutComponent with the + * characteristics given by the matching entry in the <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer. + * - If instead the length parameter has a non-zero value, then the function creates and returns an OutComponent + * with the characteristics given by the matching entry in the <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> + * initializer with the exception of the packet length which is set equal to the value specified + * in the function call. + * . + * Thus, the length value specified in the function call may be used to override the length + * value specified in the <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer). + * This override mechanism is useful for reports or commands whose length must be determined + * dynamically (as opposed to being statically determined in the + * <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer). + * + * When an OutComponent is returned by this function, it has the following attributes set: + * - The OutComponent packet length + * - The OutComponent command/report type flag (which defines whether the OutComponent is a + * report or a command) + * - The OutComponent source attribute + * - The OutComponent group attribute + * - The OutComponent service type + * - The OutComponent service sub-type + * - The OutComponent discriminant + * - The OutComponent sequence counter + * - The OutComponent instance identifier + * . + * The values of type, sub-type, command/report flag and discriminant are derived from the information in the + * <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer. The type and sub-type cannot be changed after + * an OutComponent has been created. Applications can instead override the default setting of the + * discriminant by using function <code>::CrFwOutCmpSetDiscriminant</code>. + * + * As explained above, the value of the packet length is either derived from the + * <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer (if the function is called with the + * length parameter set to zero) or else it is equal to the length parameter in the function call. + * + * The value of the instance identifier is built as follows. + * Let n be the number of OutComponents made by the factory since it was last reset; + * let APP_ID be the application identifier (see <code>#CR_FW_HOST_APP_ID</code>); let + * m be the number of bits reserved for the application identifier (see + * <code>#CR_FW_NBITS_APP_ID</code>); and let s be the number of bits of the instance + * identifier. + * The instance identifier is then given by: APP_ID*(2**(s-m))+n. + * In this formula, the value of n is incremented by 1 every time a new OutComponent is + * created by the OutFactory and it is reset to 0 when it reaches APP_ID*(2**(s-m)). + * + * The value of the sequence counter is initialized to zero. + * + * The value of the source attribute is set equal to the identifier of the host application + * (namely <code>#CR_FW_HOST_APP_ID</code>). + * + * The value of the group attribute is set to a default value of zero. Applications can override + * this default setting by using function <code>::CrFwOutCmpSetGroup</code>. + * + * This function allocates the memory for the new OutComponent from a pool of pre-allocated + * memory which is created when the OutFactory is initialized (see + * <code>::OutFactoryInitAction</code>). + * If no free memory is available in the factory pool, this function returns NULL. + * Allocation memory failure results in the application error code being set + * to <code>crOutCmpAllocationFail</code>. + * + * When an OutComponent created by this function is no longer needed, it should be + * returned to the factory by calling <code>CrFwOutCmpRelease</code>. + * + * If the OutFactory is reset, then all the OutComponents which had been created + * by the factory are released. + * + * @param type the service type of the OutComponent + * @param subType the service sub-type of the OutComponent + * @param discriminant the discriminant of the OutComponent + * @param length either zero (if the packet length is to be taken from the + * <code>::CR_FW_OUTCMP_INIT_KIND_DESC</code> initializer) or the packet length + * @return a new OutComponent or NULL if it was not possible to allocate the memory + * for the OutComponent. + */ +FwSmDesc_t CrFwOutFactoryMakeOutCmp(CrFwServType_t type, CrFwServSubType_t subType, + CrFwDiscriminant_t discriminant, CrFwPcktLength_t length); + +/** + * Release function for an OutComponent. + * The argument of this function must be an OutComponent which was created using function + * <code>::CrFwOutFactoryMakeOutCmp</code>. + * This function releases the memory which was allocated to the OutComponent. + * After this function is called, the OutComponent cannot be used any longer. + * The function does not perform any checks on the existence or status of the + * OutComponent. + * An attempt to use an OutComponent which has been released will result in undefined behaviour. + * + * An attempt to release an OutComponent which had already been released, or to release a + * non-existent OutComponent will result in undefined behaviour and in the application + * error code being set to: <code>::crOutCmpRelErr</code>. + * + * @param outCmpInstance the OutComponent to be released + */ +void CrFwOutFactoryReleaseOutCmp(FwSmDesc_t outCmpInstance); + +/** + * Return the number of OutComponents which are currently allocated. + * This function returns the number of OutComponents which have been successfully + * allocated through calls to <code>::CrFwOutFactoryMakeOutCmp</code> and have not yet been + * released through calls to <code>::CrFwOutFactoryReleaseOutCmp</code>. + * @return the number of OutComponents which are currently allocated. + */ +CrFwOutFactoryPoolIndex_t CrFwOutFactoryGetNOfAllocatedOutCmp(); + +/** + * Return the maximum number of OutComponents which may be allocated at any one time. + * @return the maximum number of OutComponents which may be allocated at any one time + */ +CrFwOutFactoryPoolIndex_t CrFwOutFactoryGetMaxNOfOutCmp(); + +/** + * Return the number of distinct instance identifiers supported by the OutFactory. + * The OutFactory allocates the instance identifier of an OutComponent as explained + * in the documentation of <code>::CrFwOutFactoryMakeOutCmp</code>. + * @return the maximum number of OutComponents which may be allocated at any one time + */ +CrFwInstanceId_t CrFwOutFactoryGetNOfInstanceId(); + +#endif /* CRFW_OUTFACTORY_H_ */ diff --git a/CrFramework/src/OutLoader/CrFwOutLoader.c b/CrFramework/src/OutLoader/CrFwOutLoader.c new file mode 100644 index 0000000000000000000000000000000000000000..e33cd7c6d26227b88efc726ca96905e439235dd9 --- /dev/null +++ b/CrFramework/src/OutLoader/CrFwOutLoader.c @@ -0,0 +1,149 @@ +/** + * @file + * + * Implementation of OutLoader State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwOutLoaderUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "CrFwTime.h" +#include "CrFwOutLoader.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "Pckt/CrFwPcktQueue.h" +#include "OutManager/CrFwOutManager.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** Descriptor of the OutLoader Singleton */ +static FwSmDesc_t outLoader = NULL; + +/** The data structure for the OutLoader Singleton */ +static CrFwCmpData_t outLoaderData; + +/** The function implementing the OutManager Selection Operation */ +static CrFwOutManagerSelect_t outManagerSelect = CR_FW_OUTLOADER_OUTMANAGER_SELECT; + +/** The function implementing the OutManager Activation Operation */ +static CrFwOutManagerActivate_t outManagerActivate = CR_FW_OUTLOADER_OUTMANAGER_ACTIVATE; + +/** The function implementing the Initialization Check */ +static FwPrAction_t initCheck = CR_FW_OUTLOADER_INITCHECK; + +/** The function implementing the Initialization Action */ +static FwPrAction_t initAction = CR_FW_OUTLOADER_INITACTION; + +/** The function implementing the Configuration Check */ +static FwPrAction_t configCheck = CR_FW_OUTLOADER_CONFIGCHECK; + +/** The function implementing the Configuration Action */ +static FwPrAction_t configAction = CR_FW_OUTLOADER_CONFIGACTION; + +/** The function implementing the Shutdown Action */ +static FwSmAction_t shutdownAction = CR_FW_OUTLOADER_SHUTDOWNACTION; + + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwOutLoaderMake() { + FwPrDesc_t resetPr, execPr, initPr; + + if (outLoader != NULL) { + return outLoader; /* The requested SM has already been created */ + } + + /* Create the requested SM as an extension of the Base Component SM */ + outLoader = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the OutLoader Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigCheck, configCheck); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, configAction); + + /* Create the Initialization Procedure for the OutLoader Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefInitCheck, initCheck); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefInitAction, initAction); + + /* Get the Dummy Execution Procedure for the OutLoader Component */ + execPr = CrFwBaseCmpGetDummyExecProc(); + + /* Override the Shutdown Action for the OutStream Component */ + FwSmOverrideAction(outLoader, &CrFwBaseCmpDefShutdownAction, shutdownAction); + + /* Initialize the data for the requested SM */ + outLoaderData.outcome = 1; + outLoaderData.initProc = initPr; + outLoaderData.resetProc = resetPr; + outLoaderData.execProc = execPr; + outLoaderData.instanceId = 0; + outLoaderData.typeId = CR_FW_OUTLOADER_TYPE; + + /* Attach the data to the OutLoader state machine and to its procedures. */ + FwSmSetData(outLoader, &outLoaderData); + FwPrSetData(outLoaderData.initProc, &outLoaderData); + FwPrSetData(outLoaderData.resetProc, &outLoaderData); + + /* Start the OutLoader */ + FwSmStart(outLoader); + + return outLoader; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutLoaderLoad(FwSmDesc_t outCmp) { + FwSmDesc_t selectedOutManager; + + selectedOutManager = outManagerSelect(outCmp); + CrFwOutManagerLoad(selectedOutManager, outCmp); + outManagerActivate(selectedOutManager); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwOutLoaderDefOutManagerSelect(FwSmDesc_t outCmp) { + CRFW_UNUSED(outCmp); + return CrFwOutManagerMake(0); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutLoadDefOutManagerActivate(FwSmDesc_t outManager) { + CRFW_UNUSED(outManager); + return; +} + diff --git a/CrFramework/src/OutLoader/CrFwOutLoader.h b/CrFramework/src/OutLoader/CrFwOutLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..6f27414f1b00e3338df342065154ed75f2197d29 --- /dev/null +++ b/CrFramework/src/OutLoader/CrFwOutLoader.h @@ -0,0 +1,146 @@ +/** + * @file + * @ingroup outMngGroup + * Definition of the OutLoader component. + * + * After a user application has obtained an OutComponent component from an OutFactory, + * it loads it into the OutLoader. + * This component is responsible for selecting the appropriate OutManager to process + * the out-going command or report. + * For this purpose, the OutLoader maintains a list of all OutManagers in an application + * (the List of OutManagers or LOM). + * + * The OutLoader is defined as an extension of the Base Component (see <code>CrFwBaseCmp.h</code>). + * The OutLoader component offers one operation – the Load operation – to load an OutComponent + * into an OutLoader. + * This operation executes the behaviour shown in the figure below. + * + * When the Load operation is called, the OutLoader decides to which OutManager in the LOM to load + * an OutComponent. + * The policy for selecting the OutManager in the LOM is an adaptation point. + * After the OutComponent is loaded into the selected OutManager, the procedure may activate + * the selected OutManager (i.e. it may release the thread which is controlling the execution of + * the selected OutManager). + * This is useful where there is a need to process the out-going command or report as soon as + * it is loaded into the OutManager (since the command or report is only processed when the + * OutManager is executed). + * + * <b>Mode of Use of an OutLoader Component</b> + * + * The configuration of the OutLoader components is defined statically in + * <code>CrFwOutLoaderUserPar.h</code>. + * + * The OutLoader component is created with function <code>::CrFwOutLoaderMake</code>. + * After being created, the OutLoader must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the OutLoader State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * Note that the OutLoader is a singleton and an application can only have one instance of + * an OutLoader. + * + * An OutLoader offers a Load operation (<code>::CrFwOutLoaderLoad</code>) through which + * an OutComponent can be loaded into an OutManager. + * This operation is normally called by a user component after it has configured an OutComponent + * and when it wishes the OutComponent to be sent to its destination. + * + * The OutLoader autonomously selects the OutManager to which an OutComponent should be loaded. + * The selection algorithm is an adaptation point for the OutLoader. + * + * By default, the initialization, reset and shutdown operations are the same as on the + * Base Component but these operations are implemented as adaptation points so that the + * user has a chance to use them to initialize or reset the data structures which are used + * to control the selection of the OutManager where an out-going command or report is loaded. + * + * @image html OutLoaderLoad.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_OUT_LOADER_H_ +#define CRFW_OUT_LOADER_H_ + +#include "FwSmConstants.h" +#include "FwPrConstants.h" +#include "Pckt/CrFwPcktQueue.h" +#include "CrFwConstants.h" + +/** + * Type for a pointer to a function implementing the OutManager Selection Operation. + * The OutManager Selection Operation is one of the adaptation points of the framework. + * A function which implements this operation takes an OutComponent as argument and returns + * the OutManager where the OutComponent should be loaded. + */ +typedef FwSmDesc_t (*CrFwOutManagerSelect_t)(FwSmDesc_t outCmp); + +/** + * Type for a pointer to a function implementing the OutManager Activation Operation. + * The OutManager Activation Operation is one of the adaptation points of the framework. + * This function can be used to activate an OutManager. + * An OutManager is activated by releasing the thread which controls its execution. + */ +typedef void (*CrFwOutManagerActivate_t)(FwSmDesc_t outManager); + +/** + * Factory function to retrieve the OutLoader State Machine instance. + * The first time this function is called, it creates the OutLoader instance. + * Subsequent calls returns the same instance. + * + * The first time this function is called, it returns the OutLoader + * State Machine which has been started but which still needs to be initialized and + * configured. + * @return the descriptor of the OutLoader State Machine or NULL + * if the state machine could not be created. + */ +FwSmDesc_t CrFwOutLoaderMake(); + +/** + * Load an OutComponent into its OutManager. + * This function runs the procedure shown in the figure below. + * The procedure has two adaptation points which are defined by specifying two functions + * in <code>CrFwOutLoaderUserPar.h</code>. + * + * @image html OutLoaderLoad.png + * @param outCmp the descriptor of the OutComponent to be loaded in the OutManager + */ +void CrFwOutLoaderLoad(FwSmDesc_t outCmp); + +/** + * Default implementation of the OutManager Selection Operation. + * This implementation always returns the first OutManager (i.e. the OutManager returned + * by <code>::CrFwOutManagerMake</code> when it is called with an argument equal + * to zero). + * @param outCmp the descriptor of the OutComponent loaded into the OutLoader (this + * argument is not used in this implementation) + * @return the first OutManager + */ +FwSmDesc_t CrFwOutLoaderDefOutManagerSelect(FwSmDesc_t outCmp); + +/** + * Default implementation of the OutManager Activation Operation. + * This implementation returns without doing anything. + * @param outManager the descriptor of the OutManager to be activated (this + * argument is not used in this implementation) + */ +void CrFwOutLoadDefOutManagerActivate(FwSmDesc_t outManager); + +#endif /* CRFW_OUT_LOADER_H_ */ diff --git a/CrFramework/src/OutManager/CrFwOutManager.c b/CrFramework/src/OutManager/CrFwOutManager.c new file mode 100644 index 0000000000000000000000000000000000000000..398e3dc7f5d0735a1695a9d3a231d80618b766fe --- /dev/null +++ b/CrFramework/src/OutManager/CrFwOutManager.c @@ -0,0 +1,303 @@ +/** + * @file + * + * Implementation of OutManager State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwOutManagerUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "CrFwTime.h" +#include "CrFwOutManager.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "Pckt/CrFwPcktQueue.h" +#include "OutFactory/CrFwOutFactory.h" +#include "OutRegistry/CrFwOutRegistry.h" +#include "OutCmp/CrFwOutCmp.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** The sizes of the POCL in the OutManager components. */ +static CrFwCounterU2_t outManagerPoclSize[CR_FW_NOF_OUTMANAGER] = CR_FW_OUTMANAGER_POCLSIZE; + +/** The descriptors of the OutManager State Machines. */ +static FwSmDesc_t outManagerDesc[CR_FW_NOF_OUTMANAGER]; + +/** The data structures for the OutManager State Machines and their Procedures. */ +static CrFwCmpData_t outManagerData[CR_FW_NOF_OUTMANAGER]; + +/** The component-specific data for the OutManager instances */ +static CrFwOutManagerData_t outManagerCmpSpecificData[CR_FW_NOF_OUTMANAGER]; + +/** + * Initialization action for OutManagers. + * This function allocates the memory for the OutManager data structures and + * initializes them. + * The outcome of the initialization action is always "success" (the situation + * where the memory allocation fails is not handled). + * @param initPr the Initialization Procedure of the OutManager + */ +static void OutManagerInitAction(FwPrDesc_t initPr); + +/** + * Configuration action for OutManagers. + * This function resets the POCL and releases all OutComponents in the POCL. + * The outcome of the initialization action is always: "success" + * @param initPr the Initialization Procedure of the OutManager + */ +static void OutManagerConfigAction(FwPrDesc_t initPr); + +/** + * Shutdown action for OutManager. + * This function resets the POCL and releases all OutComponents in the POCL. + * @param smDesc the OutManager state machine + */ +static void OutManagerShutdownAction(FwSmDesc_t smDesc); + +/** + * Implement the logic of the Execution Procedure (see figure below). + * This function is executed every time the Execution Procedure of the OutManager + * is executed. + * @image html OutManagerExecution.png + * @param execPr the Execution Procedure of the OutManager + */ +static void OutManagerExecAction(FwPrDesc_t execPr); + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwOutManagerMake(CrFwInstanceId_t i) { + FwPrDesc_t resetPr, execPr, initPr; + + if (i >= CR_FW_NOF_OUTMANAGER) { + CrFwSetAppErrCode(crOutManagerIllId); + return NULL; + } + + if (outManagerDesc[i] != NULL) { + return outManagerDesc[i]; /* The requested SM has already been created */ + } + + /* Create the requested SM as an extension of the base component SM */ + outManagerDesc[i] = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the OutManager Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, &OutManagerConfigAction); + + /* Create the Initialization Procedure for the OutManager Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitAction, &OutManagerInitAction); + + /* Create the Execution Procedure for the OutManager Component */ + execPr = FwPrCreateDer(CrFwBaseCmpGetDummyExecProc()); + FwPrOverrideAction(execPr, &CwFwBaseCmpDummyExecAction, &OutManagerExecAction); + + /* Override the Shutdown Action for the OutManager Component */ + FwSmOverrideAction(outManagerDesc[i], &CrFwBaseCmpDefShutdownAction, &OutManagerShutdownAction); + + /* Initialize the data for the requested SM */ + outManagerData[i].outcome = 1; + outManagerData[i].initProc = initPr; + outManagerData[i].resetProc = resetPr; + outManagerData[i].execProc = execPr; + outManagerData[i].instanceId = i; + outManagerData[i].typeId = CR_FW_OUTMANAGER_TYPE; + outManagerData[i].cmpSpecificData = &outManagerCmpSpecificData[i]; + + /* Attach the data to the OutManager state machine and to its procedures. */ + FwSmSetData(outManagerDesc[i], &outManagerData[i]); + FwPrSetData(outManagerData[i].initProc, &outManagerData[i]); + FwPrSetData(outManagerData[i].resetProc, &outManagerData[i]); + FwPrSetData(outManagerData[i].execProc, &outManagerData[i]); + + /* Start the OutManager */ + FwSmStart(outManagerDesc[i]); + + return outManagerDesc[i]; +} + +/*-----------------------------------------------------------------------------------------*/ +static void OutManagerExecAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwOutManagerData_t* outManagerCSData = (CrFwOutManagerData_t*)outManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = outManagerDataLocal->instanceId; + FwSmDesc_t outCmp; + CrFwCounterU2_t i; + CrFwOutRegistryCmdRepState_t outCmpState; + + outManagerCSData->nextFreePoclPos = 0; + for (i=0; i<outManagerPoclSize[id]; i++) { + outCmp = outManagerCSData->pocl[i]; + if (outCmp != NULL) { + FwSmExecute(outCmp); + CrFwOutCmpTerminate(outCmp); + if (CrFwOutCmpIsInAborted(outCmp)) + outCmpState = crOutRegistryAborted; + else if (CrFwOutCmpIsInPending(outCmp)) + outCmpState = crOutRegistryPending; + else + outCmpState = crOutRegistryTerminated; + + if (outCmpState != crOutRegistryPending) { + CrFwOutRegistryUpdateState(outCmp,outCmpState); + CrFwOutFactoryReleaseOutCmp(outCmp); + outManagerCSData->pocl[i] = NULL; + outManagerCSData->nOfOutCmpInPocl--; + } + } + } +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutManagerLoad(FwSmDesc_t smDesc, FwSmDesc_t outCmp) { + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutManagerData_t* outManagerCSData = (CrFwOutManagerData_t*)outManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = outManagerDataLocal->instanceId; + CrFwCounterU2_t i, freePos, size; + + freePos = outManagerCSData->nextFreePoclPos; + size = outManagerPoclSize[id]; + + /* Check if POCL is already full */ + if (outManagerCSData->nOfOutCmpInPocl == size) { + CrFwRepErr(crOutManagerPoclFull, outManagerDataLocal->typeId, outManagerDataLocal->instanceId); + CrFwOutFactoryReleaseOutCmp(outCmp); + return; + } + + /* Check if this is the first load request after the OutManager was reset or after it was executed. + * If this is the case, find the first free position in the POCL. + * NB: Since the for-loop is only entered if the POCL is not full, it will always terminate + * through the break. This means that, when measuring branch coverage, the fall-through case + * at the for-loop will never occur. */ + if (freePos == 0) + for (i=0; i<size; i++) + if (outManagerCSData->pocl[i] == NULL) { + freePos = i; + break; + } + + /* POCL is not full --> load outCmp */ + outManagerCSData->pocl[freePos] = outCmp; + outManagerCSData->nOfOutCmpInPocl++; + outManagerCSData->nOfLoadedOutCmp++; + + /* Start tracking OutComponent */ + CrFwOutRegistryStartTracking(outCmp); + + /* Identify next free position in POCL */ + for (i=freePos+1; i<size; i++) + if (outManagerCSData->pocl[i] == NULL) { + outManagerCSData->nextFreePoclPos = (CrFwCounterU1_t)i; + return; /* a free position has been found */ + } + + outManagerCSData->nextFreePoclPos = (CrFwCounterU1_t)size; /* no free position was found */ +} + +/*-----------------------------------------------------------------------------------------*/ +static void OutManagerInitAction(FwPrDesc_t initPr) { + CrFwCounterU1_t i; + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwPrGetData(initPr); + CrFwOutManagerData_t* outManagerCSData = (CrFwOutManagerData_t*)outManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = outManagerDataLocal->instanceId; + outManagerCSData->pocl = malloc(sizeof(FwSmDesc_t)*outManagerPoclSize[id]); + for (i=0; i<outManagerPoclSize[id]; i++) + outManagerCSData->pocl[i] = NULL; + outManagerCSData->nOfOutCmpInPocl = 0; + outManagerDataLocal->outcome = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +static void OutManagerConfigAction(FwPrDesc_t initPr) { + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwPrGetData(initPr); + CrFwOutManagerData_t* outManagerCSData = (CrFwOutManagerData_t*)outManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = outManagerDataLocal->instanceId; + CrFwCounterU1_t i; + + for (i=0; i<outManagerPoclSize[id]; i++) { + if (outManagerCSData->pocl[i] != NULL) { + CrFwOutFactoryReleaseOutCmp(outManagerCSData->pocl[i]); + outManagerCSData->pocl[i] = NULL; + } + } + outManagerCSData->nOfOutCmpInPocl = 0; + outManagerCSData->nOfLoadedOutCmp = 0; + outManagerCSData->nextFreePoclPos = 0; + outManagerDataLocal->outcome = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +static void OutManagerShutdownAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutManagerData_t* outManagerCSData = (CrFwOutManagerData_t*)outManagerDataLocal->cmpSpecificData; + CrFwInstanceId_t id = outManagerDataLocal->instanceId; + CrFwCounterU1_t i; + + for (i=0; i<outManagerPoclSize[id]; i++) { + if (outManagerCSData->pocl[i] != NULL) { + CrFwOutFactoryReleaseOutCmp(outManagerCSData->pocl[i]); + outManagerCSData->pocl[i] = NULL; + } + } + free(outManagerCSData->pocl); + outManagerCSData->nOfOutCmpInPocl = 0; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwOutManagerGetNOfPendingOutCmp(FwSmDesc_t smDesc) { + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutManagerData_t* outManagerCSData = (CrFwOutManagerData_t*)outManagerDataLocal->cmpSpecificData; + return outManagerCSData->nOfOutCmpInPocl; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU2_t CrFwOutManagerGetNOfLoadedOutCmp(FwSmDesc_t smDesc) { + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutManagerData_t* outManagerCSData = (CrFwOutManagerData_t*)outManagerDataLocal->cmpSpecificData; + return outManagerCSData->nOfLoadedOutCmp; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwOutManagerGetPOCLSize(FwSmDesc_t smDesc) { + CrFwCmpData_t* outManagerDataLocal = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwInstanceId_t id = outManagerDataLocal->instanceId; + return (CrFwCounterU1_t)outManagerPoclSize[id]; +} + diff --git a/CrFramework/src/OutManager/CrFwOutManager.h b/CrFramework/src/OutManager/CrFwOutManager.h new file mode 100644 index 0000000000000000000000000000000000000000..9635e3bbbfba9201884db4f00e676326ad958bcd --- /dev/null +++ b/CrFramework/src/OutManager/CrFwOutManager.h @@ -0,0 +1,164 @@ +/** + * @file + * @ingroup outMngGroup + * Definition of the OutManager component. + * + * The OutManager component is responsible for maintaining a list of + * pending OutComponents (see <code>CrFwOutCmp.h</code>) and for repeatedly + * executing them until they are either aborted or else they are serialized + * and sent to their destination. + * + * The list of pending commands is called the Pending OutComponent List or POCL. + * The POCL has a fixed size which is defined statically in <code>CrFwOutManagerUserPar.h</code>. + * + * The OutManager is defined as an extension of the Base Component (see <code>CrFwBaseCmp.h</code>). + * It uses the Execution Procedure of the Base Component to process the pending OutComponents. + * The OutManager component processes the pending OutComponents by sending them an Execute command. + * After each Execute command, the state of the OutComponent is reported to the OutRegistry + * (see <code>CrFwOutRegistry.h</code>). + * Commands which have been aborted or have been sent to their destination are removed + * from the POCL and are returned to the OutFactory (see <code>CrFwOutFactory.h</code>). + * The Execution Procedure of the OutManager is shown in the figure below. + * + * <b>Mode of Use of an OutManager Component</b> + * + * The configuration of the OutManager components is defined statically in + * <code>CrFwOutManagerUserPar.h</code>. + * + * An OutManager component is created with function <code>::CrFwOutManagerMake</code>. + * After being created, the OutManager must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the OutManager State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * An application can have any number of OutManagers. + * + * An OutManager offers a Load operation (<code>::CrFwOutManagerLoad</code>) through which + * an OutComponent can be added to the POCL. + * This operation is normally called by the OutLoader (see <code>CrFwOutLoader.h</code>). + * + * There is no mechanism to “unload†a pending OutComponent. + * The OutManager autonomously returns an OutComponent to the OutFactory when the + * OutComponent has been sent to its destination (i.e. when the OutComponent is in + * state TERMINATED) or when it has been aborted (i.e. when the OutComponent is in + * state ABORTED). + * + * After an OutManager has been configured, it can be executed by means of function + * <code>FwSmExecute</code>. + * Execution of an OutManager causes its Execution Procedure (see figure below) to be + * executed. + * + * When an OutManager is reset or shutdown, its POCL is reset (all pending OutComponents + * are cleared and returned to the OutFactory). + * + * @image html OutManagerExecution.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_OUT_MANAGER_H_ +#define CRFW_OUT_MANAGER_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" +#include "Pckt/CrFwPcktQueue.h" + +/** + * Factory function to retrieve the i-th OutManager State Machine instance. + * The first time this function is called with a certain value of the argument i, it + * creates the i-th OutManager State Machine instance. + * Subsequent calls returns the same instance. + * + * The OutManager identifier i must be in the range: [0, <code>#CR_FW_NOF_OUTMANAGER</code>-1]. + * If the identifier is out of range, the function returns NULL and sets the application + * error code to: <code>::crOutManagerIllId</code>. + * + * The first time this function is called with a certain value of i, it returns an + * OutManager State Machine which has been started but which still needs to be initialized and + * configured. + * @param outManagerId the identifier of the OutManager + * @return the descriptor of the OutManager State Machine or NULL + * if the state machine could not be created or if the identifier i is out of range. + */ +FwSmDesc_t CrFwOutManagerMake(CrFwInstanceId_t outManagerId); + +/** + * Load a new OutComponent into the OutManager. + * The behaviour implemented by this function is shown in the activity diagram below. + * If the POCL is not full, the function identifies a free position in the POCL where + * to store the OutComponent. + * This function adds OutComponents to the POCL. The POCL is flushed when the OutManager + * is executed (i.e. it is flushed by function <code>::OutManagerExecAction</code>). + * The algorithms to identify a free position in the POCL and to process the POCL + * entries when the OutManager is executed are optimized for a situation where multiple + * load operations are performed before the OutManager is executed. + * + * Additionally, these algorithms guarantee the following ordering constraint. + * Let OutComponents C1 to Cn be successfully loaded into an OutManager through a sequence + * of calls to function <code>::CrFwOutManagerLoad</code> and assume that this sequence + * of load operations is not interrupted by an execution of the OutManager. + * Under these conditions, when the OutManager is executed next, the OutComponents C1 to + * Cn will be processed in the order in which they have been loaded. + * + * The implementation of function <code>::CrFwOutManagerLoad</code> is based on the + * internal variable <code>freePos</code>. This variable has the following + * characteristics: + * - it is initialized to point to the first entry in the POCL; + * - after the execution of the load function, <code>freePos</code> either points to the next + * free position in the POCL or is equal to the POCL size if the POCL is full; + * - after execution of the OutManager, it is re-initialized to point to the first position + * in the POCL. + * . + * @image html OutManagerLoad.png + * @param smDesc the descriptor of the OutManager State Machine. + * @param outCmp the descriptor of the OutComponent to be loaded in the OutManager + */ +void CrFwOutManagerLoad(FwSmDesc_t smDesc, FwSmDesc_t outCmp); + +/** + * Return the number of OutComponents currently in the POCL of an OutManager. + * @param smDesc the descriptor of the OutManager State Machine. + * @return the number of OutComponents currently in the POCL of an OutManager. + */ +CrFwCounterU1_t CrFwOutManagerGetNOfPendingOutCmp(FwSmDesc_t smDesc); + +/** + * Return the number of OutComponents successfully loaded in the POCL of an OutManager + * since the OutManager was last reset. + * @param smDesc the descriptor of the OutManager State Machine. + * @return the number of OutComponents successfully loaded in the POCL of an OutManager. + */ +CrFwCounterU2_t CrFwOutManagerGetNOfLoadedOutCmp(FwSmDesc_t smDesc); + +/** + * Return the size of the POCL of an OutManager. + * @param smDesc the descriptor of the OutManager State Machine. + * @return the size of the POCL of an OutManager. + */ +CrFwCounterU1_t CrFwOutManagerGetPOCLSize(FwSmDesc_t smDesc); + +#endif /* CRFW_OUT_MANAGER_H_ */ diff --git a/CrFramework/src/OutRegistry/CrFwOutRegistry.c b/CrFramework/src/OutRegistry/CrFwOutRegistry.c new file mode 100644 index 0000000000000000000000000000000000000000..64507c4d54c56b5c2780b7c6998aa6019216fb11 --- /dev/null +++ b/CrFramework/src/OutRegistry/CrFwOutRegistry.c @@ -0,0 +1,397 @@ +/** + * @file + * + * Implementation of OutRegistry component. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include configuration files */ +#include "CrFwOutRegistryUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +#include "OutCmp/CrFwOutCmp.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "CrFwOutRegistry.h" +/* Include FW Profile files */ +#include "FwPrConfig.h" +#include "FwPrDCreate.h" +#include "FwSmConfig.h" +#include "FwSmDCreate.h" +#include "FwPrCore.h" + +/** Array of service descriptors (see <code>CrFwServDesc_t</code>). */ +static CrFwServDesc_t servDesc[CR_FW_OUTREGISTRY_NSERV] = CR_FW_OUTREGISTRY_INIT_SERV_DESC; + +/** + * An instance of this type holds the information about an out-going command or report + * which is being tracked by the OuRegistry. + */ +typedef struct { + /** The identifier of the out-going command or report */ + CrFwInstanceId_t instanceId; + /** The state of the out-going command or report */ + CrFwOutRegistryCmdRepState_t state; +} CrFwTrackedState_t; + +/** Array to track the state of out-going commands or reports */ +static CrFwTrackedState_t cmdRepState[CR_FW_OUTREGISTRY_N]; + +/** The index of the most recent entry in <code>cmdRepState</code>. */ +static CrFwTrackingIndex_t cmdRepStateIndex = 0; + +/** The OutRegistry singleton. */ +static FwSmDesc_t outRegistry = NULL; + +/** The data for the OutRegistry singleton. */ +static CrFwCmpData_t outRegistryData; + +/** + * Initialization action for OutRegistry. + * This function allocates the memory for the OutRegistry data structures and + * initializes all data structures which depend on the set of services supported + * by the application. + * The outcome of the initialization action is always "success". + * The situation where the memory allocation for the OutRegistry data structures + * fails is not handled and will result in undefined behaviour (probably a run-time + * exception). + * @param initPr the Initialization Procedure of the OutRegistry + */ +static void OutRegistryInitAction(FwPrDesc_t initPr); + +/** + * Configuration action for OutRegistry. + * This function sets the enable state of all service types, sub-types and discriminant + * to "enabled" and resets the queue of tracked commands and reports. + * The outcome of the configuration action is always: "successful" + * @param resetPr the Configuration Procedure of the OutRegistry + */ +static void OutRegistryConfigAction(FwPrDesc_t resetPr); + +/** + * Shutdown action for OutRegistry. + * This function sets the enable state of all service types, sub-types and discriminant + * to "enabled" and resets the queue of tracked commands and reports. + * This function also releases the memory allocated when the OutRegistry was initialized. + * @param smDesc the OutRegistry state machine + */ +static void OutRegistryShutdownAction(FwSmDesc_t smDesc); + +/*------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwOutRegistryMake() { + FwPrDesc_t resetPr, execPr, initPr; + + if (outRegistry != NULL) { + return outRegistry; + } + + /* Extend the Base Component */ + outRegistry = FwSmCreateDer(CrFwBaseCmpMake()); + + /* Create the Reset Procedure for the OuRegistry Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, &OutRegistryConfigAction); + + /* Create the Initialization Procedure for the OuRegistry Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitAction, &OutRegistryInitAction); + + /* Override the Shutdown Action for the InStream Component */ + FwSmOverrideAction(outRegistry, &CrFwBaseCmpDefShutdownAction, &OutRegistryShutdownAction); + + /* Get the Dummy Execution Procedure for the OutRegistry Component */ + execPr = CrFwBaseCmpGetDummyExecProc(); + + /* Initialize the data for the requested SM */ + outRegistryData.outcome = 1; + outRegistryData.initProc = initPr; + outRegistryData.resetProc = resetPr; + outRegistryData.execProc = execPr; + outRegistryData.instanceId = 0; + outRegistryData.typeId = CR_FW_OUTREGISTRY_TYPE; + + /* Attach the data to the OutRegistry state machine and to its procedures. */ + FwSmSetData(outRegistry, &outRegistryData); + FwPrSetData(outRegistryData.initProc, &outRegistryData); + FwPrSetData(outRegistryData.resetProc, &outRegistryData); + + /* Start the OutRegistry */ + FwSmStart(outRegistry); + + return outRegistry; +} + +/*------------------------------------------------------------------------------------*/ +CrFwServType_t CrFwOutRegistryGetServType(CrFwCmdRepIndex_t cmdRepIndex) { + return servDesc[cmdRepIndex].servType; +} + +/*------------------------------------------------------------------------------------*/ +CrFwServSubType_t CrFwOutRegistryGetServSubType(CrFwCmdRepIndex_t cmdRepIndex) { + return servDesc[cmdRepIndex].servSubType; +} + +/*------------------------------------------------------------------------------------*/ +CrFwCmdRepIndex_t CrFwOutRegistryGetCmdRepIndex(CrFwServType_t servType, CrFwServSubType_t servSubType) { + CrFwCmdRepIndex_t i = 0; + + while (servDesc[i].nextServType != 0) + if (servDesc[i].servType < servType) + i = servDesc[i].nextServType; + else if (servDesc[i].servType > servType) + return CR_FW_OUTREGISTRY_NSERV; /* The specified type does not exist */ + else + break; + + if (servDesc[i].servType != servType) + return CR_FW_OUTREGISTRY_NSERV; /* The specified type does not exist */ + + while (servDesc[i].servSubType <= servSubType) { + if (servDesc[i].servSubType == servSubType) + return i; /* Cmd-Rep index found! */ + i++; + if (servDesc[i].servType != servType) + return CR_FW_OUTREGISTRY_NSERV; /* The specified sub-type does not exist in the specified type */ + } + + return CR_FW_OUTREGISTRY_NSERV; /* The specified sub-type does not exist in the specified type */ +} + +/*------------------------------------------------------------------------------------*/ +void CrFwOutRegistrySetEnable(CrFwServType_t servType, CrFwServSubType_t servSubType, + CrFwDiscriminant_t discriminant, CrFwBool_t isEnabled) { + CrFwCmdRepIndex_t i = 0; + CrFwDiscriminant_t byteIndex, bitPos; + unsigned char temp; + + while (servDesc[i].nextServType != 0) + if (servDesc[i].servType < servType) + i = servDesc[i].nextServType; + else if (servDesc[i].servType > servType) { + CrFwSetAppErrCode(crIllServType); + return; + } else + break; + + if (servDesc[i].servType != servType) { + CrFwSetAppErrCode(crIllServType); + return; + } + + if (servSubType == 0) { + while (servDesc[i].servType == servType) { + servDesc[i].isServTypeEnabled = isEnabled; + i++; + if (i == CR_FW_OUTREGISTRY_NSERV) + return; + } + return; + } + + while (servDesc[i].servType == servType) { + if (servDesc[i].servSubType < servSubType) + i++; + else if (servDesc[i].servSubType > servSubType) { + CrFwSetAppErrCode(crIllServSubType); + return; + } else + break; + } + + if (servDesc[i].servSubType < servSubType) { + CrFwSetAppErrCode(crIllServSubType); + return; + } + + if (discriminant == 0) { + servDesc[i].isServSubTypeEnabled = isEnabled; + return; + } + + if (discriminant > servDesc[i].maxDiscriminant) + CrFwSetAppErrCode(crIllDiscriminant); + else { + byteIndex = discriminant/(8*sizeof(char)); + bitPos = (CrFwDiscriminant_t)(discriminant - byteIndex*8*(CrFwDiscriminant_t)sizeof(char)); + if (isEnabled == 1) + servDesc[i].isDiscriminantEnabled[byteIndex] = servDesc[i].isDiscriminantEnabled[byteIndex] | (unsigned char)(1 << (bitPos-1)); + else { + temp = (unsigned char)(~(1 << (bitPos-1))); + servDesc[i].isDiscriminantEnabled[byteIndex] = servDesc[i].isDiscriminantEnabled[byteIndex] & temp; + } + } +} + +/*------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwOutRegistryIsEnabled(FwSmDesc_t outCmp) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(outCmp); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)cmpData->cmpSpecificData; + CrFwCmdRepIndex_t cmdRepIndex; + CrFwDiscriminant_t byteIndex, bitPos, discriminant; + unsigned char enableByte; + /*CrFwOutCmpData_t* outCmpData = &(((CrFwCmpData_t*)FwSmGetData(outCmp))->cmpSpecificData.outCmpData);*/ + + cmdRepIndex = cmpSpecificData->index; + if (servDesc[cmdRepIndex].isServTypeEnabled == 0) + return 0; + + if (servDesc[cmdRepIndex].isServSubTypeEnabled == 0) + return 0; + + discriminant = CrFwOutCmpGetDiscriminant(outCmp); + if (discriminant == 0) + return 1; + byteIndex = discriminant/(8*sizeof(char)); + bitPos = (CrFwDiscriminant_t)(discriminant - byteIndex*8*(CrFwDiscriminant_t)sizeof(char)); + enableByte = servDesc[cmdRepIndex].isDiscriminantEnabled[byteIndex]; + if ((enableByte & (1 << (bitPos-1))) == 0) + return 0; + else + return 1; +} + +/*------------------------------------------------------------------------------------*/ +void CrFwOutRegistryStartTracking(FwSmDesc_t outCmp) { + CrFwCmpData_t* outCmpData = (CrFwCmpData_t*)FwSmGetData(outCmp); + CrFwOutCmpData_t* outCmpSpecificData = (CrFwOutCmpData_t*)outCmpData->cmpSpecificData; + + cmdRepState[cmdRepStateIndex].instanceId = outCmpData->instanceId; + cmdRepState[cmdRepStateIndex].state = crOutRegistryPending; + outCmpSpecificData->trackingIndex = cmdRepStateIndex; + /*outCmpData->cmpSpecificData.outCmpData.trackingIndex = cmdRepStateIndex;*/ + + if (cmdRepStateIndex == (CR_FW_OUTREGISTRY_N-1)) + cmdRepStateIndex = 0; + else + cmdRepStateIndex++; +} + +/*------------------------------------------------------------------------------------*/ +void CrFwOutRegistryUpdateState(FwSmDesc_t outCmp, CrFwOutRegistryCmdRepState_t newState) { + CrFwCmpData_t* outCmpData = (CrFwCmpData_t*)FwSmGetData(outCmp); + CrFwOutCmpData_t* outCmpSpecificData = (CrFwOutCmpData_t*)outCmpData->cmpSpecificData; + CrFwTrackingIndex_t i; + + i = outCmpSpecificData->trackingIndex; + /*i = outCmpData->cmpSpecificData.outCmpData.trackingIndex;*/ + if (cmdRepState[i].instanceId == outCmpData->instanceId) { + cmdRepState[i].state = newState; + } +} + +/*------------------------------------------------------------------------------------*/ +CrFwOutRegistryCmdRepState_t CrFwOutRegistryGetState(CrFwInstanceId_t cmdRepId) { + CrFwTrackingIndex_t i; + CrFwTrackingIndex_t j; + + if (cmdRepStateIndex > 0) + i = (CrFwTrackingIndex_t)(cmdRepStateIndex-1); + else + i = (CR_FW_OUTREGISTRY_N-1); + + for (j=0; j<CR_FW_OUTREGISTRY_N; j++) { + if (cmdRepState[i].state == crOutRegistryNoEntry) + break; + if (cmdRepState[i].instanceId == cmdRepId) { + return cmdRepState[i].state; + } else if (i == 0) + i = (CR_FW_OUTREGISTRY_N-1); + else + i--; + } + + return crOutRegistryNotTracked; +} + +/*------------------------------------------------------------------------------------*/ +static void OutRegistryInitAction(FwPrDesc_t initPr) { + CrFwCmdRepIndex_t i, nextServType; + CrFwDiscriminant_t nOfBytes; + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(initPr); + + for (i=0; i<CR_FW_OUTREGISTRY_NSERV; i++) { + if (servDesc[i].maxDiscriminant == 0) + servDesc[i].isDiscriminantEnabled = NULL; + else { + nOfBytes = (CrFwDiscriminant_t)(servDesc[i].maxDiscriminant/sizeof(char)+1); + servDesc[i].isDiscriminantEnabled = malloc(sizeof(unsigned char)*nOfBytes); + } + } + + nextServType = 0; + for (i=CR_FW_OUTREGISTRY_NSERV-1; i>0; i--) { + servDesc[i].nextServType = nextServType; + if (servDesc[i-1].servType != servDesc[i].servType) + nextServType = i; + } + servDesc[0].nextServType = nextServType; + + cmpData->outcome = 1; +} + +/*------------------------------------------------------------------------------------*/ +static void OutRegistryConfigAction(FwPrDesc_t initPr) { + CrFwCmdRepIndex_t i; + CrFwDiscriminant_t j; + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwPrGetData(initPr); + CrFwCounterU2_t k; + + for (i=0; i<CR_FW_OUTREGISTRY_NSERV; i++) { + servDesc[i].isServTypeEnabled = 1; + servDesc[i].isServSubTypeEnabled = 1; + if (servDesc[i].maxDiscriminant != 0) + for (j=0; j<(servDesc[i].maxDiscriminant/(8*sizeof(char))+1); j++) + servDesc[i].isDiscriminantEnabled[j] = (unsigned char)(~0); + } + + for (k=0; k<CR_FW_OUTREGISTRY_N; k++) + cmdRepState[k].state = crOutRegistryNoEntry; + + cmdRepStateIndex = 0; + + cmpData->outcome = 1; +} + +/*------------------------------------------------------------------------------------*/ +static void OutRegistryShutdownAction(FwSmDesc_t smDesc) { + CrFwCmdRepIndex_t i; + CrFwCounterU2_t k; + CRFW_UNUSED(smDesc); + + for (i=0; i<CR_FW_OUTREGISTRY_NSERV; i++) { + servDesc[i].isServTypeEnabled = 1; + servDesc[i].isServSubTypeEnabled = 1; + if (servDesc[i].maxDiscriminant != 0) + free(servDesc[i].isDiscriminantEnabled); + } + + for (k=0; k<CR_FW_OUTREGISTRY_N; k++) + cmdRepState[k].state = crOutRegistryNoEntry; + + cmdRepStateIndex = 0; +} diff --git a/CrFramework/src/OutRegistry/CrFwOutRegistry.h b/CrFramework/src/OutRegistry/CrFwOutRegistry.h new file mode 100644 index 0000000000000000000000000000000000000000..00ee6a2d6084ab735c370df157903b9fa8e380a3 --- /dev/null +++ b/CrFramework/src/OutRegistry/CrFwOutRegistry.h @@ -0,0 +1,263 @@ +/** + * @file + * @ingroup outMngGroup + * Definition of the OutRegistry Component. + * + * An OutRegistry acts as a registry for out-going commands or reports (namely for + * commands or reports which have been loaded into an OutManager). + * The OutRegistry is responsible for: + * - keeping track of an out-going command's or report's state + * - storing the enable state of out-going commands or reports + * - storing the link between the index of an out-going command or report and its + * service type and sub-type + * . + * The index of an out-going command or report is a positive integer in the range + * from 0 to <code>::CR_FW_OUTREGISTRY_NSERV</code>-1. + * <code>::CR_FW_OUTREGISTRY_NSERV</code> is the total number of out-going service + * types and sub-types in an application. + * The index of an out-going command or report uniquely identifies the command's + * or report's type and sub-type. + * + * The set of out-going service types and sub-types supported by an application + * is specified in <code>CrFwOutRegistryUserPar.h</code>. + * + * The framework internally uses the index as a more efficient way of identifying + * a pair [service type, service sub-type] for an out-going command or report. + * The OutRegistry offers a function which allows the service type and service sub-type + * associated to a certain index to be retrieved. + * + * The OutRegistry is a singleton component which is implemented as an extension + * of the Base Component of <code>CrFwBaseCmp.h</code>. + * + * The OutRegistry maintains a list of the last N commands or reports to have been + * loaded in an OutManager. + * The OutRegistry maintains the state of each such command or report. + * The command's or report's state in the OutRegistry can have one of the following values: + * - PENDING: the command or report is waiting to be sent + * - ABORTED: the command or report was aborted because it was disabled when it was loaded + * - TERMINATED: the command or report has been passed to the OutStream + * . + * The value of N (the maximum number of items which can be tracked by the OutRegistry) + * is fixed and is an initialization parameter. + * + * The OutRegistry uses the instance identifier of the OutComponent encapsulating + * the out-going report or command as the key through which the out-going command or report + * state is tracked. + * + * The OutRegistry stores the enable state of out-going commands and reports. + * The enable state of out-going command and reports can be controlled at three levels: + * - At the level of the service type (all commands or reports of a certain type are disabled) + * - At the level of the service sub-type (all commands or reports matching a certain + * [type, sub-type] pair are disabled) + * - At the level of the discriminant (all commands or reports matching a certain + * [type, sub-type, discriminant] triplet are enabled or disabled) + * . + * The enable state of a particular out-going command or report is derived from these three + * enable levels by running the Enable State Determination Procedure shown in the + * figure below. + * The OutRegistry offers functions through which all three levels of enable state + * can be controlled and through which the enable state of a specific out-going + * command or report can be determined. + * By default, the enable state for all kinds of reports or commands is set to: + * "enabled". + * + * <b>Mode of Use of an OutRegistry Component</b> + * + * The configuration of the OutRegistry component is defined statically in + * <code>CrFwOutRegistryUserPar.h</code>. + * + * The OutRegistry component is a "final" component that does not normally need + * to be extended. + * + * An OutRegistry component is created with function <code>::CrFwOutRegistryMake</code>. + * After being created, the OutRegistry must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the OutRegistry State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * @image html EnableStateDetermination.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_OUTREGISTRY_H_ +#define CRFW_OUTREGISTRY_H_ + +/* Include configuration files */ +#include "CrFwOutRegistryUserPar.h" +#include "CrFwUserConstants.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include framework files */ +#include "CrFwConstants.h" + +/** Enumerated type for the state of an out-going command or report tracked by the OutRegistry */ +typedef enum { + /** No entry yet in OutRegistry */ + crOutRegistryNoEntry = 0, + /** Out-going command or report is pending (waiting to be sent) */ + crOutRegistryPending = 1, + /** Out-going command or report has been aborted */ + crOutRegistryAborted = 2, + /** Out-going command or report has been passed to the OutStream */ + crOutRegistryTerminated = 3, + /** Out-going command or report is not tracked */ + crOutRegistryNotTracked = 4 +} CrFwOutRegistryCmdRepState_t; + +/** + * Factory function for the singleton instance of the OutRegistry. + * The first time this function is called, it creates and configures the OutRegistry. + * Subsequent calls returns the same singleton instance. + * The first time this function is called, it returns the OutRegistry in state CREATED. + * + * If the creation or the configuration of the OutRegistry fails, the function + * returns NULL. + * @return singleton instance of the OutRegistry or NULL if the creation or configuration + * of the OutRegistry failed. + */ +FwSmDesc_t CrFwOutRegistryMake(); + +/** + * Get the service type of the argument command or report index. + * For out-going commands or reports the index uniquely identifies a pair: + * [service type, service sub-type]. + * This function returns the service type corresponding to a certain index value. + * If the index value is out of range (i.e. if it is greater than + * <code>::CR_FW_OUTREGISTRY_NSERV</code>-1), the behaviour of this function is + * undefined. + * @param cmdRepIndex the command or report index + * @return the service type corresponding to the command or report index + */ +CrFwServType_t CrFwOutRegistryGetServType(CrFwCmdRepIndex_t cmdRepIndex); + +/** + * Get the service sub-type of the argument command or report index. + * For out-going commands or reports the index uniquely identifies a pair: + * [service type, service sub-type]. + * This function returns the service sub-type corresponding to a certain index value. + * If the index value is out of range (i.e. if it is greater than + * <code>::CR_FW_OUTREGISTRY_NSERV</code>-1), the behaviour of this function is + * undefined. + * @param cmdRepIndex the command or report index + * @return the service type corresponding to the command or report index + */ +CrFwServSubType_t CrFwOutRegistryGetServSubType(CrFwCmdRepIndex_t cmdRepIndex); + +/** + * Get the index corresponding to the argument [service type, service sub-type] of an out-going + * command or report. + * For out-going commands or reports the index uniquely identifies a pair: + * [service type, service sub-type]. + * This function returns the index corresponding to a specific [service type, service sub-type] + * pair. + * If either of the two arguments has an illegal value (i.e. if it has a value which does + * not correspond to any [service type, service sub-type] declared in the initializer + * of the service descriptor <code>::CR_FW_OUTREGISTRY_INIT_SERV_DESC</code>.), + * the function returns CR_FW_OUTREGISTRY_NSERV. + * @param servType the service type + * @param servSubType the service sub-type + * @return cmdRepIndex the command or report index or CR_FW_OUTREGISTRY_NSERV if the + * specified [type, sub-type] does not exist + */ +CrFwCmdRepIndex_t CrFwOutRegistryGetCmdRepIndex(CrFwServType_t servType, CrFwServSubType_t servSubType); + +/** + * Set the enable state of a set of out-going commands or reports. + * The enable state of out-going command and reports can be controlled at three levels: + * - At the level of the service type (all commands or reports of a certain type are disabled) + * - At the level of the service sub-type (all commands or reports matching a certain + * [type, sub-type] pair are disabled) + * - At the level of the discriminant (all commands or reports matching a certain + * [type, sub-type, discriminant] triplet are enabled or disabled) + * . + * This function allows all three enable levels to be set according to the logic + * in the activity diagram shown below. + * Use of illegal values for the function parameters results in the application error code + * being set to: <code>#crIllServType</code> (if the service type is illegal), or to + * <code>#crIllServSubType</code> (if the service sub-type is illegal), or to + * <code>#crIllDiscriminant</code> (if the discriminant value is illegal). + * A service type or sub-type or a discriminant value are illegal if they are not covered + * in the list of [type, sub-types, discriminant] in the <code>CrFwOutRegistryUserPar.h</code> + * (see <code>::CR_FW_OUTREGISTRY_INIT_SERV_DESC</code>). + * @image html EnableCmdRep.png + * @param servType the service type + * @param servSubType the service type + * @param discriminant the discriminant + * @param isEnabled the enable state + */ +void CrFwOutRegistrySetEnable(CrFwServType_t servType, CrFwServSubType_t servSubType, + CrFwDiscriminant_t discriminant, CrFwBool_t isEnabled); + +/** + * Query the enable status of an out-going command or report. + * If the argument does not represent an out-going command or report (i.e. if it is not + * a component of type OutComponent), the behaviour of the function is undefined. + * The enable state of an out-going command or report is determined by running the + * Enable State Determination Procedure shown in the figure. + * @image html EnableStateDetermination.png + * @param outCmp the out-going command or report as an OutComponent + * @return the enable state of the specified command or report + */ +CrFwBool_t CrFwOutRegistryIsEnabled(FwSmDesc_t outCmp); + +/** + * Ask the OutRegistry to start tracking an out-going command or report. + * The OutRegistry tracks the state of the last N out-going command or reports + * to have been loaded with this function. + * Initially, when this function is called, the out-going command or report is + * placed in state PENDING. + * This function runs the procedure in the left-hand + * side of the activity diagram shown in the figure. + * @image html RegistryStartTrackingAndUpdate.png + * @param outCmp the out-going command or report to be tracked + */ +void CrFwOutRegistryStartTracking(FwSmDesc_t outCmp); + +/** + * Ask the OutRegistry to update the state of an out-going command or report. + * If the argument component is not tracked by the OutRegistry (perhaps because + * too many OutComponents have been added to the list of tracked components), + * nothing is done. + * This function runs the procedure in the right-hand + * side of the activity diagram shown in the figure. + * @image html RegistryStartTrackingAndUpdate.png + * @param outCmp the out-going command or report to be tracked + * @param newState the new state of the out-going command or report + */ +void CrFwOutRegistryUpdateState(FwSmDesc_t outCmp, CrFwOutRegistryCmdRepState_t newState); + +/** + * Query the OutRegistry for the state of an out-going command or report. + * If the specified index does not correspond to any command or report being + * tracked by the OutRegistry, a value of <code>::crOutRegistryNotTracked</code> + * is returned. + * This function searches all locations in the InRegistry in sequence until it + * finds the out-going command or report. + * @param cmdRepId the instance identifier of the out-going command or report. + * @return the state of the out-going command or report (or <code>::crOutRegistryNotTracked</code> + * if the command or report is not tracked) + */ +CrFwOutRegistryCmdRepState_t CrFwOutRegistryGetState(CrFwInstanceId_t cmdRepId); + +#endif /* CRFW_OUTREGISTRY_H_ */ diff --git a/CrFramework/src/OutStream/CrFwOutStream.c b/CrFramework/src/OutStream/CrFwOutStream.c new file mode 100644 index 0000000000000000000000000000000000000000..1f85c570ff6f6bb7577e580af53f5d38ca4b98df --- /dev/null +++ b/CrFramework/src/OutStream/CrFwOutStream.c @@ -0,0 +1,433 @@ +/** + * @file + * + * Implementation of OutStream State Machine. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +#include<string.h> +/* Include configuration files */ +#include "CrFwOutStreamUserPar.h" +#include "CrFwCmpData.h" +/* Include framework files */ +#include "CrFwConstants.h" +#include "CrFwRepErr.h" +#include "CrFwTime.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "CrFwOutStream.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +#include "BaseCmp/CrFwDummyExecProc.h" +#include "Pckt/CrFwPckt.h" +#include "Pckt/CrFwPcktQueue.h" +#include "UtilityFunctions/CrFwUtilityFunctions.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +/** Base OutStream from which all other OutStreams are derived. */ +static FwSmDesc_t baseOutStreamSmDesc = NULL; + +/** The sizes of the packet queues in the OutStream components. */ +static CrFwCounterU1_t outStreamPcktQueueSize[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_PQSIZE; + +/** The destinations associated to the OutStream components. */ +static CrFwDestSrc_t outStreamDest[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_DEST; + +/** The number of groups associated to the OutStream components. */ +static CrFwGroup_t outStreamNOfGroups[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_NOF_GROUPS; + +/** The functions implementing the packet hand-over operations for the OutStream components */ +static CrFwPcktHandover_t outStreamHandoverPckt[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_PCKTHANDOVER; + +/** The functions implementing the initialization checks for the InStream components. */ +static FwPrAction_t outStreamInitCheck[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_INITCHECK; + +/** The functions implementing the initialization actions for the InStream components. */ +static FwPrAction_t outStreamInitAction[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_INITACTION; + +/** The functions implementing the configuration checks for the InStream components. */ +static FwPrAction_t outStreamConfigCheck[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_CONFIGCHECK; + +/** The functions implementing the configuration actions for the InStream components. */ +static FwPrAction_t outStreamConfigAction[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_CONFIGACTION; + +/** The functions implementing the shutdown actions for the InStream components. */ +static FwSmAction_t outStreamShutdownAction[CR_FW_NOF_OUTSTREAM] = CR_FW_OUTSTREAM_SHUTDOWNACTION; + +/** The descriptors of the OutStream State Machines. */ +static FwSmDesc_t outStreamDesc[CR_FW_NOF_OUTSTREAM]; + +/** The base data structures for the OutStream State Machines and their Procedures. */ +static CrFwCmpData_t outStreamData[CR_FW_NOF_OUTSTREAM]; + +/** The component-specific data for the OutStream State Machines and their Procedures. */ +static CrFwOutStreamData_t outStreamCmpSpecificData[CR_FW_NOF_OUTSTREAM]; + +/** + * Function which enqueues a packet on the packet queue. + * The packet to be enqueued is taken from the data associated to OutStream State + * Machine. + * This function is used as the transition action for the self-transition on the + * BUFFERING state and as a transition action on the transition out of the + * READY state. + * If the packet cannot be enqueued because the packet queue is full, an error + * is generated and the packet is released. + * @param smDesc the state machine descriptor + */ +static void EnqueuePckt(FwSmDesc_t smDesc); + +/** + * Function which flushes the packet queue. + * This function is used as the transition action on the transition out of state + * BUFFERING. + * @param smDesc the state machine descriptor + */ +static void FlushPcktQueue(FwSmDesc_t smDesc); + +/** + * Function which resets to 1 the sequence counter of an out-going packet. + * This function is used as transition action on the transition out of the initial + * state. + * @param smDesc the state machine descriptor + */ +static void ResetSeqCounter(FwSmDesc_t smDesc); + +/** + * Function which first attempts to hand over a packet to the middleware and, + * if this fails, it pushes it on the packet queue. + * This function is used as the transition action out of state READY. + * @param smDesc the state machine descriptor + */ +static void SendOrEnqueue(FwSmDesc_t smDesc); + +/** + * Function which checks if the packet queue is empty. + * This function is used as guard for the transition into state READY. + * @param smDesc the state machine descriptor + * @return 1 if the packet queue is empty; zero otherwise. + */ +static int IsPacketQueueEmpty(FwSmDesc_t smDesc); + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwOutStreamMake(CrFwInstanceId_t i) { + const FwSmCounterS1_t nOfStates = 2; /* Number of states */ + const FwSmCounterS1_t nOfChoicePseudoStates = 1; /* Number of choice pseudo-states */ + const FwSmCounterS1_t nOfTrans = 6; /* Number of transitions */ + const FwSmCounterS1_t nOfActions = 4; /* Number of actions */ + const FwSmCounterS1_t nOfGuards = 1; /* Number of guards */ + const FwSmCounterS1_t CPS_1 = 1; /* Identifier of first choice pseudo-state */ + FwSmDesc_t esm; + FwPrDesc_t resetPr, execPr, initPr; + + if (i >= CR_FW_NOF_OUTSTREAM) { + CrFwSetAppErrCode(crOutStreamIllId); + return NULL; + } + + /* If not yet done, create the base OutStream SM */ + if (baseOutStreamSmDesc == NULL) { + /* Extend the Base Component */ + baseOutStreamSmDesc = FwSmCreateDer(CrFwBaseCmpMake()); + /* Create the OutStream SM and then embed it in state CONFIGURED of the Base Component */ + esm = FwSmCreate(nOfStates, nOfChoicePseudoStates, nOfTrans, nOfActions, nOfGuards); + FwSmAddState(esm, CR_FW_OUTSTREAM_STATE_READY, 1, NULL, NULL, NULL, NULL); + FwSmAddState(esm, CR_FW_OUTSTREAM_STATE_BUFFERING, 2, NULL, NULL, NULL, NULL); + FwSmAddChoicePseudoState(esm, CPS_1, 2); + FwSmAddTransIpsToSta(esm, CR_FW_OUTSTREAM_STATE_READY, &ResetSeqCounter); + FwSmAddTransStaToCps(esm, CR_FW_OUTSTREAM_TR_SEND, CR_FW_OUTSTREAM_STATE_READY, CPS_1, + &SendOrEnqueue, NULL); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_OUTSTREAM_STATE_READY, NULL, &IsPacketQueueEmpty); + FwSmAddTransCpsToSta(esm, CPS_1, CR_FW_OUTSTREAM_STATE_BUFFERING, NULL, NULL); /* Else Transition */ + FwSmAddTransStaToCps(esm, CR_FW_OUTSTREAM_TR_CONNECTION_AVAILABLE, CR_FW_OUTSTREAM_STATE_BUFFERING, + CPS_1, &FlushPcktQueue, NULL); + FwSmAddTransStaToSta(esm, CR_FW_OUTSTREAM_TR_SEND, CR_FW_OUTSTREAM_STATE_BUFFERING, + CR_FW_OUTSTREAM_STATE_BUFFERING, &EnqueuePckt, NULL); + FwSmEmbed(baseOutStreamSmDesc, CR_FW_BASE_STATE_CONFIGURED, esm); + } + + if (outStreamDesc[i] != NULL) { + return outStreamDesc[i]; /* The requested SM has already been created */ + } + + /* Create the requested SM as an extension of the base OutStream SM */ + outStreamDesc[i] = FwSmCreateDer(baseOutStreamSmDesc); + + /* Create the Reset Procedure for the OutStream Component */ + resetPr = FwPrCreateDer(CrFwCmpGetResetProc()); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigCheck, outStreamConfigCheck[i]); + FwPrOverrideAction(resetPr, &CrFwBaseCmpDefConfigAction, outStreamConfigAction[i]); + + /* Create the Initialization Procedure for the OutStream Component */ + initPr = FwPrCreateDer(CrFwCmpGetInitProc()); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitCheck, outStreamInitCheck[i]); + FwPrOverrideAction(initPr, &CrFwBaseCmpDefInitAction, outStreamInitAction[i]); + + /* Override the Shutdown Action for the OutStream Component */ + FwSmOverrideAction(outStreamDesc[i], &CrFwBaseCmpDefShutdownAction, outStreamShutdownAction[i]); + + /* Get the Dummy Execution Procedure for the OutStream Component */ + execPr = CrFwBaseCmpGetDummyExecProc(); + + /* Initialize the data for the requested SM */ + outStreamData[i].outcome = 1; + outStreamData[i].initProc = initPr; + outStreamData[i].resetProc = resetPr; + outStreamData[i].execProc = execPr; + outStreamData[i].instanceId = i; + outStreamData[i].typeId = CR_FW_OUTSTREAM_TYPE; + outStreamCmpSpecificData[i].dest = outStreamDest[i]; + outStreamCmpSpecificData[i].handoverPckt = outStreamHandoverPckt[i]; + outStreamData[i].cmpSpecificData = &outStreamCmpSpecificData[i]; + + /* Attach the data to the OutStream state machine and to its procedures. + * The data is attached to the outer SM and to the SM embedded in state CONFIGURED + * and to the Initialization and Reset Procedures. */ + FwSmSetData(outStreamDesc[i], &outStreamData[i]); + FwSmSetData(FwSmGetEmbSm(outStreamDesc[i], CR_FW_BASE_STATE_CONFIGURED), &outStreamData[i]); + FwPrSetData(outStreamData[i].initProc, &outStreamData[i]); + FwPrSetData(outStreamData[i].resetProc, &outStreamData[i]); + + /* Start the OutStream */ + FwSmStart(outStreamDesc[i]); + + return outStreamDesc[i]; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwOutStreamIsInReady(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_OUTSTREAM_STATE_READY); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwOutStreamIsInBuffering(FwSmDesc_t smDesc) { + return (FwSmGetCurStateEmb(smDesc) == CR_FW_OUTSTREAM_STATE_BUFFERING); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmDesc_t CrFwOutStreamGet(CrFwDestSrc_t dest) { + CrFwInstanceId_t i; + for (i=0; i<CR_FW_NOF_OUTSTREAM; i++) + if (outStreamCmpSpecificData[i].dest == dest) + return outStreamDesc[i]; + + CrFwSetAppErrCode(crOutStreamUndefDest); + return NULL; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutStreamSend(FwSmDesc_t smDesc, CrFwPckt_t pckt) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + cmpSpecificData->pckt = pckt; + FwSmMakeTrans(smDesc, CR_FW_OUTSTREAM_TR_SEND); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutStreamConnectionAvail(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, CR_FW_OUTSTREAM_TR_CONNECTION_AVAILABLE); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwDestSrc_t CrFwOutStreamGetDest(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + return cmpSpecificData->dest; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwSeqCnt_t CrFwOutStreamGetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + return cmpSpecificData->seqCnt[group]; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutStreamSetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group, CrFwSeqCnt_t seqCnt) +{ + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + cmpSpecificData->seqCnt[group] = seqCnt; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwOutStreamGetNOfPendingPckts(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + return CrFwPcktQueueGetNOfPckts(&(cmpSpecificData->pcktQueue)); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwGroup_t CrFwOutStreamGetNOfGroups(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return outStreamNOfGroups[outStreamBaseData->instanceId]; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwOutStreamGetPcktQueueSize(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + return CrFwPcktQueueGetSize(&(cmpSpecificData->pcktQueue)); +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutStreamDefConfigAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + + CrFwPcktQueueReset(&(cmpSpecificData->pcktQueue)); + cmpSpecificData->dest = outStreamDest[outStreamBaseData->instanceId]; + cmpSpecificData->handoverPckt = outStreamHandoverPckt[outStreamBaseData->instanceId]; + outStreamBaseData->outcome = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutStreamDefShutdownAction(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + CrFwPcktQueueShutdown(&(cmpSpecificData->pcktQueue)); + free(cmpSpecificData->seqCnt); + cmpSpecificData->seqCnt = NULL; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwOutStreamDefInitAction(FwPrDesc_t prDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwPrGetData(prDesc); + CrFwInstanceId_t i = outStreamBaseData->instanceId; + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + + cmpSpecificData->seqCnt = malloc(sizeof(CrFwSeqCnt_t)*outStreamNOfGroups[i]); + CrFwPcktQueueInit(&(outStreamCmpSpecificData[i].pcktQueue),outStreamPcktQueueSize[i]); + outStreamBaseData->outcome = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +static void EnqueuePckt(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + CrFwPckt_t pckt = cmpSpecificData->pckt; + CrFwPckt_t pcktCopy; + CrFwPcktQueue_t pcktQueue = &(cmpSpecificData->pcktQueue); + CrFwPcktLength_t len = CrFwPcktGetLength(pckt); + + pcktCopy = CrFwPcktMake(CrFwPcktGetLength(pckt)); + if (pcktCopy == NULL) { + CrFwRepErr(crOutStreamNoMorePckt, outStreamBaseData->typeId, outStreamBaseData->instanceId); + return; + } + memcpy(pcktCopy,pckt,len); + if (!CrFwPcktQueuePush(pcktQueue, pcktCopy)) { + CrFwRepErr(crOutStreamPQFull, outStreamBaseData->typeId, outStreamBaseData->instanceId); + CrFwPcktRelease(pcktCopy); + } + + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void FlushPcktQueue(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + CrFwPckt_t oldestPckt; + CrFwPcktQueue_t pcktQueue = &(cmpSpecificData->pcktQueue); + CrFwGroup_t oldestPcktGroup = 0; + + while (CrFwPcktQueueIsEmpty(pcktQueue)==0) { + oldestPckt = CrFwPcktQueueGetOldest(pcktQueue); + if (CrFwPcktGetSrc(oldestPckt) == CR_FW_HOST_APP_ID) { /* pckt originates from host application */ + oldestPcktGroup = CrFwPcktGetGroup(oldestPckt); + if (oldestPcktGroup < outStreamNOfGroups[outStreamBaseData->instanceId]) + CrFwPcktSetSeqCnt(oldestPckt, cmpSpecificData->seqCnt[oldestPcktGroup]); + else /* pckt belongs to a non-existent group */ + CrFwRepErrGroup(crOutStreamIllGroup, outStreamBaseData->typeId, + outStreamBaseData->instanceId, oldestPcktGroup); + } + if (cmpSpecificData->handoverPckt(oldestPckt) != 1) + return; + if (CrFwPcktGetSrc(oldestPckt) == CR_FW_HOST_APP_ID) + if (oldestPcktGroup < outStreamNOfGroups[outStreamBaseData->instanceId]) + cmpSpecificData->seqCnt[oldestPcktGroup]++; + CrFwPcktQueuePop(pcktQueue); /* remove packet from PQ */ + CrFwPcktRelease(oldestPckt); + } + return; +} + +/*-----------------------------------------------------------------------------------------*/ +static void ResetSeqCounter(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + CrFwGroup_t i; + for (i=0; i<outStreamNOfGroups[outStreamBaseData->instanceId]; i++) + cmpSpecificData->seqCnt[i] = 1; +} + +/*-----------------------------------------------------------------------------------------*/ +static void SendOrEnqueue(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + CrFwPckt_t pckt = cmpSpecificData->pckt; + CrFwPckt_t pcktCopy; + CrFwPcktLength_t len; + CrFwPcktQueue_t pcktQueue; + CrFwGroup_t pcktGroup = 0; /* added by UVIE */ + + if (CrFwPcktGetSrc(pckt) == CR_FW_HOST_APP_ID) { /* pckt originates from host application */ + pcktGroup = CrFwPcktGetGroup(pckt); + if (pcktGroup < outStreamNOfGroups[outStreamBaseData->instanceId]) + CrFwPcktSetSeqCnt(pckt, cmpSpecificData->seqCnt[pcktGroup]); + else /* pckt belongs to a non-existent group */ + CrFwRepErrGroup(crOutStreamIllGroup, outStreamBaseData->typeId, + outStreamBaseData->instanceId, pcktGroup); + } + if (cmpSpecificData->handoverPckt(pckt) != 1) { + pcktQueue = &(cmpSpecificData->pcktQueue); + len = CrFwPcktGetLength(pckt); + pcktCopy = CrFwPcktMake(len); + if (pcktCopy == NULL) { + CrFwRepErr(crOutStreamNoMorePckt, outStreamBaseData->typeId, outStreamBaseData->instanceId); + return; + } + memcpy(pcktCopy,pckt,len); + CrFwPcktQueuePush(pcktQueue,pcktCopy); /* Enqueue packet, queue is empty at entry in READY */ + } else { + if (CrFwPcktGetSrc(pckt) == CR_FW_HOST_APP_ID) + if (pcktGroup < outStreamNOfGroups[outStreamBaseData->instanceId]) + cmpSpecificData->seqCnt[pcktGroup]++; + } +} + +/*-----------------------------------------------------------------------------------------*/ +static int IsPacketQueueEmpty(FwSmDesc_t smDesc) { + CrFwCmpData_t* outStreamBaseData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutStreamData_t* cmpSpecificData = (CrFwOutStreamData_t*)outStreamBaseData->cmpSpecificData; + return CrFwPcktQueueIsEmpty(&(cmpSpecificData->pcktQueue)); +} + diff --git a/CrFramework/src/OutStream/CrFwOutStream.h b/CrFramework/src/OutStream/CrFwOutStream.h new file mode 100644 index 0000000000000000000000000000000000000000..1a3068a907770a169adcd2e75def7bb9fb9f134e --- /dev/null +++ b/CrFramework/src/OutStream/CrFwOutStream.h @@ -0,0 +1,261 @@ +/** + * @file + * @ingroup outMngGroup + * Definition of the OutStream component. + * + * An application will normally instantiate one OutStream Component for + * each report or command destination. + * An OutStream is implemented by the OutStream State Machine (see figures below) + * embedded within state CONFIGURED of a Base State Machine. + * + * This header file defines a function to create and access the OutStream attached to a + * certain command or report destination. + * This header file therefore also defines the interface to the OutStreamRegistry + * component of the CORDET Framework. + * + * An application can instantiate several OutStream Components. + * Each OutStream instance has an identifier which uniquely identifies it + * within the set of OutStream Components. + * This identifier is an integer in the range 0 to: <code>#CR_FW_NOF_OUTSTREAM</code>-1. + * + * <b>Mode of Use of an OutStream Component</b> + * + * The configuration of the OutStream components is defined statically in + * <code>CrFwOutStreamUserPar.h</code>. + * + * An OutStream component is created with function <code>::CrFwOutStreamMake</code>. + * After being created, the OutStream must be initialized and reset. + * This is done with functions <code>::CrFwCmpInit</code> and <code>::CrFwCmpReset</code>. + * Nominally, after being initialized and reset the OutStream State Machine should be + * in state CONFIGURED (this can be checked by verifying that function <code>FwSmGetCurState</code> + * returns CR_FW_BASE_STATE_CONFIGURED). + * + * After it has been configured, an OutStream can process two transition commands: + * - A Send command to send a packet (representing either a command or a report) + * to the middleware connection attached to the OutStream. + * This command is sent through function <code>::CrFwOutStreamSend</code>. + * - A ConnectionAvailable command to signal the ability of the middleware to send + * a new packet to its destination. This command is sent with the + * the <code>::CrFwOutStreamConnectionAvail</code> function. + * . + * If at the time the Send command is received, the middleware is not ready to receive + * the packet, the packet is stored in Packet Queue. + * The next attempt to send it out will be made when command ConnectionAvailable is sent. + * + * @image html OutStream.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_OUT_STREAM_H_ +#define CRFW_OUT_STREAM_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Configuration Files */ +#include "Pckt/CrFwPcktQueue.h" +#include "CrFwUserConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" + +/** + * Factory function to retrieve the i-th OutStream State Machine instance. + * The first time this function is called with a certain value of the argument i, it + * creates the i-th OutStream State Machine instance. + * Subsequent calls returns the same instance. + * + * The OutStream identifier i must be in the range: [0, <code>#CR_FW_NOF_OUTSTREAM</code>-1]. + * If the identifier is out of range, the function returns NULL and sets the application + * error code to: <code>::crOutStreamIllId</code>. + * + * The first time this function is called with a certain value of i, it returns an + * OutStream State Machine which has been started but which still needs to be initialized and + * configured. + * @param outStreamId the identifier of the Base State Machine of the OutStream + * @return the descriptor of the OutStream State Machine or NULL + * if the state machine could not be created or if the identifier i is out of range. + */ +FwSmDesc_t CrFwOutStreamMake(CrFwInstanceId_t outStreamId); + +/** + * Return true if the argument OutStream is in state READY. + * @param smDesc the descriptor of the Base State Machine of the OutStream + * @return 1 if the argument InCommand is in state CONFIGURED, sub-state + * READY; 0 otherwise + */ +CrFwBool_t CrFwOutStreamIsInReady(FwSmDesc_t smDesc); + +/** + * Return true if the argument OutStream is in state BUFFERING. + * @param smDesc the descriptor of the Base State Machine of the OutStream + * @return 1 if the argument InCommand is in state CONFIGURED, sub-state + * BUFFERING; 0 otherwise + */ +CrFwBool_t CrFwOutStreamIsInBuffering(FwSmDesc_t smDesc); + +/** + * Getter function for the OutStream corresponding to the argument destination. + * Nominally, each OutStream is associated to a certain destination. + * The binding between an OutStream and its destination is done statically in the + * configuration file <code>CrFwOutStreamUserPar.h</code>. + * + * If the value of the destination argument is illegal (i.e. if no + * OutStream has been bound to it), this function returns NULL and sets the + * application error code to: <code>::crOutStreamUndefDest</code>. + * + * This function should only be called after all OutStreams have been built through + * calls to function <code>::CrFwOutStreamMake</code>. + * If this pre-condition is not satisfied, execution of this function could result + * in an access to a NULL pointer. + * @param dest the destination associated to the OutStream + * @return the descriptor of the OutStream State Machine or NULL + * if the argument destination was illegal or no OutStream had been bound to it. + */ +FwSmDesc_t CrFwOutStreamGet(CrFwDestSrc_t dest); + +/** + * Send a packet to the OutStream. + * This function hands over the argument packet to the OutStream and then it sends + * command "Send" to its state machine. + * This causes the OutStream to try to send the packet to the destination associated + * to the OutStream. + * If the middleware is not ready to accept the packet, then a copy of the packet + * is made and is stored in the OutStream's Packet Queue from where it will be sent to + * the middleware at a later time. + * If the packet copy cannot be done because no more free packets + * are available, error <code>::crOutStreamNoMorePckt</code> is generated. + * If the Packet Queue is full, the packet is released and error + * <code>::crOutStreamPQFull</code> is generated. + * + * If packet cannot be sent to the middleware (or to make a copy of the packet and buffer the copy internally + * if the middleware is currently not available). + * + * The argument <code>pckt</code> is a pointer to the out-going packet. + * This pointer is "owned" by the caller of function <code>CrFwOutStreamSend</code> + * who remains responsible for releasing it when it is no longer needed. + * The function only uses the pointer during its execution. + * @param smDesc the descriptor of the OutStream State Machine. + * @param pckt the packet to be sent by the OutStream + */ +void CrFwOutStreamSend(FwSmDesc_t smDesc, CrFwPckt_t pckt); + +/** + * Signal that the out-going middleware connection has become available. + * This function sends the ConnectionAvailable command to the OutStream State Machine. + * @param smDesc the descriptor of the OutStream State Machine. + */ +void CrFwOutStreamConnectionAvail(FwSmDesc_t smDesc); + +/** + * Default configuration action for an OutStream. + * This function resets the packet queue of the OutStream. + * + * Configuration actions have an outcome (see <code>CrFwResetProc.h</code>). + * The outcome of this configuration action is always "success". + * + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Configuration Actions. + * @param prDesc the descriptor of the Reset Procedure of the OutStream + */ +void CrFwOutStreamDefConfigAction(FwPrDesc_t prDesc); + +/** + * Default initialization action for an OutStream. + * This function: (a) allocates the memory for the packet queue of the OutStream; + * (b) allocates the memory for the array holding the sequence counters for the + * groups attached to the OutStream; and + * (c) initializes all data structures implementing the OutStream. + * Initialization actions have an outcome (see <code>CrFwResetProc.h</code>). + * The situation of where the memory allocation fails is not handled and + * therefore the outcome of this configuration action is always "success". + * + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Initialization Actions. + * @param prDesc the descriptor of the Initialization Procedure of the OutStream + */ +void CrFwOutStreamDefInitAction(FwPrDesc_t prDesc); + +/** + * Default shutdown action for an OutStream. + * This function releases the memory allocated to the packet queue of the OutStream + * and releases the memory allocated to the array holding the sequence counters. + * + * This function should never be directly called by the end-application. + * It is declared as a public function so that it may be used in application-specific + * Shutdown Actions. + * @param smDesc the descriptor of the OutStream State Machine + */ +void CrFwOutStreamDefShutdownAction(FwSmDesc_t smDesc); + +/** + * Get the destination for an OutStream. + * @param smDesc the descriptor of the OutStream State Machine. + * @return dest the destination associated to the OutStream + */ +CrFwDestSrc_t CrFwOutStreamGetDest(FwSmDesc_t smDesc); + +/** + * Return the value of the sequence counter for one of the groups + * maintained by an OutStream. + * The group identifier is passed as an argument to the function call. + * No check is performed on the validity of the group identifier. + * @param smDesc the descriptor of the OutStream State Machine. + * @param group the identifier of the group + * @return the OutStream sequence counter + */ +CrFwSeqCnt_t CrFwOutStreamGetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group); + +/** + * Sets the value of the sequence counter for one of the groups + * maintained by an OutStream. + * The group identifier is passed as an argument to the function call. + * No check is performed on the validity of the group identifier. + * @param smDesc the descriptor of the OutStream State Machine. + * @param group the identifier of the group + * @param seqCnt the OutStream sequence counter + */ +void CrFwOutStreamSetSeqCnt(FwSmDesc_t smDesc, CrFwGroup_t group, CrFwSeqCnt_t seqCnt); + +/** + * Return the number of packets currently in the packet queue of an OutStream. + * @param smDesc the descriptor of the OutStream State Machine. + * @return the number of packets currently in the packet queue of the OutStream. + */ +CrFwCounterU1_t CrFwOutStreamGetNOfPendingPckts(FwSmDesc_t smDesc); + +/** + * Return the number of groups associated to the OutStream. + * @param smDesc the descriptor of the OutStream State Machine. + * @return the number of groups associated to the OutStream. + */ +CrFwGroup_t CrFwOutStreamGetNOfGroups(FwSmDesc_t smDesc); + +/** + * Return the size of the packet queue of the OutStream. + * @param smDesc the descriptor of the OutStream State Machine. + * @return the size of the packet queue of the OutStream. + */ +CrFwCounterU1_t CrFwOutStreamGetPcktQueueSize(FwSmDesc_t smDesc); + +#endif /* CRFW_OUT_STREAM_H_ */ diff --git a/CrFramework/src/Pckt/CrFwPckt.h b/CrFramework/src/Pckt/CrFwPckt.h new file mode 100644 index 0000000000000000000000000000000000000000..04eacc5b74a6c353d2f8de41fa73d630f73a7750 --- /dev/null +++ b/CrFramework/src/Pckt/CrFwPckt.h @@ -0,0 +1,368 @@ +/** + * @file + * @ingroup crOpenIfGroup + * Interface for creating and accessing a report or command packet. + * An application instantiated from the CORDET Framework interacts with other + * framework applications by exchanging with them commands and reports. + * When commands and reports travel from one application to another, they + * take the form of packets. + * + * A packet is an ordered sequence of bytes which contain all the information + * required to reconstruct a report or a command. + * Although the exact layout of packets is not defined at framework level, + * the framework defines, through this header file, an interface for creating and + * accessing the data in a packet. + * + * This interface defines a packet factory, namely a function which allows + * a new packet to be created and an existing packet to be released. + * + * A packet encapsulates either a command or a report. + * This interface defines functions through which the attributes of the encapsulated + * command or report can be retrieved from a packet or can be set in a packet. + * For attributes other than the command or report parameters, getter and setter + * functions are defined. + * For the command or report parameters, getter functions are provided which return: + * the start address of the parameter area of the packet and its size. + * The parameter area is the part of a packet which is reserved to the storage + * of the parameters of the command or report encapsulated by the packet. + * + * In general, the implementation of this interface is entirely application-specific + * but a simple default implementation is provided in <code>CrFwPckt.c</code>. + * This default implementation is primarily intended for testing and demonstration + * purposes. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_PACKET_H_ +#define CRFW_PACKET_H_ + +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Make function for command or report packets. + * This function returns an unconfigured packet of the specified length. + * An unconfigured packet of length L consists of a sequence of L bytes. + * The function allocates the memory for the packet and returns a pointer to the + * allocated memory. + * + * The memory allocated to the packet remains reserved to the packet until the + * packet is released through a call to function <code>::CrFwPcktRelease</code>. + * The content of the packet returned by this function is undefined. + * The way the memory is allocated and released is implementation-specific. + * + * If the allocation of the memory for the new packet failed, the function returns + * NULL. + * Depending on the implementation, allocation memory failure may result in + * the application error code being set to <code>crPcktAllocationFail</code>. + * + * The packet length must be a positive integer. + * If a negative or a zero value is used, the function returns NULL. + * Depending on the implementation, this may also result in + * the application error code being set to <code>crPcktAllocationFail</code>. + * @param pcktLength the length of the packet in bytes (a positive integer) + * @return a new packet or NULL if it was not possible to allocate the memory + * for the packet or if the packet length was not a positive integer + */ +CrFwPckt_t CrFwPcktMake(CrFwPcktLength_t pcktLength); + +/** + * Release function for command or report packets. + * The argument of this function must be a packet which was created using function + * <code>CrFwPcktMake</code>. + * This function releases the memory which was allocated to the argument packet. + * After this function is called, the argument packet cannot be used. + * The function does not perform any checks on the existence or status of the + * argument packet. + * An attempt to use a packet which had already been released will + * result in undefined behaviour. + * + * An attempt to release a packet which had already been released, or to release a + * non-existent packet will result in undefined behaviour. + * Depending on the implementation, such attempts may result in the application + * error code being set to: <code>::crPcktRelErr</code>. + * @param pckt the packet to be released + */ +void CrFwPcktRelease(CrFwPckt_t pckt); + +/** + * Check whether a packet of a specified length is available. + * A packet of length L is available if a call to function <code>::CrFwPcktMake</code> + * with argument L would return a non-NULL value. + * Applications typically implement the <code>CrFwPckt.h</code> interface to manage a pool of + * pre-allocated memory from which packets are allocated using function + * <code>::CrFwPcktMake</code> and are released using function <code>::CrFwPcktRelease</code>. + * This function does not change the state of the pool from which the packets + * are allocated. It only verifies whether the allocation of a packet of a given + * length would be possible at the time the function is called. + * + * The packet length must be a positive integer. + * If a negative or a zero value is used, the function returns false. + * @param pcktLength the length of the packet in bytes (a positive integer) + * @return true if a packet of the specified length is available, false otherwise + * of if the length is not a positive integer + */ +CrFwBool_t CrFwPcktIsAvail(CrFwPcktLength_t pcktLength); + +/** + * Return the number of packets which are currently allocated. + * This function returns the number of packets which have been successfully + * allocated through calls to <code>::CrFwPcktMake</code> and have not yet been + * released through calls to <code>::CrFwPcktRelease</code>. + * @return the number of packets which are currently allocated. + */ +CrFwCounterU2_t CrFwPcktGetNOfAllocated(); + +/** + * Return the maximum length of a packet in number of bytes. + * Some implementation may restrict the maximum length of a packet. + * This function allows this maximum length to be retrieved. + * If the function returns a value of zero, then no restriction on the length of + * a packet is defined by the implementation. + * @return the maximum length of a packet in number of bytes or zero if no restriction + * on the packet length exists. + */ +CrFwPcktLength_t CrFwPcktGetMaxLength(); + +/** + * Return the type of a packet (either a command packet or a report packet). + * @param pckt the packet + * @return the type of the entity (a command or a report) encapsulated by the packet. + */ +CrFwCmdRepType_t CrFwPcktGetCmdRepType(CrFwPckt_t pckt); + +/** + * Set the type of a packet (either a command packet or a report packet). + * @param pckt the packet + * @param type the type of the entity (a command or a report) encapsulated by the packet. + */ +void CrFwPcktSetCmdRepType(CrFwPckt_t pckt, CrFwCmdRepType_t type); + +/** + * Return the length (in number of bytes) of a packet. + * @param pckt the packet. + * @return the length (in number of bytes) of the packet. + */ +CrFwPcktLength_t CrFwPcktGetLength(CrFwPckt_t pckt); + +/** + * Return the sequence counter of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the sequence counter. + */ +CrFwSeqCnt_t CrFwPcktGetSeqCnt(CrFwPckt_t pckt); + +/** + * Set the sequence counter of the command or report encapsulated in a packet. + * @param pckt the packet. + * @param seqCnt the sequence counter. + */ +void CrFwPcktSetSeqCnt(CrFwPckt_t pckt, CrFwSeqCnt_t seqCnt); + +/** + * Return the time stamp of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the time stamp. + */ +CrFwTimeStamp_t CrFwPcktGetTimeStamp(CrFwPckt_t pckt); + +/** + * Set the time stamp of the command or report encapsulated in a packet. + * @param pckt the packet. + * @param timeStamp the time stamp. + */ +void CrFwPcktSetTimeStamp(CrFwPckt_t pckt, CrFwTimeStamp_t timeStamp); + +/** + * Return the discriminant of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the discriminant. + */ +CrFwDiscriminant_t CrFwPcktGetDiscriminant(CrFwPckt_t pckt); + +/** + * Set the discriminant of the command or report encapsulated in a packet. + * @param pckt the packet. + * @param discriminant the discriminant. + */ +void CrFwPcktSetDiscriminant(CrFwPckt_t pckt, CrFwDiscriminant_t discriminant); + +/** + * Set the service type of the command or report encapsulated in a packet. + * @param pckt the packet. + * @param servType the service type. + */ +void CrFwPcktSetServType(CrFwPckt_t pckt, CrFwServType_t servType); + +/** + * Return the service type of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the service type. + */ +CrFwServType_t CrFwPcktGetServType(CrFwPckt_t pckt); + +/** + * Set the service sub-type of the command or report encapsulated in a packet. + * @param pckt the packet. + * @param servSubType the service sub-type. + */ +void CrFwPcktSetServSubType(CrFwPckt_t pckt, CrFwServSubType_t servSubType); + +/** + * Return the service sub-type of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the service sub-type. + */ +CrFwServSubType_t CrFwPcktGetServSubType(CrFwPckt_t pckt); + +/** + * Set the group of the command/report encapsulated in a packet. + * @param pckt the packet. + * @param group the destination or source group of the packet. + */ +void CrFwPcktSetGroup(CrFwPckt_t pckt, CrFwGroup_t group); + +/** + * Return the group of the command/report encapsulated in a packet. + * @param pckt the packet. + * @return the destination or source group of the packet. + */ +CrFwGroup_t CrFwPcktGetGroup(CrFwPckt_t pckt); + +/** + * Set the destination of the command or report encapsulated in a packet. + * @param pckt the packet. + * @param dest the destination of the packet. + */ +void CrFwPcktSetDest(CrFwPckt_t pckt, CrFwDestSrc_t dest); + +/** + * Return the destination of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the destination of the packet. + */ +CrFwDestSrc_t CrFwPcktGetDest(CrFwPckt_t pckt); + +/** + * Set the source of the command or report encapsulated in a packet. + * @param pckt the packet. + * @param src the source of the packet. + */ +void CrFwPcktSetSrc(CrFwPckt_t pckt, CrFwDestSrc_t src); + +/** + * Return the source of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the source of the packet. + */ +CrFwDestSrc_t CrFwPcktGetSrc(CrFwPckt_t pckt); + +/** + * Set the command or report identifier in the command or report encapsulated in a packet. + * @param pckt the packet. + * @param id the command or report identifier. + */ +void CrFwPcktSetCmdRepId(CrFwPckt_t pckt, CrFwInstanceId_t id); + +/** + * Return the command or report identifier of the command or report encapsulated in a packet. + * @param pckt the packet. + * @return the command or report identifier. + */ +CrFwInstanceId_t CrFwPcktGetCmdRepId(CrFwPckt_t pckt); + +/** + * Set the acknowledge level for the command encapsulated in a packet. + * If the packet on which this function is called does not encapsulate a command, nothing + * is done. + * @param pckt the packet. + * @param accept 1 if acknowledge of command acceptance is desired, 0 otherwise. + * @param start 1 if acknowledge of command start is desired, 0 otherwise. + * @param progress 1 if acknowledge of command progress is desired, 0 otherwise. + * @param term 1 if acknowledge of command acceptance termination is desired, 0 otherwise. + */ +void CrFwPcktSetAckLevel(CrFwPckt_t pckt, CrFwBool_t accept, CrFwBool_t start, + CrFwBool_t progress, CrFwBool_t term); + +/** + * Return the acknowledge level for command acceptance for the command encapsulated in the + * packet. + * If the packet does not hold a command, the behaviour of the function is undefined. + * @param pckt a packet encapsulating a command. + * @return 1 if command acceptance is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwPcktIsAcceptAck(CrFwPckt_t pckt); + +/** + * Return the acknowledge level for command start for the command encapsulated in the + * packet. + * If the packet does not hold a command, the behaviour of the function is undefined. + * @param pckt a packet encapsulating a command. + * @return 1 if command start is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwPcktIsStartAck(CrFwPckt_t pckt); + +/** + * Return the acknowledge level for command progress for the command encapsulated in the + * packet. + * If the packet does not hold a command, the behaviour of the function is undefined. + * @param pckt a packet encapsulating a command. + * @return 1 if command progress is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwPcktIsProgressAck(CrFwPckt_t pckt); + +/** + * Return the acknowledge level for command termination for the command encapsulated in the + * packet. + * If the packet does not hold a command, the behaviour of the function is undefined. + * @param pckt a packet encapsulating a command. + * @return 1 if command termination is to be acknowledged, 0 otherwise. + */ +CrFwBool_t CrFwPcktIsTermAck(CrFwPckt_t pckt); + +/** + * Return the start address of the packet's parameter area. + * The parameter area is the part of a packet which is reserved to the storage + * of the parameters of the command or report encapsulated by the packet. + * The parameter area consists of an uninterrupted sequence of bytes. + * The size of the parameter area is returned by function <code>::CrFwPcktGetParLength</code>. + * @param pckt a packet encapsulating a command or a report. + * @return the start address of the packet's parameter area. + */ +char* CrFwPcktGetParStart(CrFwPckt_t pckt); + +/** + * Return the length in bytes of the packet's parameter area. + * The parameter area is the part of a packet which is reserved to the storage + * of the parameters of the command or report encapsulated by the packet. + * The parameter area consists of an uninterrupted sequence of bytes. + * The start address of the parameter area is returned by function <code>::CrFwPcktGetParStart</code>. + * @param pckt a packet encapsulating a command or a report. + * @return the length in bytes of the packet's parameter area. + */ +CrFwPcktLength_t CrFwPcktGetParLength(CrFwPckt_t pckt); + + +#endif /* CRFW_PACKET_H_ */ diff --git a/CrFramework/src/Pckt/CrFwPcktQueue.c b/CrFramework/src/Pckt/CrFwPcktQueue.c new file mode 100644 index 0000000000000000000000000000000000000000..cede4819d4cd54f1e9dbea7d93cf88c67f167b56 --- /dev/null +++ b/CrFramework/src/Pckt/CrFwPcktQueue.c @@ -0,0 +1,146 @@ +/** + * @file + * @ingroup pcktGroup + * Implementation of Packet Queue Management. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +#include "../CrFwConstants.h" +#include "CrFwPckt.h" +#include "CrFwPcktQueue.h" + +/*-----------------------------------------------------------------------------------------*/ +CrFwPckt_t CrFwPcktQueuePop(CrFwPcktQueue_t pcktQueue) { + CrFwCounterU1_t posOldest; + CrFwPckt_t oldestPckt; + + if (!pcktQueue->isEmpty) { + posOldest = pcktQueue->oldestItem; + oldestPckt = pcktQueue->pckt[posOldest]; + if (posOldest < (pcktQueue->size-1)) + pcktQueue->oldestItem++; + else + pcktQueue->oldestItem = 0; + if (pcktQueue->oldestItem == pcktQueue->nextFreeItem) + pcktQueue->isEmpty = 1; + return oldestPckt; + } else + return NULL; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwPckt_t CrFwPcktQueueGetOldest(CrFwPcktQueue_t pcktQueue) { + if (!pcktQueue->isEmpty) + return pcktQueue->pckt[pcktQueue->oldestItem]; + else + return NULL; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwPcktQueuePush(CrFwPcktQueue_t pcktQueue, CrFwPckt_t pckt) { + if (pcktQueue->isEmpty == 1) { + pcktQueue->pckt[0] = pckt; + pcktQueue->nextFreeItem = 1; + pcktQueue->oldestItem =0; + pcktQueue->isEmpty = 0; + return 1; + } + + if (pcktQueue->nextFreeItem == pcktQueue->oldestItem) + return 0; + + pcktQueue->pckt[pcktQueue->nextFreeItem] = pckt; + if (pcktQueue->nextFreeItem < (pcktQueue->size-1)) + pcktQueue->nextFreeItem++; + else + pcktQueue->nextFreeItem = 0; + return 1; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwPcktQueueReset(CrFwPcktQueue_t pcktQueue) { + CrFwCounterU1_t i; + + if (pcktQueue->isEmpty == 1) + return; + + if (pcktQueue->oldestItem < pcktQueue->nextFreeItem) { + for (i=pcktQueue->oldestItem; i<pcktQueue->nextFreeItem; i++) + CrFwPcktRelease(pcktQueue->pckt[i]); + pcktQueue->isEmpty = 1; + return; + } + + for (i=pcktQueue->oldestItem; i<pcktQueue->size; i++) + CrFwPcktRelease(pcktQueue->pckt[i]); + for (i=0; i<pcktQueue->nextFreeItem; i++) + CrFwPcktRelease(pcktQueue->pckt[i]); + pcktQueue->isEmpty = 1; + return; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwPcktQueueInit(CrFwPcktQueue_t pcktQueue, CrFwCounterU1_t size) { + CrFwCounterU1_t i; + + if (pcktQueue->pckt != NULL) + return; + + pcktQueue->pckt = malloc(size*sizeof(CrFwPckt_t)); + for (i=0; i<size; i++) + pcktQueue->pckt[i] = NULL; + pcktQueue->isEmpty = 1; + pcktQueue->nextFreeItem = 0; + pcktQueue->oldestItem = 0; + pcktQueue->size = size; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwPcktQueueShutdown(CrFwPcktQueue_t pcktQueue) { + CrFwPcktQueueReset(pcktQueue); + free(pcktQueue->pckt); + pcktQueue->pckt = NULL; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwPcktQueueIsEmpty(CrFwPcktQueue_t pcktQueue) { + return pcktQueue->isEmpty; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwPcktQueueGetNOfPckts(CrFwPcktQueue_t pcktQueue) { + + if (pcktQueue->isEmpty == 1) + return 0; + + if (pcktQueue->oldestItem < pcktQueue->nextFreeItem) + return (CrFwCounterU1_t)(pcktQueue->nextFreeItem - pcktQueue->oldestItem); + + return (CrFwCounterU1_t)(pcktQueue->size - (pcktQueue->oldestItem - pcktQueue->nextFreeItem)); +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCounterU1_t CrFwPcktQueueGetSize(CrFwPcktQueue_t pcktQueue) { + return pcktQueue->size; +} diff --git a/CrFramework/src/Pckt/CrFwPcktQueue.h b/CrFramework/src/Pckt/CrFwPcktQueue.h new file mode 100644 index 0000000000000000000000000000000000000000..1720d4ea75c7ad72ba65f48c8b047ca63a86ca14 --- /dev/null +++ b/CrFramework/src/Pckt/CrFwPcktQueue.h @@ -0,0 +1,136 @@ +/** + * @file + * @ingroup pcktGroup + * Definition and management of packet queues. + * An application instantiated from the CORDET Framework interacts with other + * framework applications by exchanging with them commands and reports. + * When commands and reports travel from one application to another, they + * take the form of packets. + * + * A packet is an ordered sequence of bytes which contain all the information + * required to reconstruct a report or a command. + * Although the exact layout of packets is not defined at framework level, + * the framework defines in <code>CrFwPckt.h</code> an interface for creating and + * accessing a packet. + * + * Components which send or receive packets need to manage packet queues. + * A packet queue is a data structure which holds a set of packets and manages + * them in FIFO order. + * This file defines a type for packet queues and defines the operations + * for managing a packet queue. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_PACKETQUEUE_H_ +#define CRFW_PACKETQUEUE_H_ + +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Pop a packet from the packet queue. + * If the packet queue is not empty, this function returns the oldest packet + * in the queue. + * If the packet queue is empty, this function returns NULL. + * @param pcktQueue the packet queue. + * @return the oldest packet on the packet or NULL if the packet queue was empty. + */ +CrFwPckt_t CrFwPcktQueuePop(CrFwPcktQueue_t pcktQueue); + +/** + * Return the oldest packet from the queue without removing it from the queue. + * If the packet queue is not empty, this function returns the oldest packet + * in the queue but does not remove the packet from queue. + * If the packet queue is empty, this function returns NULL. + * @param pcktQueue the packet queue. + * @return the oldest packet on the packet or NULL if the packet queue was empty. + */ +CrFwPckt_t CrFwPcktQueueGetOldest(CrFwPcktQueue_t pcktQueue); + +/** + * Push a packet onto the packet queue. + * If the packet queue is not full, this function adds the packet to the packet + * queue and return 1. + * If the packet queue is full, this function does nothing and returns 0. + * @param pcktQueue the packet queue + * @param pckt the packet to be pushed onto the packet queue. + * @return 1 if the push operation was successful, or 0 if the push operation failed + * because the packet queue was full. + */ +CrFwBool_t CrFwPcktQueuePush(CrFwPcktQueue_t pcktQueue, CrFwPckt_t pckt); + +/** + * Initializes the packet queue. + * This function allocates the memory for the packet queue and then initializes + * it to represent an empty packet queue. + * The initialization of a packet queue can only be done once. + * If the packet queue has already been initialized, this function returns without + * doing anything. + * The situation where the memory allocation operation for the packet queue fails + * is not handled and will result in undefined behaviour (probably, a run-time exception). + * @param pcktQueue the packet queue. + * @param size the size of the packet queue + */ +void CrFwPcktQueueInit(CrFwPcktQueue_t pcktQueue, CrFwCounterU1_t size); + +/** + * Reset the packet queue. + * This function clears all entries in the packet queue and releases all packets + * which are in the packet queue. + * @param pcktQueue the packet queue. + */ +void CrFwPcktQueueReset(CrFwPcktQueue_t pcktQueue); + +/** + * Shutdown the packet queue. + * This function resets the packet queue (using function <code>::CrFwPcktQueueReset</code>) + * and then releases the memory which allocated for the packet queue through function + * <code>::CrFwPcktQueueInit</code>. + * @param pcktQueue the packet queue. + */ +void CrFwPcktQueueShutdown(CrFwPcktQueue_t pcktQueue); + +/** + * Return 1 if the packet queue is empty and 0 otherwise. + * @param pcktQueue the packet queue. + * @return 1 if the packet queue is empty and 0 otherwise. + */ +CrFwBool_t CrFwPcktQueueIsEmpty(CrFwPcktQueue_t pcktQueue); + +/** + * Return the number of packets currently in the packet queue. + * @param pcktQueue the packet queue + * @return the number of packets currently in the packet queue. + */ +CrFwCounterU1_t CrFwPcktQueueGetNOfPckts(CrFwPcktQueue_t pcktQueue); + +/** + * Return the size of the packet queue. + * @param pcktQueue the packet queue + * @return the packet queue size. + */ +CrFwCounterU1_t CrFwPcktQueueGetSize(CrFwPcktQueue_t pcktQueue); + +#endif /* CRFW_PACKETQUEUE_H_ */ diff --git a/CrFramework/src/UtilityFunctions/CrFwUtilityFunctions.c b/CrFramework/src/UtilityFunctions/CrFwUtilityFunctions.c new file mode 100644 index 0000000000000000000000000000000000000000..27486c0c210f0f28947e3e820b238c5543f282fe --- /dev/null +++ b/CrFramework/src/UtilityFunctions/CrFwUtilityFunctions.c @@ -0,0 +1,148 @@ +/** + * @file + * Implementation of utility functions. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include <stdlib.h> +/* Include framework files */ +#include "CrFwConstants.h" +#include "BaseCmp/CrFwBaseCmp.h" +#include "BaseCmp/CrFwInitProc.h" +#include "BaseCmp/CrFwResetProc.h" +/* Include FW Profile files */ +#include "FwSmConstants.h" +#include "FwSmDCreate.h" +#include "FwSmConfig.h" +#include "FwSmCore.h" +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" +/* Include configuration files */ +#include "CrFwCmpData.h" + +/** The application error code. */ +static CrFwAppErrCode_t appErrCode = crNoAppErr; + +/*-----------------------------------------------------------------------------------------*/ +CrFwAppErrCode_t CrFwGetAppErrCode() { + return appErrCode; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwSetAppErrCode(CrFwAppErrCode_t errCode) { + appErrCode = errCode; +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrBool_t CrFwIsPrOutcomeOne(FwPrDesc_t prDesc) { + CrFwCmpData_t* prData = (CrFwCmpData_t*)FwPrGetData(prDesc); + return (prData->outcome); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmBool_t CrFwIsSmOutcomeZero(FwSmDesc_t smDesc) { + CrFwCmpData_t* smData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return (smData->outcome == 0); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmBool_t CrFwIsSmOutcomeOne(FwSmDesc_t smDesc) { + CrFwCmpData_t* smData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return (smData->outcome == 1); +} + +/*-----------------------------------------------------------------------------------------*/ +FwSmBool_t CrFwIsSmOutcomeTwo(FwSmDesc_t smDesc) { + CrFwCmpData_t* smData = (CrFwCmpData_t*)FwSmGetData(smDesc); + return (smData->outcome == 2); +} + +/*-----------------------------------------------------------------------------------------*/ +FwPrBool_t CrFwWaitOnePrCycle(FwPrDesc_t prDesc) { + if (FwPrGetNodeExecCnt(prDesc) > 0) + return 1; + else + return 0; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwPrCheckAlwaysTrue(FwPrDesc_t prDesc) { + CRFW_UNUSED(prDesc); + return 1; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwSmCheckAlwaysTrue(FwSmDesc_t smDesc) { + CRFW_UNUSED(smDesc); + return 1; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwBool_t CrFwSmCheckAlwaysFalse(FwSmDesc_t smDesc) { + CRFW_UNUSED(smDesc); + return 0; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwPrEmptyAction(FwPrDesc_t prDesc) { + CRFW_UNUSED(prDesc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +void CrFwSmEmptyAction(FwSmDesc_t smDesc) { + CRFW_UNUSED(smDesc); + return; +} + +/*-----------------------------------------------------------------------------------------*/ +CrFwCmdRepKindIndex_t CrFwFindCmdRepKindIndex(CrFwCmdRepKindKey_t* cmdRepKindArray, + CrFwCmdRepKindIndex_t length, CrFwCmdRepKindKey_t targetKey) { + + CrFwCmdRepKindIndex_t pos_lower, pos_upper, pos_half; + + pos_lower = 0; + pos_upper = (CrFwCmdRepKindIndex_t)(length-1); + + while (pos_lower < pos_upper) { + pos_half = (CrFwCmdRepKindIndex_t)(pos_lower+(pos_upper-pos_lower)/2); + if (pos_half == pos_lower) + break; + if (targetKey > cmdRepKindArray[pos_half]) { + pos_lower = pos_half; + } else if (targetKey < cmdRepKindArray[pos_half]) { + pos_upper = pos_half; + } else + return pos_half; + } + + if (targetKey == cmdRepKindArray[pos_lower]) + return pos_lower; + + if (targetKey == cmdRepKindArray[pos_upper]) + return pos_upper; + + return length; +} diff --git a/CrFramework/src/UtilityFunctions/CrFwUtilityFunctions.h b/CrFramework/src/UtilityFunctions/CrFwUtilityFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..469500856627f5420b7b721cef36d8c91f190fbf --- /dev/null +++ b/CrFramework/src/UtilityFunctions/CrFwUtilityFunctions.h @@ -0,0 +1,176 @@ +/** + * @file + * @ingroup utilityFunctionsGroup + * Definition of the utility functions for the CORDET Framework. + * + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2013, All Rights Reserved + * + * This file is part of CORDET Framework. + * + * CORDET Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CORDET Framework is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CORDET Framework. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef CRFW_UTILITY_FUNCTIONS_H_ +#define CRFW_UTILITY_FUNCTIONS_H_ + +/* Include FW Profile Files */ +#include "FwSmConstants.h" +#include "FwPrConstants.h" +/* Include Framework Files */ +#include "CrFwConstants.h" +/* Include Configuration Files */ +#include "CrFwUserConstants.h" + +/** + * Return the value of the application error code. + * The application error code is set by a framework function when when either + * of the following situations arises: + * - a framework function has been called by the application code with an illegal + * parameter values or in an illegal context and execution of the function with the illegal + * values would cause an internal framework data structure to be corrupted. + * - a framework function which releases dynamically allocated framework components has been + * asked to either release a non-allocated component or to release a component which had + * already been released. + * . + * Nominally, the application error code should be equal to: <code>::crNoAppErr</code>. + * If the application error code has a different value, then it is likely that the + * framework is not configured as the user intended. + * @return the application error code + */ +CrFwAppErrCode_t CrFwGetAppErrCode(); + +/** + * Set the value of the application error code (see <code>::CrFwGetAppErrCode</code>). + * @param errCode the application error code + */ +void CrFwSetAppErrCode(CrFwAppErrCode_t errCode); + +/** + * Convenience function to check whether the outcome of the last check or action + * is equal to 1 ("true"). + * This function returns "true" if and only if the outcome field of the component data (see + * <code>::CrFwCmpData</code>) is equal to 1. + * This function is intended to be used as a guard in a procedure. + * @param prDesc the procedure descriptor + * @return return 1 if the outcome is 1 and return 0 otherwise + */ +FwPrBool_t CrFwIsPrOutcomeOne(FwPrDesc_t prDesc); + +/** + * Convenience function to check whether the outcome of the last check or action + * is equal to 0 ("false"). + * This function returns "true" if and only if the outcome field of the component data (see + * <code>::CrFwCmpData</code>) is equal to 0. + * This function is intended to be used as a guard in a state machine. + * @param smDesc the state machine descriptor + * @return return 1 if the outcome is 0 and return 0 otherwise + */ +FwSmBool_t CrFwIsSmOutcomeZero(FwSmDesc_t smDesc); + +/** + * Convenience function to check whether the outcome of the last check or action + * is equal to 1 ("true"). + * This function returns "true" if and only if the outcome field of the component data (see + * <code>::CrFwCmpData</code>) is equal to 1. + * This function is intended to be used as a guard in a state machine. + * @param smDesc the state machine descriptor + * @return return 1 if the outcome is 1 and return 0 otherwise + */ +FwSmBool_t CrFwIsSmOutcomeOne(FwSmDesc_t smDesc); + +/** + * Convenience function to check whether the outcome of the last check or action + * is equal to 2. + * This function returns "true" if and only if the outcome field of the component data (see + * <code>::CrFwCmpData</code>) is equal to 2. + * This function is intended to be used as a guard in a state machine. + * @param smDesc the state machine descriptor + * @return return 1 if the outcome is 2 and return 0 otherwise + */ +FwSmBool_t CrFwIsSmOutcomeTwo(FwSmDesc_t smDesc); + +/** + * Convenience function which returns true when a procedure has spent more than one cycle + * in the current action node. + * This function can be used as a guard in a procedure where there is a need to express + * the fact that the procedure should remain only one cycle in a node: the guard is false + * after the action node has been executed the first time and becomes true after it has been + * executed the second time. + * @param prDesc the procedure descriptor + * @return return 1 if the action of the current node has been executed two or more times; + * return 0 otherwise. + */ +FwPrBool_t CrFwWaitOnePrCycle(FwPrDesc_t prDesc); + +/** + * Convenience function to be used in a procedure as default implementation for a check + * which always returns true. + * @param prDesc the procedure descriptor + * @return always returns true + */ +CrFwBool_t CrFwPrCheckAlwaysTrue(FwPrDesc_t prDesc); + +/** + * Convenience function to be used in a state machine as default implementation for a check + * which always returns true. + * @param smDesc the state machine descriptor + * @return always returns true + */ +CrFwBool_t CrFwSmCheckAlwaysTrue(FwSmDesc_t smDesc); + +/** + * Convenience function to be used in a state machine as default implementation for a check + * which always returns false. + * @param smDesc the state machine descriptor + * @return always returns false + */ +CrFwBool_t CrFwSmCheckAlwaysFalse(FwSmDesc_t smDesc); + +/** + * Convenience function to be used in a procedure as default implementation for an action + * which returns without doing anything. + * @param prDesc the procedure descriptor + */ +void CrFwPrEmptyAction(FwPrDesc_t prDesc); + +/** + * Convenience function to be used in a state machine as default implementation for an action + * which returns without doing anything. + * @param smDesc the state machine descriptor + */ +void CrFwSmEmptyAction(FwSmDesc_t smDesc); + +/** + * Convenience function to retrieve the index of an array where a certain target value is + * located. + * This function is used by the InFactory (see <code>CrFwInFactory.h</code>) and OutFactory + * (see <code>CrFwOutFactory.h</code>). + * The InFactory and OutFactory maintain arrays which store sets of command and report kinds + * in increasing order. + * A command or report kind is encoded through a key. + * This function finds the index corresponding to a given target key value. + * @param cmdRepKindArray array of key values (the key values must be stored in increasing order) + * @param length length of the array of key values + * @param targetKey the key value that is searched + * @return the index in the array where the target key value is located or the length of the + * array if the target key value is not in the array + */ +CrFwCmdRepKindIndex_t CrFwFindCmdRepKindIndex(CrFwCmdRepKindKey_t* cmdRepKindArray, + CrFwCmdRepKindIndex_t length, CrFwCmdRepKindKey_t targetKey); + +#endif /* CRFW_BASE_CMP_H_ */ diff --git a/CrIa/Makefile b/CrIa/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0c4d3532ec16d10b9fd314b38c5b8363a593eb7c --- /dev/null +++ b/CrIa/Makefile @@ -0,0 +1,150 @@ +.PHONY: all +all: ifsw-dpu ifsw-pc + @echo "finished building all targets" + +ifsw-dpu: + @echo "+--------------------------+" + @echo "| building CrIa DPU target |" + @echo "+--------------------------+" + make -f ./Makefile-dpu.mk + @echo "+-----------------------+" + @echo "| built CrIa DPU target |" + @echo "+-----------------------+" + @echo + +perf-dpu: + @echo "+----------------------------------------------------+" + @echo "| building CrIa DPU target with performance wrappers |" + @echo "+----------------------------------------------------+" + make -f ./Makefile-dpu.mk perf + @echo "+-------------------------------------------------+" + @echo "| built CrIa DPU target with performance wrappers |" + @echo "+-------------------------------------------------+" + @echo + +ifsw-eval: + @echo "+---------------------------+" + @echo "| building CrIa LEON target |" + @echo "+---------------------------+" + make -f ./Makefile-eval.mk + @echo "+------------------------+" + @echo "| built CrIa LEON target |" + @echo "+------------------------+" + @echo + +ifsw-pc: + @echo "+-------------------------+" + @echo "| building CrIa PC target |" + @echo "+-------------------------+" + make -f ./Makefile-pc.mk ifsw + @echo "+----------------------+" + @echo "| built CrIa PC target |" + @echo "+----------------------+" + @echo + +scan: + @echo "+-----------------------+" + @echo "| running static checks |" + @echo "+-----------------------+" + @echo + + @echo "1. CLANG" + scan-build -V make -f ./Makefile-pc.mk ifsw + + @echo "+--------------------------------+" + @echo "| finished running static checks |" + @echo "+--------------------------------+" + @echo + +checks: + @echo "+--------------------+" + @echo "| running TCL checks |" + @echo "+--------------------+" + @echo + + @echo "1. scan for LEON3 cache bug" + -sparc-elf-objdump -d build/dpu/ifsw-dpu | /home/space/BCC-1.0.50/TN/leon3ft-b2bst-scan.tcl + + @echo "2. scan for TN-0010 bug" + -sparc-elf-objdump -d build/dpu/ifsw-dpu | /home/space/BCC-1.0.50/TN/tn-0010.tcl + + @echo "3. scan for TN-0011 bug" + -sparc-elf-objdump -d build/dpu/ifsw-dpu | /home/space/BCC-1.0.50/TN/tn-0011.tcl + -sparc-elf-objdump -d build/dpu/ifsw-dpu | /home/space/BCC-1.0.50/TN/tn-0011-obj.tcl + + @echo "4. scan for TN-0012 bug" + -sparc-elf-objdump -d build/dpu/ifsw-dpu | /home/space/BCC-1.0.50/TN/tn-0012.tcl + + @echo "5. scan for TN-0013 bug" + -sparc-elf-objdump -d build/dpu/ifsw-dpu | /home/space/BCC-1.0.50/TN/tn-0013.tcl + + @echo "+-----------------------------+" + @echo "| finished running TCL checks |" + @echo "+-----------------------------+" + @echo + +printf: + @echo "+----------------------------------+" + @echo "| checking for printf in flight SW |" + @echo "+----------------------------------+" + @echo + @grep -R printf src | grep -v sprintf | grep -v src/CrIaMain.c | grep -v src/IfswDebug | grep -v '.txt' | cut -d ":" -f 1,1 | sort | uniq -c + @grep -R printf ../IBSW/lib | grep -v sprintf | cut -d ":" -f 1,1 | sort | uniq -c + @grep -R printf ../IBSW/include | grep -v sprintf | cut -d ":" -f 1,1 | sort | uniq -c + @echo + @echo "+--------------------------------+" + @echo "| now go and check these printfs |" + @echo "+--------------------------------+" + @echo + +todos: + @echo "+------------------------------------------+" + @echo "| checking for TODO and FIXME in flight SW |" + @echo "+------------------------------------------+" + @echo + @echo "TODOs:" + @grep -Ri 'TODO' src | grep -v src/CrIaMain.c | grep -v src/IfswDebug | grep -v '.txt' | cut -d ":" -f 1,1 | sort | uniq -c + @grep -Ri 'TODO' ../IBSW/lib | cut -d ":" -f 1,1 | sort | uniq -c + @grep -Ri 'TODO' ../IBSW/include | cut -d ":" -f 1,1 | sort | uniq -c + @echo + @echo "FIXMEs:" + @grep -Ri 'FIXME' src | grep -v src/CrIaMain.c | grep -v src/IfswDebug | grep -v '.txt' | cut -d ":" -f 1,1 | sort | uniq -c + @grep -Ri 'FIXME' ../IBSW/lib | cut -d ":" -f 1,1 | sort | uniq -c + @grep -Ri 'FIXME' ../IBSW/include | cut -d ":" -f 1,1 | sort | uniq -c + @echo "+--------------------------------+" + @echo "| now go and check these TODOs |" + @echo "+--------------------------------+" + @echo + +checkidb: + @echo "+-----------------------------+" + @echo "| checking for orphans in IDB |" + @echo "+-----------------------------+" + @echo + ./checkidb.sh + @echo + @echo "+----------------------------+" + @echo "| IDB orphan check completed |" + @echo "+----------------------------+" + @echo + +showdef: + @echo "+-----------------------------+" + @echo "| checking for #if constructs |" + @echo "+-----------------------------+" + @echo + grep -R '#if' src ifsw.* ../IBSW/ | grep -v 'PC_TARGET' | grep -v 'sparc' | grep -v SPW_ROUTING | grep -v IBSW/test | grep -v IBSW/unused | grep -v '_H$$' | grep -v "IBSW/exports" | grep -v "IBSW/reports" | grep -v 'IBSW/example' | grep -v '_H_$$' + @echo + @echo "+-------------------------------+" + @echo "| these were all #if constructs |" + @echo "+-------------------------------+" + @echo + + + +.PHONY: clean +.IGNORE: clean +clean: + make -f ./Makefile-dpu.mk clean + make -f ./Makefile-eval.mk clean + make -f ./Makefile-pc.mk clean diff --git a/CrIa/Makefile-dpu.mk b/CrIa/Makefile-dpu.mk new file mode 100644 index 0000000000000000000000000000000000000000..6f4b1051a812936f7b7d9ead37d6e204f02fea0d --- /dev/null +++ b/CrIa/Makefile-dpu.mk @@ -0,0 +1,147 @@ +.PHONY: all +CC = sparc-elf-gcc +BUILDDIR = $(shell realpath build/dpu) +INCLUDEDIR = $(shell realpath ../IBSW/include) +IBSW_DIR = $(shell realpath ../IBSW/lib) +IASW_DIR = $(shell realpath src) +CORDET_DIR = $(shell realpath ../CrFramework/src) +CPPFLAGS := -D__SPW_ROUTING__ + +# -DLIBERATE_XIB disables the XIB checks for their incrementation + +GIT_ID := $(shell git log -n 1 --format="%h" | sed -e "s/\(....\).*/\1/") +IFSW_VERSION := "6E" +CE_VERSION := "0B" +BUILD_ID := "0x"$(GIT_ID)$(IFSW_VERSION)$(CE_VERSION) + +# +# In BCC 4.4.2 1.0.50 -mfix-gr712rc replaces -mfix-b2bst +# +CFLAGS := -mv8 -mhard-float -mfix-gr712rc -O2 -std=gnu89 -W -Wall -Wextra -Werror -pedantic -Wshadow -Wuninitialized -fdiagnostics-show-option -Wcast-qual -Wformat=2 +INCLUDES := -I$(INCLUDEDIR) -I$(INCLUDEDIR)/leon \ + -I$(shell realpath src) \ + -I$(shell realpath src/Sdp) \ + -I$(shell realpath src/Ta) \ + -I$(shell realpath src/CrConfigIa) \ + -I$(shell realpath src/Services/General) \ + -I$(shell realpath ../include/CrFramework) \ + -I$(shell realpath ../include/FwProfile) \ + -I$(shell realpath ../include) \ + -I$(shell realpath ../CrFramework/src) + +# 512 kiB for .text, 128 kiB for initialised values, rest for .bss +LDFLAGS := -Ttext=0x40480000 -Tdata=0x40500000 -Tbss=0x40520000 -Xlinker --defsym -Xlinker __BUILD_ID=$(BUILD_ID) -Xlinker -Map=dpu.map +SOURCES := $(IASW_DIR)/../ifsw.c \ + $(IBSW_DIR)/core1553brm_as250.c\ + $(IBSW_DIR)/circular_buffer16.c\ + $(IBSW_DIR)/circular_buffer8.c \ + $(IBSW_DIR)/irq_dispatch.c \ + $(IBSW_DIR)/grspw2.c \ + $(IBSW_DIR)/cpus_buffer.c \ + $(IBSW_DIR)/packet_tracker.c \ + $(IBSW_DIR)/timing/leon3_gptimer.c \ + $(IBSW_DIR)/timing/leon3_grtimer.c \ + $(IBSW_DIR)/timing/leon3_grtimer_longcount.c \ + $(IBSW_DIR)/timing/timing.c \ + $(IBSW_DIR)/timing/watchdog.c \ + $(IBSW_DIR)/timing/syncpulse.c \ + $(IBSW_DIR)/error_log.c \ + $(IBSW_DIR)/ibsw_init/init_cpus.c \ + $(IBSW_DIR)/ibsw_init/init_ptrack.c \ + $(IBSW_DIR)/ibsw_init/init_spw.c \ + $(IBSW_DIR)/ibsw_init/init_1553.c \ + $(IBSW_DIR)/ibsw_init/init_sync_timing.c \ + $(IBSW_DIR)/ibsw_init/init_error_log.c \ + $(IBSW_DIR)/ibsw_init/init_edac.c \ + $(IBSW_DIR)/ibsw_init/init_cpu_0_idle_timing.c \ + $(IBSW_DIR)/ibsw_init/ibsw_mainloop.c \ + $(IBSW_DIR)/ibsw_init/ibsw_init.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_interface.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_spw.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_datapool_update.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_watchdog.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_1553.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_utility.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_memscrub.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_fbf.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_time.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_execute_op.c \ + $(IBSW_DIR)/ibsw_interface/ibsw_error_log.c \ + $(IBSW_DIR)/event_report.c \ + $(IBSW_DIR)/iwf_fpga.c \ + $(IBSW_DIR)/iwf_flash.c \ + $(IBSW_DIR)/sysctl.c \ + $(IBSW_DIR)/wrap_malloc.c \ + $(IBSW_DIR)/leon3_dsu.c \ + $(IBSW_DIR)/traps.c \ + $(IBSW_DIR)/fpe.c \ + $(IBSW_DIR)/reset.c \ + $(IBSW_DIR)/ahb.c \ + $(IBSW_DIR)/edac.c \ + $(IBSW_DIR)/memscrub.c \ + $(IBSW_DIR)/memcfg.c \ + $(IBSW_DIR)/stacktrace.c \ + $(shell find $(CORDET_DIR) -type f -name *.\[c\] | sed /AppStartUp/d) \ + $(shell find -L $(IASW_DIR) -type f -name *.\[c\]| sed /CrIaMain/d | sed /AppStartUp/d | sed -e "/Performance\/performance.c/d" ) + +ASMSOURCES := $(IBSW_DIR)/asm/data_access_exception_trap.S \ + $(IBSW_DIR)/asm/floating_point_exception_trap.S \ + $(IBSW_DIR)/asm/reset_trap.S + +ALLSOURCES := $(SOURCES) $(ASMSOURCES) + +OBJECTS := $(patsubst %.c, $(BUILDDIR)/%.o, $(subst $(SOURCEDIR)/,, $(ALLSOURCES))) +TARGET := $(BUILDDIR)/ifsw-dpu + +DEBUG?=1 +ifeq "$(shell expr $(DEBUG) \> 1)" "1" + CFLAGS += -DDEBUGLEVEL=$(DEBUG) +else + CFLAGS += -DDEBUGLEVEL=1 +endif + + +#all: builddir $(OBJECTS) $(BUILDDIR)/$(TARGET) +# $(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ +# +#builddir: +# mkdir -p $(BUILDDIR) +# +#clean: +# rm -f $(BUILDDIR)/{$(TARGET), $(OBJECTS)} +# rm -rf $(BUILDDIR) +# +# +#$(BUILDDIR)/$(TARGET): $(OBJECTS) +# $(CC) $^ -o $@ +# +#$(OBJECTS): $(SOURCES) +# $(CC) $(CPPFLAGS) $(CFLAGS) -c $^ -o $@ + +all: $(ALLSOURCES) + echo "BUILD number is:" $(BUILD_ID) + mkdir -p $(BUILDDIR) + $(CC) $(CPPFLAGS) $(INCLUDES) $(LDFLAGS) $(CFLAGS) $^ -o $(TARGET) ../FwProfile/build/dpu/libfwprofile.a -Wl,--wrap=malloc -Wl,--wrap=free + sparc-elf-objcopy -O srec build/dpu/ifsw-dpu build/dpu/ifsw.srec + +.ONESHELL: +perf: $(SOURCES) $(shell realpath src/Performance/performance.c) + echo "BUILD number is:" $(BUILD_ID) + mkdir -p $(BUILDDIR) + # generate wrappers + $(eval WRAPS=$(shell bash -c 'source src/Performance/generate_wrappers.sh > /dev/null && echo $${WRAPPERS}')) + cd $(BUILDDIR) + # compile to .s files + $(CC) $(CPPFLAGS) $(INCLUDES) $(LDFLAGS) $(CFLAGS) -S $^ + # patch wrappers in + $(IASW_DIR)/Performance/patch_asms.sh + # compile .s files to executable + $(CC) $(CPPFLAGS) $(INCLUDES) $(LDFLAGS) $(CFLAGS) -o ifsw-dpu *.s $(ASMSOURCES) ../../../FwProfile/build/dpu/libfwprofile.a -Wl,--wrap=malloc -Wl,--wrap=free + cd .. + sparc-elf-objcopy -O srec $(BUILDDIR)/ifsw-dpu $(BUILDDIR)/ifsw.srec + cat $(BUILDDIR)/dpu.map | grep perf | awk '($$2=="perf"){printf "\nNote: The perf structure starts at %s\n\n", $$1}' + + + +# $(CC) $(CPPFLAGS) $(INCLUDES) $(LDFLAGS) $(CFLAGS) $^ -o $(TARGET) ../../FwProfile/build/dpu/libfwprofile.a -Wl,--wrap=malloc -Wl,--wrap=free $(shell bash -c 'source src/Performance/generate_wrappers.sh > /dev/null && echo $${WRAPPERS}' ) + diff --git a/CrIa/Makefile-eval.mk b/CrIa/Makefile-eval.mk new file mode 100644 index 0000000000000000000000000000000000000000..36936927b6e78f8254edeef36ae5ccdc06427fe6 --- /dev/null +++ b/CrIa/Makefile-eval.mk @@ -0,0 +1,68 @@ +CC = sparc-elf-gcc +BUILDDIR = $(shell realpath build/eval) +INCLUDEDIR = $(shell realpath ../IBSW/include) +IBSW_DIR = $(shell realpath ../IBSW/lib) +IASW_DIR = $(shell realpath src) +CORDET_DIR = $(shell realpath ../CrFramework/src) +CPPFLAGS := -D__SPW_ROUTING__ +CFLAGS := -mv8 -O2 -std=gnu89 -ggdb -W -Wall -Wextra -Werror -pedantic +INCLUDES := -I$(INCLUDEDIR) -I$(INCLUDEDIR)/leon \ + -Isrc \ + -Isrc/CrConfigIa\ + -Isrc/Services/General\ + -I../include/CrFramework\ + -I../include/FwProfile\ + -I../include \ + -I../CrFramework/src \ + -I../include/CordetFW/CrFramework/OutCmp + +LDFLAGS := -Ttext=0x40480000 +SOURCES := ifsw.c \ + $(IBSW_DIR)/core1553brm_as250.c\ + $(IBSW_DIR)/circular_buffer16.c\ + $(IBSW_DIR)/circular_buffer8.c \ + $(IBSW_DIR)/irq_dispatch.c \ + $(IBSW_DIR)/grspw2.c \ + $(IBSW_DIR)/cpus_buffer.c \ + $(IBSW_DIR)/packet_tracker.c \ + $(IBSW_DIR)/timing.c \ + $(IBSW_DIR)/error_log.c \ + $(IBSW_DIR)/xen_printf.c \ + $(IBSW_DIR)/IbswInterface.c \ + $(IBSW_DIR)/ibsw.c \ + $(IBSW_DIR)/sysctl.c \ + $(IBSW_DIR)/wrap_malloc.c \ + $(shell find $(CORDET_DIR) -type f -name *.\[c\] | sed /AppStartUp/d) \ + $(shell find $(IASW_DIR) -type f -name *.\[c\]| sed /CrIaMain/d | sed /AppStartUp/d) + +OBJECTS := $(patsubst %.c, $(BUILDDIR)/%.o, $(subst $(SOURCEDIR)/,, $(SOURCES))) +TARGET := $(BUILDDIR)/ifsw-eval + +DEBUG?=1 +ifeq "$(shell expr $(DEBUG) \> 1)" "1" + CFLAGS += -DDEBUGLEVEL=$(DEBUG) +else + CFLAGS += -DDEBUGLEVEL=1 +endif + + +#all: builddir $(OBJECTS) $(BUILDDIR)/$(TARGET) +# $(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ +# +#builddir: +# mkdir -p $(BUILDDIR) +# +#clean: +# rm -f $(BUILDDIR)/{$(TARGET), $(OBJECTS)} +# rm -rf $(BUILDDIR) +# +# +#$(BUILDDIR)/$(TARGET): $(OBJECTS) +# $(CC) $^ -o $@ +# +#$(OBJECTS): $(SOURCES) +# $(CC) $(CPPFLAGS) $(CFLAGS) -c $^ -o $@ + +all: $(SOURCES) + mkdir -p $(BUILDDIR) + $(CC) $(CPPFLAGS) $(INCLUDES) $(LDFLAGS) $(CFLAGS) $^ -o $(TARGET) ../FwProfile/build/dpu/libfwprofile.a -lpthread -Wl,--wrap=malloc -Wl,--wrap=free diff --git a/CrIa/Makefile-pc.mk b/CrIa/Makefile-pc.mk new file mode 100644 index 0000000000000000000000000000000000000000..5edeb983cde5c2d427bb5965585dd7f16e2b603c --- /dev/null +++ b/CrIa/Makefile-pc.mk @@ -0,0 +1,70 @@ +CC = gcc +CFLAGS = -O2 -W -Wall -Wextra -Wno-variadic-macros -Werror -std=gnu89 -m32 -pedantic -ggdb +IFSW_VERSION := "6E" +CE_VERSION := "0B" +BUILD_ID := "0x"$(IFSW_VERSION)$(CE_VERSION) +DEFS = -DPC_TARGET -DBUILD_ID=$(BUILD_ID) +LD = gcc +LDFLAGS = -m32 + +# use pc or dpu +TARGET = pc + +ROOTDIR = $(shell pwd) +SOURCEDIR = $(ROOTDIR)/src + + +# generic user include directory +INC_DIR = $(shell realpath ../include) + +# FwProfile include and library path +FWP_DIR = $(shell realpath ../FwProfile) +FWP_INC = $(FWP_DIR)/src +FWP_LIB = $(FWP_DIR)/build + +# CrFramework sources and include path +CRFW_DIR = $(shell realpath ../CrFramework) +CRFW_SRC = $(shell find $(CRFW_DIR)/src | grep -e "\.c" | sort | sed /AppStartUp/d) # all c files but the AppStartUp +CRFW_INC = $(CRFW_DIR)/src + +# CrIaConfig includes +CRIA_DIR = $(shell realpath .) +CRIA_CONF_INC = $(CRIA_DIR)/src/CrConfigIa +CRIA_INC = $(CRIA_DIR)/src +SDP_INC = $(CRIA_DIR)/src/Sdp +TA_INC = $(CRIA_DIR)/src/Ta + +# CrIa Sources +CRIA_SRC = $(shell find $(CRIA_DIR)/src -name *.\[c\] | sed -e "/Performance\/performance.c/d" -e "/IfswMath.c/d") + +INCLUDES = -I$(FWP_INC) -I$(CRFW_INC) -I$(CRIA_INC) -I$(CRIA_CONF_INC) -I$(INC_DIR) -I$(SDP_INC) -I$(TA_INC) +#LIBS = -L$(FWP_LIB)/$(TARGET) -lfwprofile +LIBS = +LOPTIONS = -lpthread +FWPLIB = $(FWP_LIB)/$(TARGET)/libfwprofile.a + +BUILDDIR = $(ROOTDIR)/build/$(TARGET) + +#SOURCES = $(shell ls $(SOURCEDIR)/*.c) +#OBJECTS = $(patsubst %.c,$(BUILDDIR)/%.o,$(notdir $(SOURCES))) + + +ifsw: $(CRIA_SRC) $(CRFW_SRC) + @echo "Building" $(TARGET) "target." + @mkdir -p $(BUILDDIR) + # compile + @echo "******** Compiling object files ********" + cd $(BUILDDIR) && $(CC) $(CFLAGS) $(INCLUDES) $(DEFS) -c $(CRIA_SRC) $(CRFW_SRC) + # link + @echo "******** Linking components ********" + cd $(BUILDDIR) && $(LD) $(LDFLAGS) $(LIBS) -o CrIa *.o $(FWPLIB) $(LOPTIONS) -lm + @echo "CrIa is ready!" + +.PHONY: all +all: ifsw + @echo "Finished building" $(TARGET) "target." + +.PHONY: clean +clean: + rm -f $(BUILDDIR)/*.[ao] $(BUILDDIR)/CrIa + diff --git a/CrIa/doc/Doxyfile b/CrIa/doc/Doxyfile new file mode 100644 index 0000000000000000000000000000000000000000..2bd62ea852163c5a47661a9cc562846a98c9a9fc --- /dev/null +++ b/CrIa/doc/Doxyfile @@ -0,0 +1,2482 @@ +# Doxyfile 1.8.14 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "CHEOPS IASW" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 1.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "CHEOPS Instrument Application Software" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = "images/cheops-logo-with-additional3.png" + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = ../ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = ../ + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = YES + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = YES + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = "/bin/sh -c 'git log --pretty=\"format:%ci, author:%aN <%aE>, commit:%h\" -1 \"${1}\" || echo no git'" + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = YES + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../src ./extradoc ../ifsw.h ../ifsw.c + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = ../example + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = images + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = customdoxygen.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when enabling USE_PDFLATEX this option is only used for generating +# bitmaps for formulas in the HTML output, but not in the Makefile that is +# written to the output directory. +# The default file is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's config +# file, i.e. a series of assignments. You only have to provide replacements, +# missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's config file. A template extensions file can be generated +# using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO, the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = ../include + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = __attribute__(x)=1 __SPW_ROUTING__=1 __sparc__=1 + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = YES + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = svg + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = YES + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = /opt/plantuml + +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/CrIa/doc/DoxygenLayout.xml b/CrIa/doc/DoxygenLayout.xml new file mode 100644 index 0000000000000000000000000000000000000000..7479687ef34ccb9d265a30c64f63b44943fceee6 --- /dev/null +++ b/CrIa/doc/DoxygenLayout.xml @@ -0,0 +1,194 @@ +<doxygenlayout version="1.0"> + <!-- Generated by doxygen 1.8.11 --> + <!-- Navigation index tabs for HTML output --> + <navindex> + <tab type="mainpage" visible="yes" title=""/> + <tab type="pages" visible="yes" title="" intro=""/> + <tab type="modules" visible="yes" title="" intro=""/> + <tab type="namespaces" visible="yes" title=""> + <tab type="namespacelist" visible="yes" title="" intro=""/> + <tab type="namespacemembers" visible="yes" title="" intro=""/> + </tab> + <tab type="classes" visible="yes" title=""> + <tab type="classlist" visible="yes" title="" intro=""/> + <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> + <tab type="hierarchy" visible="yes" title="" intro=""/> + <tab type="classmembers" visible="yes" title="" intro=""/> + </tab> + <tab type="files" visible="yes" title=""> + <tab type="filelist" visible="yes" title="" intro=""/> + <tab type="globals" visible="yes" title="" intro=""/> + </tab> + <tab type="examples" visible="yes" title="" intro=""/> + </navindex> + + <!-- Layout definition for a class page --> + <class> + <briefdescription visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <inheritancegraph visible="$CLASS_GRAPH"/> + <collaborationgraph visible="$COLLABORATION_GRAPH"/> + <detaileddescription title=""/> + <memberdecl> + <nestedclasses visible="yes" title=""/> + <publictypes title=""/> + <services title=""/> + <interfaces title=""/> + <publicslots title=""/> + <signals title=""/> + <publicmethods title=""/> + <publicstaticmethods title=""/> + <publicattributes title=""/> + <publicstaticattributes title=""/> + <protectedtypes title=""/> + <protectedslots title=""/> + <protectedmethods title=""/> + <protectedstaticmethods title=""/> + <protectedattributes title=""/> + <protectedstaticattributes title=""/> + <packagetypes title=""/> + <packagemethods title=""/> + <packagestaticmethods title=""/> + <packageattributes title=""/> + <packagestaticattributes title=""/> + <properties title=""/> + <events title=""/> + <privatetypes title=""/> + <privateslots title=""/> + <privatemethods title=""/> + <privatestaticmethods title=""/> + <privateattributes title=""/> + <privatestaticattributes title=""/> + <friends title=""/> + <related title="" subtitle=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <services title=""/> + <interfaces title=""/> + <constructors title=""/> + <functions title=""/> + <related title=""/> + <variables title=""/> + <properties title=""/> + <events title=""/> + </memberdef> + <allmemberslink visible="yes"/> + <usedfiles visible="$SHOW_USED_FILES"/> + <authorsection visible="yes"/> + </class> + + <!-- Layout definition for a namespace page --> + <namespace> + <briefdescription visible="yes"/> + <detaileddescription title=""/> + <memberdecl> + <nestednamespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <classes visible="yes" title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection visible="yes"/> + </namespace> + + <!-- Layout definition for a file page --> + <file> + <briefdescription visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <includegraph visible="$INCLUDE_GRAPH"/> + <includedbygraph visible="$INCLUDED_BY_GRAPH"/> + <sourcelink visible="yes"/> + <detaileddescription title=""/> + <memberdecl> + <classes visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection/> + </file> + + <!-- Layout definition for a group page --> + <group> + <briefdescription visible="yes"/> + <groupgraph visible="$GROUP_GRAPHS"/> + <detaileddescription title=""/> + <memberdecl> + <nestedgroups visible="yes" title=""/> + <dirs visible="yes" title=""/> + <files visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <classes visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <pagedocs/> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + </memberdef> + <authorsection visible="yes"/> + </group> + + <!-- Layout definition for a directory page --> + <directory> + <briefdescription visible="yes"/> + <directorygraph visible="yes"/> + <memberdecl> + <dirs visible="yes"/> + <files visible="yes"/> + </memberdecl> + <detaileddescription title=""/> + </directory> +</doxygenlayout> diff --git a/CrIa/doc/Makefile b/CrIa/doc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..533632bab1e780f0839d5c17dc46494eb128c7cd --- /dev/null +++ b/CrIa/doc/Makefile @@ -0,0 +1,16 @@ +CSSFILES = $(shell ls *.css) +JSFILES = $(shell ls *.js) +HTFILES = header.html footer.html + +.PHONY: all + +all: + @which plantuml + @test -d html || mkdir html + doxygen + cp $(CSSFILES) $(JSFILES) $(HTFILES) html/ + +.PHONY: clean +clean: + rm -rf html + diff --git a/CrIa/doc/bootstrap.min.css b/CrIa/doc/bootstrap.min.css new file mode 100644 index 0000000000000000000000000000000000000000..4cf729e4342a51d8b300e8d43f2f78b0a6faf403 --- /dev/null +++ b/CrIa/doc/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/CrIa/doc/bootstrap.min.js b/CrIa/doc/bootstrap.min.js new file mode 100644 index 0000000000000000000000000000000000000000..e79c065134f2cfcf3e44a59cffcb5f090232f98f --- /dev/null +++ b/CrIa/doc/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active"); +d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/CrIa/doc/customdoxygen.css b/CrIa/doc/customdoxygen.css new file mode 100644 index 0000000000000000000000000000000000000000..6a32ca7cc14ef237589954afbe62418891459d9e --- /dev/null +++ b/CrIa/doc/customdoxygen.css @@ -0,0 +1,306 @@ +/* +h1, .h1, h2, .h2, h3, .h3{ + font-weight: 200 !important; +} +*/ + +h1,.h1 { + font-size: 24px; +} + +h2,.h2 { + font-size: 20px; +} + +h3,.h3 { + font-size: 16px; +} + +h4,.h4 { + font-size: 14px; +} + +h5,.h5 { + font-size: 12px; +} + +h6,.h6 { + font-size: 10px; +} + + + +#navrow1, #navrow2, #navrow3, #navrow4, #navrow5{ + border-bottom: 1px solid #706d6e; +} + +.adjust-right { +margin-left: 30px !important; +font-size: 1.15em !important; +} +.navbar{ + border: 0px solid #222 !important; +} + + +/* Sticky footer styles +-------------------------------------------------- */ +html, +body { + height: 100%; + /* The html and body elements cannot have any padding or margin. */ +} + +img { +max-width:100%; +max-height:100%; +} + +/* Wrapper for page content to push down footer */ +#wrap { + min-height: 100%; + height: auto; + /* Negative indent footer by its height */ + margin: 0 auto -60px; + /* Pad bottom by footer height */ + padding: 0 0 60px; +} + +/* Set the fixed height of the footer here */ +#footer { + font-size: 0.9em; + padding: 8px 0px; + background-color: #f5f5f5; +} + +.footer-row { + line-height: 44px; +} + +#footer > .container { + padding-left: 15px; + padding-right: 15px; +} + +.footer-follow-icon { + margin-left: 3px; + text-decoration: none !important; +} + +.footer-follow-icon img { + width: 20px; +} + +.footer-link { + padding-top: 5px; + display: inline-block; + color: #999999; + text-decoration: none; +} + +.footer-copyright { + text-align: center; +} + + +@media (min-width: 992px) { + .footer-row { + text-align: left; + } + + .footer-icons { + text-align: right; + } +} +@media (max-width: 991px) { + .footer-row { + text-align: center; + } + + .footer-icons { + text-align: center; + } +} + +/* DOXYGEN Code Styles +----------------------------------- */ + + +div.ingroups { + font-size: 16pt; + width: 50%; + text-align: left; + padding-top: 10px; +} + +a.qindex { + font-size: 8pt; +} + +a.qindexHL { + font-size: 9pt; + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 8pt; + line-height: 125%; + font-family: monospace, fixed; +} + +div.navtab { + text-align: left; + padding-left: 5px; + margin-right: 5px; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +.caption { + font-weight: bold; + padding-top: 10px; + padding-bottom: 20px; +} +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + diff --git a/CrIa/doc/doxy-boot.js b/CrIa/doc/doxy-boot.js new file mode 100644 index 0000000000000000000000000000000000000000..7bcfc1d1015f8296e4aee9d09bb9e906369da408 --- /dev/null +++ b/CrIa/doc/doxy-boot.js @@ -0,0 +1,121 @@ +$( document ).ready(function() { + + $("div.headertitle").addClass("page-header"); + $("div.title").addClass("h1"); + + $('li > a[href="index.html"] > span').before("<i class='fa fa-cog'></i> "); + $('li > a[href="index.html"] > span').text("CHEOPS IASW"); + $('li > a[href="modules.html"] > span').before("<i class='fa fa-square'></i> "); + $('li > a[href="namespaces.html"] > span').before("<i class='fa fa-bars'></i> "); + $('li > a[href="annotated.html"] > span').before("<i class='fa fa-list-ul'></i> "); + $('li > a[href="classes.html"] > span').before("<i class='fa fa-book'></i> "); + $('li > a[href="inherits.html"] > span').before("<i class='fa fa-sitemap'></i> "); + $('li > a[href="functions.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_func.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_vars.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_enum.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_eval.html"] > span').before("<i class='fa fa-list'></i> "); + $('img[src="ftv2ns.png"]').replaceWith('<span class="label label-danger">N</span> '); + $('img[src="ftv2cl.png"]').replaceWith('<span class="label label-danger">C</span> '); + + $("ul.tablist").addClass("nav nav-pills nav-justified"); + $("ul.tablist").css("margin-top", "0.5em"); + $("ul.tablist").css("margin-bottom", "0.5em"); + $("li.current").addClass("active"); + $("iframe").attr("scrolling", "yes"); + + $("#nav-path > ul").addClass("breadcrumb"); + + $("table.params").addClass("table"); + $("div.ingroups").wrapInner("<small></small>"); + $("div.levels").css("margin", "0.5em"); + $("div.levels > span").addClass("btn btn-default btn-xs"); + $("div.levels > span").css("margin-right", "0.25em"); + + $("table.directory").addClass("table table-striped"); + $("div.summary > a").addClass("btn btn-default btn-xs"); + $("table.fieldtable").addClass("table"); + $(".fragment").addClass("well"); + $(".memitem").addClass("panel panel-default"); + $(".memproto").addClass("panel-heading"); + $(".memdoc").addClass("panel-body"); + $("span.mlabel").addClass("label label-info"); + + $("table.memberdecls").addClass("table"); + $("[class^=memitem]").addClass("active"); + + $("div.ah").addClass("btn btn-default"); + $("span.mlabels").addClass("pull-right"); + $("table.mlabels").css("width", "100%") + $("td.mlabels-right").addClass("pull-right"); + + $("div.ttc").addClass("panel panel-primary"); + $("div.ttname").addClass("panel-heading"); + $("div.ttname a").css("color", 'white'); + $("div.ttdef,div.ttdoc,div.ttdeci").addClass("panel-body"); + + $('#MSearchBox').parent().remove(); + + $('div.fragment.well div.line:first').css('margin-top', '15px'); + $('div.fragment.well div.line:last').css('margin-bottom', '15px'); + + $('table.doxtable').removeClass('doxtable').addClass('table table-striped table-bordered').each(function(){ + $(this).prepend('<thead></thead>'); + $(this).find('tbody > tr:first').prependTo($(this).find('thead')); + + $(this).find('td > span.success').parent().addClass('success'); + $(this).find('td > span.warning').parent().addClass('warning'); + $(this).find('td > span.danger').parent().addClass('danger'); + }); + + + + if($('div.fragment.well div.ttc').length > 0) + { + $('div.fragment.well div.line:first').parent().removeClass('fragment well'); + } + + $('table.memberdecls').find('.memItemRight').each(function(){ + $(this).contents().appendTo($(this).siblings('.memItemLeft')); + $(this).siblings('.memItemLeft').attr('align', 'left'); + }); + + function getOriginalWidthOfImg(img_element) { + var t = new Image(); + t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src; + return t.width; + } + + $('div.dyncontent').find('img').each(function(){ + if(getOriginalWidthOfImg($(this)[0]) > $('#content>div.container').width()) + $(this).css('width', '100%'); + }); + + $(".memitem").removeClass('memitem'); + $(".memproto").removeClass('memproto'); + $(".memdoc").removeClass('memdoc'); + $("span.mlabel").removeClass('mlabel'); + $("table.memberdecls").removeClass('memberdecls'); + $("[class^=memitem]").removeClass('memitem'); + $("span.mlabels").removeClass('mlabels'); + $("table.mlabels").removeClass('mlabels'); + $("td.mlabels-right").removeClass('mlabels-right'); + $(".navpath").removeClass('navpath'); + $("li.navelem").removeClass('navelem'); + $("a.el").removeClass('el'); + $("div.ah").removeClass('ah'); + $("div.header").removeClass("header"); + + $('.mdescLeft').each(function(){ + if($(this).html()==" ") { + $(this).siblings('.mdescRight').attr('colspan', 2); + $(this).remove(); + } + }); + $('td.memItemLeft').each(function(){ + if($(this).siblings('.memItemRight').html()=="") { + $(this).attr('colspan', 2); + $(this).siblings('.memItemRight').remove(); + } + }); +}); diff --git a/CrIa/doc/extradoc/mainpage.dox b/CrIa/doc/extradoc/mainpage.dox new file mode 100644 index 0000000000000000000000000000000000000000..9b001da375cab7c1764f549381b313f211f5fd51 --- /dev/null +++ b/CrIa/doc/extradoc/mainpage.dox @@ -0,0 +1,66 @@ +/** + +@mainpage + +@section iaswdoc IASW Documentation + +The documentation of the IASW is provided in part externally and in part (especially the detailed design of the science data processing) +through this Doxygen. If this is what you are interested in, <b>go to the <a href="modules.html">Modules</a> section</b>. + +@section sec_sources Source Code + +The source code may be found in the subdirectories _src_ and in the +topmost level of the source tree. The src/Sdp subdirectory contains +the data processing chain, which is linked in from the CompressionEntity, +the stand-alone compression and de-compression application. + +@section sec_files Files + +The files and data structures can be browsed following these links: <a href="files.html">Files</a>, <a href="annotated.html">Data Structures</a>. + +@section sec_executable Compiling the Executable + +@subsection sec_build_prerequisites Prerequisites + +To build and run the executable, you need the following prerequisities: + + - gnu make, gcc toolchain, sparc bcc toolchain (BCC 4.4.2 release 1.0.45) + + - CrFramework and FwProfile, included in the IFSW source tree + +@subsection sec_build Build + +The build process is simple: + + - cd into the CrIa directory and "make". + If it's the first time, it is necessary to cd to FwProfile and "make" this one first. + +This creates an executable for the DPU, a SREC file for upload and it also builds the CrIa executable for the PC. -- Have fun. + +@section iaswcopyright Copyright + +This application has been developed for the ESA mission CHEOPS. It was enabled by funding through the ESA-PRODEX contract C4000112123. + +@subsection iaswlic License +This program is free software; you can redistribute it and/or modify it +under the terms and conditions of the GNU General Public License, +version 2, as published by the Free Software Foundation. + +This program is distributed in the hope it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +@subsection iaswauthors Credits + +\par University of Vienna +Franz Kerschbaum (management), Roland Ottensamer (technical lead), Roman Ferstl, +Philipp Löschl, Armin Luntzer, Christian Reimers + +\par PnP Software GmbH +Alessandro Pasetti, Vaclav Cechticky, Marcel Opprecht + + +Thanks to University of Bern and ESA for all the support. + +*/ diff --git a/CrIa/doc/footer.html b/CrIa/doc/footer.html new file mode 100644 index 0000000000000000000000000000000000000000..f2fa20497a366600145ea79809f6250cf08f2704 --- /dev/null +++ b/CrIa/doc/footer.html @@ -0,0 +1,26 @@ +<!-- HTML footer for doxygen 1.8.8--> +<!-- start footer part --> +<!--BEGIN GENERATE_TREEVIEW--> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + $navpath + <li class="footer">$generatedby + <a href="http://www.doxygen.org/index.html"> + <img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li> + </ul> +</div> +<!--END GENERATE_TREEVIEW--> +</div> +</div> +</div> +</div> +</div> +<!--BEGIN !GENERATE_TREEVIEW--> +<hr class="footer"/><address class="footer"><small> +$generatedby  <a href="http://www.doxygen.org/index.html"> +<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/> +</a> $doxygenversion +</small></address> +<!--END !GENERATE_TREEVIEW--> +</body> +</html> diff --git a/CrIa/doc/header.html b/CrIa/doc/header.html new file mode 100644 index 0000000000000000000000000000000000000000..d4b85eb86c9df8e6cc1f10c931e7e3626d0e4cf1 --- /dev/null +++ b/CrIa/doc/header.html @@ -0,0 +1,47 @@ +<!-- HTML header for doxygen 1.8.8--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <!-- For Mobile Devices --> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> + <meta name="generator" content="Doxygen $doxygenversion"/> + + <script type="text/javascript" src="jquery.js"></script> + + <!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME--> + <!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME--> + <!--<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>--> + <script type="text/javascript" src="$relpath^dynsections.js"></script> + $treeview + $search + $mathjax + <link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" /> + + <link rel="stylesheet" href="$relpath^bootstrap.min.css"> + + $extrastylesheet + + <script src="$relpath^bootstrap.min.js"></script> + <script type="text/javascript" src="$relpath^doxy-boot.js"></script> + </head> + <body> + + <nav class="navbar navbar-default" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <a class="navbar-brand"> + <img alt="Logo" align="left" style="margin-right: 1em;" src=$projectlogo/> + $projectname $projectnumber</a> + </div> + </div> + </nav> + <div id="top"><!-- do not remove this div, it is closed by doxygen! --> + <div class="content" id="content"> + <div class="container"> + <div class="row"> + <div class="col-sm-12 panel panel-default" style="padding-bottom: 15px;"> + <div style="margin-bottom: 15px;"> +<!-- end header part --> diff --git a/CrIa/doc/images/Interlopers_1.png b/CrIa/doc/images/Interlopers_1.png new file mode 100644 index 0000000000000000000000000000000000000000..0a1c70a8d85c8300d9a12a8c4d9372087c292090 Binary files /dev/null and b/CrIa/doc/images/Interlopers_1.png differ diff --git a/CrIa/doc/images/Interlopers_2.png b/CrIa/doc/images/Interlopers_2.png new file mode 100644 index 0000000000000000000000000000000000000000..21ebfc7c4046818882fe9e129da4257e1b15d389 Binary files /dev/null and b/CrIa/doc/images/Interlopers_2.png differ diff --git a/CrIa/doc/images/cheops-logo-with-additional3.png b/CrIa/doc/images/cheops-logo-with-additional3.png new file mode 100644 index 0000000000000000000000000000000000000000..20e1b7978b60d6a269645f9fc35a4abb07c6107a Binary files /dev/null and b/CrIa/doc/images/cheops-logo-with-additional3.png differ diff --git a/CrIa/doc/images/fingerprint.png b/CrIa/doc/images/fingerprint.png new file mode 100644 index 0000000000000000000000000000000000000000..7c88d4f89fd3f254c8dfb3dcae95f91dced5c6c3 Binary files /dev/null and b/CrIa/doc/images/fingerprint.png differ diff --git a/CrIa/doc/images/obsDB_fingerprint.png b/CrIa/doc/images/obsDB_fingerprint.png new file mode 100644 index 0000000000000000000000000000000000000000..9ea66a6ebdeddc4e949292354928943e3225b669 Binary files /dev/null and b/CrIa/doc/images/obsDB_fingerprint.png differ diff --git a/CrIa/doc/images/radius_photometry_real_psf_shape.png b/CrIa/doc/images/radius_photometry_real_psf_shape.png new file mode 100644 index 0000000000000000000000000000000000000000..6f9c66728ab7a45492a3fb3d28e70620ffc24139 Binary files /dev/null and b/CrIa/doc/images/radius_photometry_real_psf_shape.png differ diff --git a/CrIa/doc/images/radius_photometry_real_psf_signal.png b/CrIa/doc/images/radius_photometry_real_psf_signal.png new file mode 100644 index 0000000000000000000000000000000000000000..ee594a8c868bc265e3fcef27328715952d24ca6f Binary files /dev/null and b/CrIa/doc/images/radius_photometry_real_psf_signal.png differ diff --git a/CrIa/doc/images/radius_photometry_sim_psf.png b/CrIa/doc/images/radius_photometry_sim_psf.png new file mode 100644 index 0000000000000000000000000000000000000000..0efc701cbe91ebd083ce92a59559730949e996d7 Binary files /dev/null and b/CrIa/doc/images/radius_photometry_sim_psf.png differ diff --git a/CrIa/doc/images/star_extraction_process.png b/CrIa/doc/images/star_extraction_process.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad19c971d36138ae3425e2885c0120b3262a811 Binary files /dev/null and b/CrIa/doc/images/star_extraction_process.png differ diff --git a/CrIa/ifsw.c b/CrIa/ifsw.c new file mode 100644 index 0000000000000000000000000000000000000000..c45d02befd3dc60714925e8340577efd8d0c2120 --- /dev/null +++ b/CrIa/ifsw.c @@ -0,0 +1,334 @@ +/** + * @file ifsw.c + * @ingroup IASW + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup IASW Instrument Application Software + * + * @brief various functions to initialize and manage buffers related with the + * science data processing + * + * ## IASW + * + * The application is made of several (more or less) independent software components. + * Each of them have their own design, some of which is provided as external documents. + * - The IASW design specification is given by the "CHEOPS IASW Specification", CHEOPS-PNP-INST-RS-001. + * + * - An overview of the Science Data Processing (@ref Sdp) architectural design is given by "CHEOPS SDP Architectural Design", CHEOPS-UVIE-DD-001 + * and the details are found here in the Doxygen. + * + * - The IBSW design specification is given by "CHEOPS IBSW Architectural Design", CHEOPS-UVIE-DD-001. + * At present, the IBSW has its own Doxygen tree with the detailed design. + * Its inclusion in here is TBC. + * + * - The design of the TargetAcquisition function is contained in "CHEOPS IFSW Engineering Algorithms", CHEOPS-UVIE-INST-TN-008. + * The detailed design is also to be included here in the Doxygen (TBD). + * + * - The design of the Centroiding Algorithm is given in "Optimized Centroiding of Stars for Space Applications", R. Ferstl, + * Master Thesis, UVIE 2016, http://othes.univie.ac.at/41269/. + * The detailed design is also to be included in this Doxygen (TBD). + * + */ + + +#include <stdio.h> + +#include <io.h> +#include <asm/leon.h> +#include <leon/leon_reg.h> + +#include <ibsw.h> +#include <event_report.h> +#include <wrap_malloc.h> +#include <errno.h> +#include <stdint.h> +#include <event_report.h> +#include <iwf_fpga.h> +#include <memcfg.h> +#include <leon3_dsu.h> +#include <traps.h> + +#include <ScienceDataProcessing.h> +#include <EngineeringAlgorithms.h> +#include <TargetAcquisition.h> +#include "Services/General/CrIaConstants.h" +#include "ifsw.h" +#include "IfswDebug.h" + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#ifndef PC_TARGET +#include <FwSmCore.h> +#include "../IBSW/include/ibsw_interface.h" +#endif + +extern struct ibsw_config ibsw_cfg; + +extern unsigned char __BUILD_ID; + +static uint32_t notifCounter[N_RT_CONT]; + + +#define CPU_0_STACK_BASE SRAM1_CPU_0_STACK_BASE +#define CPU_1_STACK_BASE SRAM1_CPU_1_STACK_BASE + + +/* configure cpu1 entry to trap table */ + +void cpu1_setup_entry() +{ + uint32_t tmp; + + + dsu_set_noforce_debug_mode(1); + dsu_set_cpu_break_on_iu_watchpoint(1); + + dsu_set_force_debug_on_watchpoint(1); + + /* set trap base register to be the same as on CPU0 and point + * %pc and %npc there + */ + tmp = dsu_get_reg_tbr(0) & ~0xfff; + + dsu_set_reg_tbr(1, tmp); + dsu_set_reg_pc(1, tmp); + dsu_set_reg_npc(1, tmp + 0x4); + + dsu_clear_iu_reg_file(1); + + /* self-referrring stackframe */ + dsu_set_reg_sp(1, 1, SRAM1_CPU_1_STACK_BASE); + dsu_set_reg_fp(1, 1, SRAM1_CPU_1_STACK_BASE); + + /* default invalid mask */ + dsu_set_reg_wim(1, 0x2); + + /* set CWP to 7 */ + dsu_set_reg_psr(1, 0xf34010e1); + + dsu_clear_cpu_break_on_iu_watchpoint(1); + /* resume cpu 1 */ + dsu_clear_force_debug_on_watchpoint(1); + + /* + NOTE: the NS bit of FSR is set in the main for core 0 + as well as for core 1 + */ +} + + +/* wake a cpu by writing to the multiprocessor status register */ +void cpu_wake(uint32_t cpu_id) +{ + iowrite32be(cpu_id, (uint32_t *) 0x80000210); +} + + +unsigned short cpu1_notification(unsigned short action) +{ + unsigned int rt_idx; + unsigned short event_data[2]; + unsigned short status; + + CrIaCopy(CPU2PROCSTATUS_ID, &status); + + MPDEBUGP("NOTIF: status is %d and action is %d\n", status, action); + + rt_idx = RTCONT_CMPR - 1; + if (action == SDP_STATUS_ACQUISITION) + { + rt_idx = RTCONT_ACQ - 1; + } + + /* Mantis 1603 */ + + /* Second CPU is idle, notification can be processed */ + if (status == SDP_STATUS_IDLE) + { + notifCounter[rt_idx] = 0; + status = action; + CrIaPaste(CPU2PROCSTATUS_ID, &status); + cpu_wake(0x2); + return 0; + } + + /* Second CPU is locked by the one operation and notification + is for the same container --> overrun situation! */ + if (status == action) + { + notifCounter[rt_idx]++; + event_data[0] = rt_idx + 1; + event_data[1] = (unsigned short) notifCounter[rt_idx]; + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_NOTIF_ERR, event_data, 4); + return status; + } + + /* if we get here, then status != action, but CPU2 is busy. This means, that + the notification does not need to be processed, e.g. we are doing compression and get a later-phased + acquisition notification */ + + return 0; +} + + +void run_acquisition(void) +{ + TargetAcquisition(&outgoingSibInStruct); + + return; +} + + +void run_compression(void) +{ + ScienceProcessing(); + + return; +} + + +/* cpu 1 main loop */ +void dataproc_mainloop(void) +{ + unsigned char core1load; + unsigned short action; + __attribute__((unused)) register int sp asm ("%sp"); + __attribute__((unused)) uint32_t cnt = 0; + + + while (1) + { + leon3_powerdown_safe(0x40000000); + + CrIaCopy(CPU2PROCSTATUS_ID, &action); + + /* report 100% CPU 1 */ + core1load = 100; + CrIaPaste(CORE1LOAD_ID, &core1load); + + MPDEBUGP("CPU1: poked %d %x op: %d\n", cnt++, sp, action); + + if (action == SDP_STATUS_ACQUISITION) + { + MPDEBUGP("carrying out acquisition...\n"); +#ifdef PC_TARGET + TargetAcquisition(&outgoingSibInStruct); +#else + FwSmExecute(smDescAlgoAcq1); + /* run_rt(RTCONT_ACQ, DEADLINE_ACQ, run_acquisition); */ +#endif + } + + if (action == SDP_STATUS_SCIENCE) + { + MPDEBUGP("carrying out science...\n"); +#ifdef PC_TARGET + ScienceProcessing(); +#else + FwSmExecute(smDescAlgoCmpr); +#endif + } + + action = SDP_STATUS_IDLE; + CrIaPaste(CPU2PROCSTATUS_ID, &action); + + /* report 0% CPU 1 load */ + core1load = 0; + CrIaPaste(CORE1LOAD_ID, &core1load); + } + + /* never reached */ +} + + +int main() +{ + static uint32_t cpu1_ready; + + leon3_flush(); + leon3_enable_icache(); + leon3_enable_dcache(); + leon3_enable_fault_tolerant(); + leon3_enable_snooping(); + + if(leon3_cpuid() == 0) + { + /* self-referring stackframe */ + leon_set_fp(CPU_0_STACK_BASE); + leon_set_sp(CPU_0_STACK_BASE); + + memcfg_configure_sram_flash_access(); + + fpga_mem_ctrl_sram_flash_set_enabled(); + + cpu1_setup_entry(); + + /* NOTE: We do not set the NS bit of the FPU for the first core, + because we want to handle the trap. */ + + /* write to MP status register and wait for CPU 1 to start */ + cpu_wake(0x2); + while (!ioread32be(&cpu1_ready)); + + if(ibsw_init(&ibsw_cfg)) + { + event_report(INIT, HIGH, (uint32_t) errno); + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_UN); + } + + event_report(INIT, NORMAL, 0); + + ibsw_mainloop(&ibsw_cfg); + } + else + { + /* ignore access exception traps (usually edac doublefaults) on cpu 1 */ + /* NOTE: on cpu 0 the trap handler is set up in ibsw_init by ibsw_configure_edac. */ + trap_handler_install(0x9, data_access_exception_trap_ignore); /* EDAC */ + + /* we also install the handler for the FPE, even if we disable them hereafter */ + trap_handler_install(0x8, floating_point_exception_trap); + + /* Upon startup, the FPU of the second core has random initial values, + including the FSR. Here we set the CPU 1 FSR such as to disable + all FPU traps. + + 0x0F800000 ... enable all FP exceptions (except NS) + 0x08000000 ... operand error (NV) + 0x06000000 ... rounding errors (OF + UF) + 0x01000000 ... division by zero and invalid * sqrt(0) (DZ) + 0x00800000 ... inexact result (NX) + + 0x00400000 ... NS bit + */ + { + volatile uint32_t initval = 0x00400000; + + /* NOTE: load fsr means write to it */ + __asm__ __volatile__("ld [%0], %%fsr \n\t" + ::"r"(&initval)); + } + + /* signal ready */ + iowrite32be(0x1, &cpu1_ready); + + dataproc_mainloop(); + } + + return 0; +} + diff --git a/CrIa/ifsw.h b/CrIa/ifsw.h new file mode 100644 index 0000000000000000000000000000000000000000..0e3948209b26c0ca732cfec4771fc7e2a0929bf6 --- /dev/null +++ b/CrIa/ifsw.h @@ -0,0 +1,27 @@ +#ifndef IFSW_H +#define IFSW_H + +#include <stdint.h> + +#define CUSTOM_STACK 1 + +#define CPU_0_STACK_BASE SRAM1_CPU_0_STACK_BASE +#define CPU_1_STACK_BASE SRAM1_CPU_1_STACK_BASE + + + +/* configure cpu1 entry to trap table from SRAM addr 0x0 */ +void cpu1_setup_entry(); + +void cpu_wake(uint32_t cpu_id); + +unsigned short cpu1_notification(unsigned short action); + +void run_acquisition(void); + +void run_compression(void); + +/* cpu 1 main loop */ +void dataproc_mainloop(void); + +#endif diff --git a/CrIa/src/CrConfigIa/CrFwAppSmUserPar.h b/CrIa/src/CrConfigIa/CrFwAppSmUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..742b76cdcadcfc936e411577f7ca3bda988eccfc --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwAppSmUserPar.h @@ -0,0 +1,54 @@ +/** + * @file CrFwAppSmUserPar.h + * @ingroup CrIaDemo + * + * Parameters for the Application State Machine for the IASW Application. + * + * \see CrFwAppSm.h + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_APPSM_USERPAR_H_ +#define CRFW_APPSM_USERPAR_H_ + +#include "CrIaAppSm.h" + +/** + * The pointer to the state machine embedded in state START-UP. The value of + * this constant must be either NULL (if no state machine is embedded in + * START-UP) or a pointer of type FwSmDesc_t. + * + * The default value for this adaptation point is NULL. + */ +#define CR_FW_APPSM_STARTUP_ESM NULL + +/** + * The pointer to the state machine embedded in state NORMAL. The value of + * this constant must be either NULL (if no state machine is embedded in + * NORMAL) or a pointer of type FwSmDesc_t. + * + * The default value for this adaptation point is NULL. + */ +#define CR_FW_APPSM_NORMAL_ESM CrIaAppSmGetModesEsm() + +/** + * The pointer to the state machine embedded in state RESET. The value of this + * constant must be either NULL (if no state machine is embedded in RESET) or a + * pointer of type FwSmDesc_t. + * + * The default value for this adaptation point is NULL. + */ +#define CR_FW_APPSM_RESET_ESM NULL + +/** + * The pointer to the state machine embedded in state SHUTDOWN. The value of + * this constant must be either NULL (if no state machine is embedded in + * SHUTDOWN) or a pointer of type FwSmDesc_t. + * + * The default value for this adaptation point is NULL. + */ +#define CR_FW_APPSM_SHUTDOWN_ESM NULL + +#endif /* CRFW_APPSM_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwCmpData.h b/CrIa/src/CrConfigIa/CrFwCmpData.h new file mode 100644 index 0000000000000000000000000000000000000000..4cfdd37ae4b2a97bab5e8f23143ee236122ef138 --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwCmpData.h @@ -0,0 +1,110 @@ +/** + * @file CrFwCmpData.h + * @ingroup CrIaDemo + * + * Definition of the Framework Component Data (FCD) Type. + * + * Each Framework Component has one instance of a FCD. This data structure is + * used to exchange input and output data with the actions and guards of the + * framework components. + * + * An instance of this data structure is attached to each state machine + * descriptor (using function FwSmSetData) and to each procedure descriptor + * (using function FwPrsetData) used in the framework. + * + * The state machines and procedures which belong to the same Framework + * Component share the same FCD instance. + * + * All the framework components are derived from the Base Component of + * CrFwBaseCmp.h. Hence, a framework component needs two sets of data: the + * base data which are the data needed by the functions defined on the Base + * Component and the derived data which are the data needed by the functions + * defined on the derived component. + * + * The FCD Type is accordingly split into two parts: one part defining the base + * data and another part defining the derived data. + * + * Framework users may have to modify the definition of the FCD Type if they + * wish to introduce new components which are derived from the Base Component + * (see detailed description of ::CrFwCmpData_t type). + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH + */ + +#ifndef CRFW_COMPDATA_H_ +#define CRFW_COMPDATA_H_ + +#include "CrFwUserConstants.h" +#include <FwPrConstants.h> + +/** + * Type for the Framework Component Data (FCD). + * + * The FCD Type is defined as a structure with a number of fixed fields and one + * open "component-specific" field (a pointer to void). + * + * The fixed fields define the base data of the FCD (i.e. the data which are + * used by the Base Component part of a Framework Component). + * + * The component-specific field can be used for additional data which are + * specific to each type of component derived from the Base Component. + * + * As an example, consider the case of an OutStream framework component (see + * CrFwOutStream.h). The fixed fields in the FCD type cover the part of the + * OutStream data which is inherited from the Base Component. The + * cmpSpecificData field covers the data which are specific to the OutStream + * type. + * + * The content of the cmpSpecificData must be cast to the appropriate type + * depending on the type of component which is being manipulated. Thus, for + * instance, in the case of OutStream component, the cmpSpecificData field must + * be cast to a pointer of type: ::CrFwOutStreamData_t. The component-specific + * data types are defined in CrFwConstants.h. + * + * This type is user-configurable to cover the case where an application + * developer needs additional data to be attached to the component instances. + */ +typedef struct CrFwCmpData { + /** + * The instance identifier of the framework component. + */ + CrFwInstanceId_t instanceId; + /** + * The type identifier of the framework component. + */ + CrFwTypeId_t typeId; + /** + * The outcome of an action or check executed by a state machine or by one of + * its procedures. + * + * In many cases, an action or a check have an outcome. This is a generic + * field where that outcome can be stored. + * + * Module CrFwUtilityFunctions.h defines convenience functions which check + * whether the outcome is equal to a certain value. + * + * Where the logical outcome is either "success" or "failure", the value of + * '1' is used to represent "success" and the value of '0' is used to + * represent "failure". + */ + CrFwOutcome_t outcome; + /** + * The Component Initialization Procedure (CIP) (see CrFwInitProc.h). + */ + FwPrDesc_t initProc; + /** + * The Component Reset Procedure (CRP) (see CrFwResetProc.h). + */ + FwPrDesc_t resetProc; + /** + * The Component Execution Procedure (CEP) (see CrFwBaseCmp.h). + */ + FwPrDesc_t execProc; + /** + * Derived data which are specific to each type of framework component. + */ + void* cmpSpecificData; +} CrFwCmpData_t; + +#endif /* CRFW_COMPDATA_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwInFactoryUserPar.h b/CrIa/src/CrConfigIa/CrFwInFactoryUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..8b41fe1bcaa857c859914ed0964f1d21bba041c3 --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwInFactoryUserPar.h @@ -0,0 +1,237 @@ +/** + * @file CrFwInFactoryUserPar.h + * @ingroup CrIaConfig + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief User-modifiable parameters for the InFactory component of the IASW application. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef CRFW_IN_FACTORY_USER_PAR_H +#define CRFW_IN_FACTORY_USER_PAR_H + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> +#include <CrFwConstants.h> +#include <UtilityFunctions/CrFwUtilityFunctions.h> +#include <CrIaInCmp.h> + +#include <Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DefineHkDr.h> +#include <Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3ClrHkDr.h> +#include <Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3EnbHkDrGen.h> +#include <Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DisHkDrGen.h> +#include <Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3SetHkRepFreq.h> + +#include <Services/CrIaServ5EventReportingService/InCmd/CrIaServ5EnbEvtRepGen.h> +#include <Services/CrIaServ5EventReportingService/InCmd/CrIaServ5DisEvtRepGen.h> + +#include <Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6LoadMem.h> +#include <Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6DumpMem.h> + +#include <Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13AbrtDwlk.h> +#include <Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13TrgLrgDataTsfr.h> + +#include <Services/CrIaServ17TestService/InCmd/CrIaServ17PerfConnTest.h> + +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbFdChk.h> +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisFdChk.h> +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbFdChk.h> +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisFdChk.h> +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbRecovProc.h> +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisRecovProc.h> +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbRecovProc.h> +#include <Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisRecovProc.h> + +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOnSem.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOffSem.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStab.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStby.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdWin.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdFull.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoDiag.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192AbortDiag.h> +#include <Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoSafe.h> + +#include <Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193PrepareSci.h> +#include <Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartSci.h> +#include <Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopScience.h> +#include <Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopSem.h> +#include <Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartOfflineOper.h> +#include <Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193SwitchOffIasw.h> + +#include <Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StartAlgo.h> +#include <Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StopAlgo.h> +#include <Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194SusAlgo.h> +#include <Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194ResAlgo.h> + +#include <Services/CrIaServ196AOCSService/InCmd/CrIaServ196StarMapCmd.h> + +#include <Services/CrIaServ197BootReportService/InCmd/CrIaServ197RepBoot.h> + +#include <Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.h> +#include <Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStop.h> + +#include <Services/CrIaServ210BootManagementService/InCmd/CrIaServ210EnbWdog.h> +#include <Services/CrIaServ210BootManagementService/InCmd/CrIaServ210DisWdog.h> +#include <Services/CrIaServ210BootManagementService/InCmd/CrIaServ210ResetDpu.h> + +#include <Services/CrIaServ211ParameterUpdateService/InCmd/CrIaServ211UpdatePar.h> + +/* SEM InRep Services */ + +#include <Services/CrSemServ1CommandVerificationService/InRep/CrSemServ1ComVerif.h> +#include <Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.h> +#include <Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtNorm.h> +#include <Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrLowSev.h> +#include <Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrMedSev.h> +/*#include <Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrHighSev.h>*/ /* NOT USED by SEM */ +#include <Services/CrSemServ21ScienceDataService/InRep/CrSemServ21DatCcdWindow.h> +#include <Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatFunctParam.h> +#include <Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatOperParam.h> +#include <Services/CrSemServ222PrivateService222/InRep/CrSemServ222DatTestLog.h> + +/** + * The maximum number of components representing an in-coming command packet which may be allocated at any one time. + * This constant must be a positive integer smaller than the range of CrFwInFactoryPoolIndex_t. + */ +#define CR_FW_INFACTORY_MAX_NOF_INCMD 6 /* same as in PCRL size */ + +/** + * Definition of the in-coming command packet kinds supported by the application. + */ +#define CR_FW_INCMD_INIT_KIND_DESC\ + {\ +{CRIA_SERV3, CRIA_SERV3_DEFINE_HK_DR, 0, &CrIaServ3DefineHkDrValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3DefineHkDrStartAction, &CrIaServ3DefineHkDrProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV3, CRIA_SERV3_CLR_HK_DR, 0, &CrIaServ3ClrHkDrValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3ClrHkDrStartAction, &CrIaServ3ClrHkDrProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV3, CRIA_SERV3_ENB_HK_DR_GEN, 0, &CrIaServ3EnbHkDrGenValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3EnbHkDrGenStartAction, &CrIaServ3EnbHkDrGenProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV3, CRIA_SERV3_DIS_HK_DR_GEN, 0, &CrIaServ3DisHkDrGenValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3DisHkDrGenStartAction, &CrIaServ3DisHkDrGenProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV3, CRIA_SERV3_SET_HK_REP_FREQ, 0, &CrIaServ3SetHkRepFreqValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3SetHkRepFreqStartAction, &CrIaServ3SetHkRepFreqProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV5, CRIA_SERV5_ENB_EVT_REP_GEN, 0, &CrIaServ5EnbEvtRepGenValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ5EnbEvtRepGenStartAction, &CrIaServ5EnbEvtRepGenProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV5, CRIA_SERV5_DIS_EVT_REP_GEN, 0, &CrIaServ5DisEvtRepGenValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ5DisEvtRepGenStartAction, &CrIaServ5DisEvtRepGenProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV6, CRIA_SERV6_LOAD_MEM, 0, &CrIaServ6LoadMemValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ6LoadMemStartAction, &CrIaServ6LoadMemProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV6, CRIA_SERV6_DUMP_MEM, 0, &CrIaServ6DumpMemValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ6DumpMemStartAction, &CrIaServ6DumpMemProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV13, CRIA_SERV13_ABRT_DWLK, 0, &CrIaServ13AbrtDwlkValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ13AbrtDwlkStartAction, &CrIaServ13AbrtDwlkProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV13, CRIA_SERV13_TRG_LRG_DATA_TSFR, 0, &CrIaServ13TrgLrgDataTsfrValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ13TrgLrgDataTsfrStartAction, &CrIaServ13TrgLrgDataTsfrProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV17, CRIA_SERV17_PERF_CONN_TEST, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ17PerfConnTestStartAction, &CrIaServ17PerfConnTestProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_GLOB_ENB_FD_CHK, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191GlobEnbFdChkStartAction, &CrIaServ191GlobEnbFdChkProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_GLOB_DIS_FD_CHK, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191GlobDisFdChkStartAction, &CrIaServ191GlobDisFdChkProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_ENB_FD_CHK, 0, &CrIaServ191EnbFdChkValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191EnbFdChkStartAction, &CrIaServ191EnbFdChkProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_DIS_FD_CHK, 0, &CrIaServ191DisFdChkValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191DisFdChkStartAction, &CrIaServ191DisFdChkProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_GLOB_ENB_RECOV_PROC, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191GlobEnbRecovProcStartAction, &CrIaServ191GlobEnbRecovProcProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_GLOB_DIS_RECOV_PROC, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191GlobDisRecovProcStartAction, &CrIaServ191GlobDisRecovProcProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_ENB_RECOV_PROC, 0, &CrIaServ191EnbRecovProcValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191EnbRecovProcStartAction, &CrIaServ191EnbRecovProcProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV191, CRIA_SERV191_DIS_RECOV_PROC, 0, &CrIaServ191DisRecovProcValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ191DisRecovProcStartAction, &CrIaServ191DisRecovProcProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_SWCH_ON_SEM, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192SwchOnSemStartAction, &CrIaServ192SwchOnSemProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_SWCH_OFF_SEM, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192SwchOffSemStartAction, &CrIaServ192SwchOffSemProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_GO_STAB, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192GoStabStartAction, &CrIaServ192GoStabProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_GO_STBY, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192GoStbyStartAction, &CrIaServ192GoStbyProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_GO_CCD_WIN, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192GoCcdWinStartAction, &CrIaServ192GoCcdWinProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_GO_CCD_FULL, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192GoCcdFullStartAction, &CrIaServ192GoCcdFullProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_GO_DIAG, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192GoDiagStartAction, &CrIaServ192GoDiagProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_ABORT_DIAG, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192AbortDiagStartAction, &CrIaServ192AbortDiagProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV192, CRIA_SERV192_GO_SAFE, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ192GoSafeStartAction, &CrIaServ192GoSafeProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV193, CRIA_SERV193_PREPARE_SCI, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ193PrepareSciStartAction, &CrIaServ193PrepareSciProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV193, CRIA_SERV193_START_SCI, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ193StartSciStartAction, &CrIaServ193StartSciProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV193, CRIA_SERV193_STOP_SCIENCE, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ193StopScienceStartAction, &CrIaServ193StopScienceProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV193, CRIA_SERV193_STOP_SEM, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ193StopSemStartAction, &CrIaServ193StopSemProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV193, CRIA_SERV193_START_OFFLINE_OPER, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ193StartOfflineOperStartAction, &CrIaServ193StartOfflineOperProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV193, CRIA_SERV193_SWITCH_OFF_IASW, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ193SwitchOffIaswStartAction, &CrIaServ193SwitchOffIaswProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV194, CRIA_SERV194_START_ALGO, 0, &CrIaServ194StartAlgoValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ194StartAlgoStartAction, &CrIaServ194StartAlgoProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV194, CRIA_SERV194_STOP_ALGO, 0, &CrIaServ194StopAlgoValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ194StopAlgoStartAction, &CrIaServ194StopAlgoProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV194, CRIA_SERV194_SUS_ALGO, 0, &CrIaServ194SusAlgoValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ194SusAlgoStartAction, &CrIaServ194SusAlgoProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV194, CRIA_SERV194_RES_ALGO, 0, &CrIaServ194ResAlgoValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ194ResAlgoStartAction, &CrIaServ194ResAlgoProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV196, CRIA_SERV196_STAR_MAP_CMD, 0, &CrIaServ196StarMapCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ196StarMapCmdStartAction, &CrIaServ196StarMapCmdProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV197, CRIA_SERV197_REP_BOOT, 0, &CrIaServ197RepBootValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ197RepBootStartAction, &CrIaServ197RepBootProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV198, CRIA_SERV198_PROC_START, 0, &CrIaServ198ProcStartValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ198ProcStartStartAction, &CrIaServ198ProcStartProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV198, CRIA_SERV198_PROC_STOP, 0, &CrIaServ198ProcStopValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ198ProcStopStartAction, &CrIaServ198ProcStopProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV210, CRIA_SERV210_ENB_WDOG, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ210EnbWdogStartAction, &CrIaServ210EnbWdogProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV210, CRIA_SERV210_DIS_WDOG, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ210DisWdogStartAction, &CrIaServ210DisWdogProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV210, CRIA_SERV210_RESET_DPU, 0, &CrIaInCmdValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ210ResetDpuStartAction, &CrIaServ210ResetDpuProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction},\ +{CRIA_SERV211, CRIA_SERV211_UPDATE_PAR, 0, &CrIaServ211UpdateParValidityCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ211UpdateParStartAction, &CrIaServ211UpdateParProgressAction, &CrFwSmEmptyAction, &CrFwSmEmptyAction}\ +} + + +/** + * The total number of kinds of in-coming command packets supported by the application. + */ +#define CR_FW_INCMD_NKINDS 47 + +/** + * The maximum number of components representing an in-coming report packet which may be allocated at any one time. + * This constant must be a positive integer smaller than the range of CrFwInFactoryPoolIndex_t. + */ +#define CR_FW_INFACTORY_MAX_NOF_INREP 255 /* has to be the same as in the PCRL size */ + +/** + * Definition of the in-coming report packet kinds supported by the application. + */ +#define CR_FW_INREP_INIT_KIND_DESC\ + {\ +{CRSEM_SERV1, CRSEM_SERV1_ACC_SUCC, 0, &CrSemServ1ComVerifUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV1, CRSEM_SERV1_ACC_FAIL, 0, &CrSemServ1ComVerifUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV1, CRSEM_SERV1_TERM_SUCC, 0, &CrSemServ1ComVerifUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV1, CRSEM_SERV1_TERM_FAIL, 0, &CrSemServ1ComVerifUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV3, CRSEM_SERV3_DAT_HK, 1, &CrSemServ3DatHkUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV3, CRSEM_SERV3_DAT_HK, 2, &CrSemServ3DatHkUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_NORM, CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY, &CrSemServ5EvtNormUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_NORM, CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY, &CrSemServ5EvtNormUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_NORM, CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION, &CrSemServ5EvtNormUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_NORM, CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED, &CrSemServ5EvtNormUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_NORM, CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY, &CrSemServ5EvtNormUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_NORM, CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY, &CrSemServ5EvtNormUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_NORM, CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL, &CrSemServ5EvtNormUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_LOW_SEV, CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD, &CrSemServ5EvtErrLowSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_WAR_PATTER, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_WAR_PACKWR, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_ERR_DAT_DMA, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_ERR_BIAS_SET, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_ERR_SYNC, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_ERR_SCRIPT, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_ERR_PWR, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_MED_SEV, CRSEM_SERV5_EVT_ERR_SPW_TC, &CrSemServ5EvtErrMedSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV21, CRSEM_SERV21_DAT_CCD_WINDOW, 0, &CrSemServ21DatCcdWindowUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV220,CRSEM_SERV220_DAT_OPER_PARAM, 0, &CrSemServ220DatOperParamUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV220,CRSEM_SERV220_DAT_FUNCT_PARAM, 0, &CrSemServ220DatFunctParamUpdateAction, &CrIaInRepValidityCheck, 0},\ +{CRSEM_SERV222,CRSEM_SERV222_DAT_TEST_LOG, 0, &CrSemServ222DatTestLogUpdateAction, &CrIaInRepValidityCheck, 0}\ + } + +/** + * The total number of kinds of in-coming report packets supported by the application. + */ +#define CR_FW_INREP_NKINDS 46 + +/* NOT USED by SEM - Dummy TM(5,4) Event Report +{CRSEM_SERV5, CRSEM_SERV5_EVT_ERR_HIGH_SEV, 44000, &CrSemServ5EvtErrHighSevUpdateAction, &CrIaInRepValidityCheck, 0},\ +*/ + +#endif /* CRFW_IN_FACTORY_USER_PAR_H */ + diff --git a/CrIa/src/CrConfigIa/CrFwInLoaderUserPar.h b/CrIa/src/CrConfigIa/CrFwInLoaderUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..7e28fb0755cf91af262cbb4d99c301540622607f --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwInLoaderUserPar.h @@ -0,0 +1,50 @@ +/** + * @file CrFwInLoaderUserPar.h + * @ingroup CrIaDemo + * + * User-modifiable parameters for the InLoader components for the IASW + * Application. + * + * \see CrFwInLoader.h + * + * The parameters defined in this file determine the configuration of the + * InLoader singleton component. + * + * The value of these parameters cannot be changed dynamically. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_INLOADER_USERPAR_H_ +#define CRFW_INLOADER_USERPAR_H_ + +#include "InLoader/CrFwInLoader.h" +#include "CrIaInLoader.h" + +/** + * The function which determines the re-routing destination of a packet. + * + * This function must conform to the prototype defined by + * ::CrFwInLoaderGetReroutingDest_t. The function specified here is the + * default re-routing destination function defined in CrFwInLoader.h. + * + * Use of this re-routing function implies that the IASW Application has no + * re-routing capabilities. + */ +#define CR_FW_INLOADER_DET_REROUTING_DEST &CrIaInLoaderGetReroutingDestination + +/** + * The function which determines the InManager into which an InReport or + * InCommand must be loaded. + * + * This function must conform to the prototype defined by + * ::CrFwInLoaderGetInManager_t. + * + * For the IASW application, the selection is as follows. + * - Incoming reports from the SEM go into the InManagerSem + * - Incoming commands from the OBC go into the InManagerGrdObc + */ +#define CR_FW_INLOADER_SEL_INMANAGER &CrIaInLoaderGetInManager + +#endif /* CRFW_INLOADER_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwInManagerUserPar.h b/CrIa/src/CrConfigIa/CrFwInManagerUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..7fbfc13e49d1874db6abe4d5aba450f19526889c --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwInManagerUserPar.h @@ -0,0 +1,39 @@ +/** + * @file CrFwInManagerUserPar.h + * @ingroup CrIaDemo + * + * User-modifiable parameters for the InManager components of the IASW + * Application. + * + * \see CrFwInManager.h + * + * The parameters defined in this file determine the configuration of the + * InManager Components. + * + * The value of these parameters cannot be changed dynamically. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_INMANAGER_USERPAR_H_ +#define CRFW_INMANAGER_USERPAR_H_ + +/** + * The number of InManager components in the application. + * The value of this constant must be smaller than the range of the ::CrFwCounterU1_t + * integer type. + */ +#define CR_FW_NOF_INMANAGER 2 + +/** + * The sizes of the Pending Command/Report List (PCRL) of the InManager + * components. Each InManager has one PCRL. + * + * This constant defines the size of the PCRL of the i-th InManager. The size + * of a PCRL must be a positive integer (i.e. it is not legal to define a + * zero-size PCRL) in the range of the ::CrFwCounterU2_t type. + */ +#define CR_FW_INMANAGER_PCRLSIZE {255, 6} /* Email from PnP on Sat, 19 Nov 2016 09:08:56 +0100 */ + +#endif /* CRFW_INMANAGER_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwInRegistryUserPar.h b/CrIa/src/CrConfigIa/CrFwInRegistryUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..94f0133877b2875941ae4faee0afaa4f0e66b4bd --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwInRegistryUserPar.h @@ -0,0 +1,24 @@ +/** + * @file CrFwInRegistryUserPar.h + * @ingroup CrIaDemo + * + * User-modifiable parameters for the InRegistry component. + * + * \see CrFwInRegistry.h + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_INREGISTRY_USERPAR_H_ +#define CRFW_INREGISTRY_USERPAR_H_ + +/** + * The maximum number of commands or reports which can be tracked by the + * InRegistry. + * + * This constant must be smaller than the range of ::CrFwTrackingIndex_t. + */ +#define CR_FW_INREGISTRY_N 10 /* value taken from DD-001, issue 2.2 p 30 */ + +#endif /* CRFW_INREGISTRY_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwInStreamUserPar.h b/CrIa/src/CrConfigIa/CrFwInStreamUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..d38eeaa4223649ab9a493b28ef0d0fa386be5b52 --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwInStreamUserPar.h @@ -0,0 +1,208 @@ +/** + * @file CrFwInStreamUserPar.h + * @ingroup CrIaDemo + * + * User-modifiable parameters for the InStream components of the IASW + * Application. + * + * \see CrFwInStream.h + * + * The parameters defined in this file determine the configuration of the + * InStream Components. + * + * The value of these parameters cannot be changed dynamically. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_INSTREAM_USERPAR_H_ +#define CRFW_INSTREAM_USERPAR_H_ + +/* Includes */ +#include "CrFwConstants.h" +#include "BaseCmp/CrFwResetProc.h" +#include "InStream/CrFwInStream.h" +#include "CrIaIasw.h" + +/** + * The number of InStream components in the application. + * + * The value of this constant must be smaller than the range of the + * ::CrFwCounterU1_t integer type. + */ +#define CR_FW_NOF_INSTREAM 3 + +/** + * The sizes of the packet queues in the InStream components. + * Each InStream has one packet queue. + * This constant defines the size of the packet queue of the i-th InStream. + * The size of the packet queue represents the maximum number of packets which + * may remain pending in the packet queue. + * The size of a packet queue must be a positive integer (i.e. it is not legal + * to define a zero-size packet queue). + */ +#define CR_FW_INSTREAM_PQSIZE {255,2,6} /* Email from PnP on Sat, 19 Nov 2016 09:08:56 +0100 */ + +/** + * The packet sources which are managed by the InStream components. + * + * Each InStream is responsible for collecting packets from one packet source. + * This constant is the initializer for the array which defines the packet + * source associated to the i-th InStream. + */ +#define CR_FW_INSTREAM_SRC {CR_FW_CLIENT_SEM, \ + CR_FW_CLIENT_OBC, \ + CR_FW_CLIENT_GRD} + +/** + * The number of groups of the InStream components. This is positive number and + * defines the number of groups of the i-th InStream. + * + * The number of groups defined in this file are those used for the IASW + * Application. + */ +#define CR_FW_INSTREAM_NOF_GROUPS {12,12,1} + +/** + * The functions implementing the Packet Collect Operations of the InStream components. + * Each InStream component needs to be able to collect a packet from the middleware. + * The function implementing this packet collect operation is one of the + * adaptation points of the framework. + * This array defines the packet collect operations for the InStreams. + * The items in the arrays must be function pointers of type: + * ::CrFwPcktCollect_t. + */ +#define CR_FW_INSTREAM_PCKTCOLLECT {&CrIbSemPcktCollect, \ + &CrIbObcPcktCollect, \ + &CrIbGrdPcktCollect} + +/** + * The functions implementing the Packet Available Check Operations of the InStream + * components. + * Each InStream component needs to be able to check whether the middleware is in + * state WAITING (no packet is available for collection) or PCKT_AVAIL (a packet is + * available for collection). + * The functions which query the middleware to check whether a packet is available or not + * is one of the adaptation points of the framework. + * This array defines the Packet Available Check Operations for the InStream. + * The items in the array must be function pointers of type: + * ::CrFwPcktAvailCheck_t. + */ +#define CR_FW_INSTREAM_PCKTAVAILCHECK {&CrIbIsSemPcktAvail, \ + &CrIbIsObcPcktAvail, \ + &CrIbIsGrdPcktAvail} + +/** + * The functions implementing the Initialization Check of the InStream + * components. + * + * The InStream components are derived from the Base Component and they + * therefore inherit its Initialization Procedure. + * + * \see CrFwInitProc.h + * + * The initialization procedure must be configured with two actions. + * - The Initiation Check + * - The Initialization Action + * + * The items in the array must be function pointers of type FwPrAction_t. + * + * For the IASW application, no Initialization Check is required for the + * InStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_INSTREAM_INITCHECK {&CrFwBaseCmpDefInitCheck, \ + &CrFwBaseCmpDefInitCheck, \ + &CrFwBaseCmpDefInitCheck} + +/** + * The functions implementing the Initialization Action of the InStream + * components. + * + * The InStream components are derived from the Base Component and they + * therefore inherit its Initialization Procedure. + * + * \see CrFwInitProc.h + * + * The initialization procedure must be configured with two actions. + * - The Initiation Check + * - The Initialization Action + * + * The items in the array must be function pointers of type FwPrAction_t + * + * For the IASW application, no Initialization Action is required for the + * InStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_INSTREAM_INITACTION {&CrFwInStreamDefInitAction, \ + &CrFwInStreamDefInitAction, \ + &CrFwInStreamDefInitAction} + +/** + * The functions implementing the Configuration Check of the InStream + * components. + * + * The InStream components are derived from the Base Component and they + * therefore inherit its Reset Procedure. + * + * \see CrSwResetProc.h + * + * The reset procedure must be configured with two actions + * - The Configuration Action + * - The Configuration Check + * + * The items in the array must be function pointers of type FwPrAction_t. + * + * Function ::CrFwBaseCmpDefConfigCheck can be used as a default + * implementation for this function. + * + * For the IASW application, no Configuration Check is required for the + * InStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_INSTREAM_CONFIGCHECK {&CrFwBaseCmpDefConfigCheck, \ + &CrFwBaseCmpDefConfigCheck, \ + &CrFwBaseCmpDefConfigCheck} + +/** + * The functions implementing the Configuration Action of the InStream + * components. + * + * The InStream components are derived from the Base Component and they + * therefore inherit its Reset Procedure. + * + * \see CrSwResetProc.h + * + * The reset procedure must be configured with two actions + * - The Configuration Action + * - The Configuration Check + * + * The items in the array must be function pointers of type FwPrAction_t. + * + * For the IASW application, no Configuration Action is required for the + * InStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_INSTREAM_CONFIGACTION {&CrFwInStreamDefConfigAction, \ + &CrFwInStreamDefConfigAction, \ + &CrFwInStreamDefConfigAction} + +/** + * The functions implementing the Shutdown Action of the InStream components. + * + * The InStream components are derived from the Base Component and they + * therefore inherit its Reset Procedure. + * + * \see CrFwBaseCmp.h + * + * The reset procedure must be configured with two actions + * - The Configuration Action + * - The Configuration Check + * + * The items in the array must be function pointers of type FwSmAction_t. + * + * For the IASW application, no Shutdown Action is required for the InStream + * components. Therefore, the default base implementation is used. + */ +#define CR_FW_INSTREAM_SHUTDOWNACTION {&CrFwInStreamDefShutdownAction, \ + &CrFwInStreamDefShutdownAction, \ + &CrFwInStreamDefShutdownAction} + +#endif /* CRFW_INSTREAM_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwOutFactoryUserPar.h b/CrIa/src/CrConfigIa/CrFwOutFactoryUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..28dd640ef9ad3375ac2377f4249fac06a6f88cc9 --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwOutFactoryUserPar.h @@ -0,0 +1,207 @@ +/** + * @file CrFwOutFactoryUserPar.h + * @ingroup CrIaConfig + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief User-modifiable parameters for the OutFactory component of the IASW application. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef CRFW_OUT_FACTORY_USER_PAR_H +#define CRFW_OUT_FACTORY_USER_PAR_H + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> +#include <CrFwConstants.h> +#include <UtilityFunctions/CrFwUtilityFunctions.h> +#include <CrIaOutCmp.h> + +#include <Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccSucc.h> +#include <Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccFail.h> +#include <Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartSucc.h> +#include <Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartFail.h> +#include <Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermSucc.h> +#include <Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermFail.h> +#include <Services/CrIaServ3HousekeepingDataReportingService/OutRep/CrIaServ3HkDr.h> +#include <Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h> +#include <Services/CrIaServ6MemoryManagementService/OutRep/CrIaServ6MemDump.h> +#include <Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13FstDwlk.h> +#include <Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13IntmDwlk.h> +#include <Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13LastDwlk.h> +#include <Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13DwlkAbrt.h> +#include <Services/CrIaServ195HeartbeatService/OutRep/CrIaServ195HbRep.h> +#include <Services/CrIaServ196AOCSService/OutRep/CrIaServ196AocsRep.h> +#include <Services/CrIaServ197BootReportService/OutRep/CrIaServ197BootRep.h> + +#include <Services/CrSemServ9HousekeepingDataReportingService/OutCmd/CrSemServ9CmdTimeUpdate.h> +#include <Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataEnable.h> +#include <Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataDisable.h> +#include <Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdOperParam.h> +#include <Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdTempCtrlEnable.h> +#include <Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdFunctParam.h> +#include <Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerEnb.h> +#include <Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerDis.h> +#include <Services/CrSemServ222PrivateService222/OutCmd/CrSemServ222DiagEnable.h> + +/** + * The maximum number of OutComponents which may be allocated at any one time. + * This constant must be smaller than the range of CrFwOutFactoryPoolIndex_t. + */ + +#define CR_FW_OUTFACTORY_MAX_NOF_OUTCMP 74 /* has to be the same as POCL size */ + + +/** + * Definition of the OutComponent kinds supported by an application. + */ + + +#define CR_FW_OUTCMP_INIT_KIND_DESC\ + {\ +{CRIA_SERV1, CRIA_SERV1_ACC_SUCC, 0, crRepType, CRIA_SERV1_ACC_SUCC_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ1AccSuccUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV1, CRIA_SERV1_ACC_FAIL, 0, crRepType, CRIA_SERV1_ACC_FAIL_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ1AccFailUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV1, CRIA_SERV1_START_SUCC, 0, crRepType, CRIA_SERV1_START_SUCC_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ1StartSuccUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV1, CRIA_SERV1_START_FAIL, 0, crRepType, CRIA_SERV1_START_FAIL_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ1StartFailUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV1, CRIA_SERV1_TERM_SUCC, 0, crRepType, CRIA_SERV1_TERM_SUCC_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ1TermSuccUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV1, CRIA_SERV1_TERM_FAIL, 0, crRepType, CRIA_SERV1_TERM_FAIL_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ1TermFailUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV3, CRSEM_SERV3_CMD_HK_ENABLE, 0, crCmdType, CRSEM_SERV3_CMD_HK_ENABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrFwSmEmptyAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV3, CRSEM_SERV3_CMD_HK_DISABLE, 0, crCmdType, CRSEM_SERV3_CMD_HK_DISABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrFwSmEmptyAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 1, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 2, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 3, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 4, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 5, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 6, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 7, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 8, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 9, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 10, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 11, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 12, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 13, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 14, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 15, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 16, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 17, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 18, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 19, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 20, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 21, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 22, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 23, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 24, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 25, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 26, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 27, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 28, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 29, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 30, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 31, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 32, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 33, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 34, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 35, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 36, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 37, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 38, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 39, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 40, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 41, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 42, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 43, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 44, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 45, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 46, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 47, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 48, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 49, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV3, CRIA_SERV3_HK_DR, 50, crRepType, CRIA_SERV3_HK_DR_LENGTH, &CrIaServ3HkDrEnableCheck, &CrIaServ3HkDrReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ3HkDrUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV3, CRSEM_SERV3_CMD_HK_PERIOD, 0, crCmdType, CRSEM_SERV3_CMD_HK_PERIOD_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrFwSmEmptyAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_NORM, CRIA_SERV5_EVT_SEM_TR, crRepType, CRIA_SERV5_EVT_SEM_TR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_NORM, CRIA_SERV5_EVT_IASW_TR, crRepType, CRIA_SERV5_EVT_IASW_TR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_NORM, CRIA_SERV5_EVT_SEMOP_TR, crRepType, CRIA_SERV5_EVT_SEMOP_TR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_NORM, CRIA_SERV5_EVT_SC_PR_STRT, crRepType, CRIA_SERV5_EVT_SC_PR_STRT_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_NORM, CRIA_SERV5_EVT_SC_PR_END, crRepType, CRIA_SERV5_EVT_SC_PR_END_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_NORM, CRIA_SERV5_EVT_INIT_SUCC, crRepType, CRIA_SERV5_EVT_INIT_SUCC_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_LOW_SEV, CRIA_SERV5_EVT_SEQ_CNT_ERR, crRepType, CRIA_SERV5_EVT_SEQ_CNT_ERR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_LOW_SEV, CRIA_SERV5_EVT_1553_ERR_L, crRepType, CRIA_SERV5_EVT_1553_ERR_L_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_LOW_SEV, CRIA_SERV5_EVT_SPW_ERR_L, crRepType, CRIA_SERV5_EVT_SPW_ERR_L_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_LOW_SEV, CRIA_SERV5_EVT_SBIT_ERR, crRepType, CRIA_SERV5_EVT_SBIT_ERR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INV_DEST, crRepType, CRIA_SERV5_EVT_INV_DEST_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INREP_CR_FAIL, crRepType, CRIA_SERV5_EVT_INREP_CR_FAIL_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_PCRL2_FULL, crRepType, CRIA_SERV5_EVT_PCRL2_FULL_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FD_FAILED, crRepType, CRIA_SERV5_EVT_FD_FAILED_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SDSC_ILL, crRepType, CRIA_SERV5_EVT_SDSC_ILL_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SDSC_OOS, crRepType, CRIA_SERV5_EVT_SDSC_OOS_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_CLCT_SIZE, crRepType, CRIA_SERV5_EVT_CLCT_SIZE_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SIB_SIZE, crRepType, CRIA_SERV5_EVT_SIB_SIZE_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FBF_LOAD_RISK, crRepType, CRIA_SERV5_EVT_FBF_LOAD_RISK_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FBF_SAVE_DENIED, crRepType, CRIA_SERV5_EVT_FBF_SAVE_DENIED_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FBF_SAVE_ABRT, crRepType, CRIA_SERV5_EVT_FBF_SAVE_ABRT_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SDB_CNF_FAIL, crRepType, CRIA_SERV5_EVT_SDB_CNF_FAIL_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_CMPR_SIZE, crRepType, CRIA_SERV5_EVT_CMPR_SIZE_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INSTRM_PQF, crRepType, CRIA_SERV5_EVT_INSTRM_PQF_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OCMP_INVD, crRepType, CRIA_SERV5_EVT_OCMP_INVD_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OCMP_ILLGR, crRepType, CRIA_SERV5_EVT_OCMP_ILLGR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_IN_ILLGR, crRepType, CRIA_SERV5_EVT_IN_ILLGR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INV_CENT, crRepType, CRIA_SERV5_EVT_INV_CENT_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, crRepType, CRIA_SERV5_EVT_OOL_PARAM_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_1553_ERR_M, crRepType, CRIA_SERV5_EVT_1553_ERR_M_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SPW_ERR_M, crRepType, CRIA_SERV5_EVT_SPW_ERR_M_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FL_FBF_BB, crRepType, CRIA_SERV5_EVT_FL_FBF_BB_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_DBIT_ERR, crRepType, CRIA_SERV5_EVT_DBIT_ERR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SYNC_LOSS, crRepType, CRIA_SERV5_EVT_SYNC_LOSS_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SDP_NOMEM, crRepType, CRIA_SERV5_EVT_SDP_NOMEM_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_SEM_ILL_ST, crRepType, CRIA_SERV5_EVT_SEM_ILL_ST_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_ACQ_FAIL, crRepType, CRIA_SERV5_EVT_ACQ_FAIL_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_PROCBUF_INSUF, crRepType, CRIA_SERV5_EVT_PROCBUF_INSUF_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_XIB_FULL, crRepType, CRIA_SERV5_EVT_XIB_FULL_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_IMG_INSUF, crRepType, CRIA_SERV5_EVT_IMG_INSUF_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_RP_STARTED, crRepType, CRIA_SERV5_EVT_RP_STARTED_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_INIT_FAIL, crRepType, CRIA_SERV5_EVT_INIT_FAIL_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_THRD_OR, crRepType, CRIA_SERV5_EVT_THRD_OR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_NOTIF_ERR, crRepType, CRIA_SERV5_EVT_NOTIF_ERR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_1553_ERR_H, crRepType, CRIA_SERV5_EVT_1553_ERR_H_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_SPW_ERR_H, crRepType, CRIA_SERV5_EVT_SPW_ERR_H_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_FL_EL_ERR, crRepType, CRIA_SERV5_EVT_FL_EL_ERR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV5, CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_FL_FBF_ERR, crRepType, CRIA_SERV5_EVT_FL_FBF_ERR_LENGTH, &CrIaServ5EventEnableCheck, &CrIaServ5EventReadyCheck, &CrIaServ5EventRepeatCheck, &CrIaServ5EventUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV6, CRIA_SERV6_MEM_DUMP, 0, crRepType, CRIA_SERV6_MEM_DUMP_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ6MemDumpUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV9, CRSEM_SERV9_CMD_TIME_UPDATE, 0, crCmdType, CRSEM_SERV9_CMD_TIME_UPDATE_LENGTH, &CrSemServ9CmdTimeUpdateEnableCheck, &CrSemServ9CmdTimeUpdateReadyCheck, &CrSemServ9CmdTimeUpdateRepeatCheck, &CrSemServ9CmdTimeUpdateUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV13, CRIA_SERV13_FST_DWLK, 0, crRepType, CRIA_SERV13_FST_DWLK_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ13FstDwlkUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV13, CRIA_SERV13_INTM_DWLK, 0, crRepType, CRIA_SERV13_INTM_DWLK_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ13IntmDwlkUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV13, CRIA_SERV13_LAST_DWLK, 0, crRepType, CRIA_SERV13_LAST_DWLK_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ13LastDwlkUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV13, CRIA_SERV13_DWLK_ABRT, 0, crRepType, CRIA_SERV13_DWLK_ABRT_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ13DwlkAbrtUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV17, CRIA_SERV17_LINK_CONN_REP, 0, crRepType, CRIA_SERV17_LINK_CONN_REP_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrFwSmEmptyAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV21, CRSEM_SERV21_CMD_CCD_DATA_ENABLE, 0, crCmdType, CRSEM_SERV21_CMD_CCD_DATA_ENABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ21CmdCcdDataEnableUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV21, CRSEM_SERV21_CMD_CCD_DATA_DISABLE, 0, crCmdType, CRSEM_SERV21_CMD_CCD_DATA_DISABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ21CmdCcdDataDisableUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV195, CRIA_SERV195_HB_REP, 0, crRepType, CRIA_SERV195_HB_REP_LENGTH, &CrFwSmCheckAlwaysTrue, &CrIaServ195HbRepReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ195HbRepUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV196, CRIA_SERV196_AOCS_REP, 0, crRepType, CRIA_SERV196_AOCS_REP_LENGTH, &CrIaServ196AocsRepEnableCheck, &CrIaServ196AocsRepReadyCheck, &CrFwSmCheckAlwaysTrue, &CrIaServ196AocsRepUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRIA_SERV197, CRIA_SERV197_BOOT_REP, 0, crRepType, CRIA_SERV197_BOOT_REP_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrIaServ197BootRepUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV220, CRSEM_SERV220_CMD_OPER_PARAM, 0, crCmdType, CRSEM_SERV220_CMD_OPER_PARAM_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ220CmdOperParamUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV220, CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE, 0, crCmdType, CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ220CmdTempCtrlEnableUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV220, CRSEM_SERV220_CMD_FUNCT_PARAM, 0, crCmdType, CRSEM_SERV220_CMD_FUNCT_PARAM_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ220CmdFunctParamUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV221, CRSEM_SERV221_CMD_SAFE_ENTER, 0, crCmdType, CRSEM_SERV221_CMD_SAFE_ENTER_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrFwSmEmptyAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV221, CRSEM_SERV221_CMD_STANDBY_ENTER, 0, crCmdType, CRSEM_SERV221_CMD_STANDBY_ENTER_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrFwSmEmptyAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV221, CRSEM_SERV221_CMD_FPM_POWER_ENABLE, 0, crCmdType, CRSEM_SERV221_CMD_FPM_POWER_ENABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ221CmdFpmPowerEnableUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV221, CRSEM_SERV221_CMD_FPM_POWER_DISABLE, 0, crCmdType, CRSEM_SERV221_CMD_FPM_POWER_DISABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ221CmdFpmPowerDisableUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV222, CRSEM_SERV222_CMD_DIAG_ENABLE, 0, crCmdType, CRSEM_SERV222_CMD_DIAG_ENABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrSemServ222CmdDiagEnableUpdateAction, &CrIaOutCmpDefSerialize},\ +{CRSEM_SERV222, CRSEM_SERV222_CMD_DIAG_DISABLE, 0, crCmdType, CRSEM_SERV222_CMD_DIAG_DISABLE_LENGTH, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysTrue, &CrFwSmCheckAlwaysFalse, &CrFwSmEmptyAction, &CrIaOutCmpDefSerialize}\ +} + +/** + * The total number of kinds of OutComponents supported by the application. + */ +#define CR_FW_OUTCMP_NKINDS 128 + +#endif /* CRFW_OUT_FACTORY_USER_PAR_H */ + + diff --git a/CrIa/src/CrConfigIa/CrFwOutLoaderUserPar.h b/CrIa/src/CrConfigIa/CrFwOutLoaderUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..401485a059bfd0a8925d3bebbc1200e62d90b36e --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwOutLoaderUserPar.h @@ -0,0 +1,131 @@ +/** + * @file CrFwOutLoaderUserPar.h + * @ingroup CrIaDemo + * + * User-modifiable parameters for the OutLoader component. + * + * \see CrFwOutLoader.h + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_OUTLOADER_USERPAR_H_ +#define CRFW_OUTLOADER_USERPAR_H_ + +#include "BaseCmp/CrFwInitProc.h" +#include "OutLoader/CrFwOutLoader.h" +#include "CrIaOutLoader.h" + +/** + * The function implementing the OutManager Selection Operation for the OutLoader. + * The value of this constant must be a function pointer of type: + * ::CrFwOutManagerSelect_t. + * As default value for this adaptation point, the OutLoader defines function + * ::CrFwOutLoaderDefOutManagerSelect. + * + * The OutManager Selection Operation defined in this file is the one used for the test cases + * of CrFwOutLoaderTestCases.h. + */ +#define CR_FW_OUTLOADER_OUTMANAGER_SELECT &CrIaOutLoaderGetOutManager + +/** + * The function implementing the OutManager Activation Operation for the OutLoader. + * The value of this constant must be a function pointer of type: + * ::CrFwOutManagerActivate_t. + * As default value for this adaptation point, the OutLoader defines function + * ::CrFwOutLoadDefOutManagerActivate. + * + * The OutManager Activation Operation defined in this file is the one used for the test cases + * of CrFwOutLoaderTestCases.h. + */ +#define CR_FW_OUTLOADER_OUTMANAGER_ACTIVATE &CrFwOutLoadDefOutManagerActivate + +/** + * The function implementing the Initialization Check of the OutLoader component. + * The OutLoader component is derived from the Base Component and it therefore + * inherits its Initialization Procedure (see CrFwInitProc.h). + * The initialization procedure must be configured with two actions: + * the Initialization Action and the Initiation Check. + * This constant defines the function implementing the Initialization Check + * for the the OutLoader component. + * This value of this constant must be a function pointer of type: + * FwPrAction_t. + * As default value for this adaptation point, function ::CrFwBaseCmpDefInitCheck + * defined on the Base Component may be used. + * + * The value of the constant in this file is the one used for the test cases + * of CrFwOutLoaderTestCases.h. + */ +#define CR_FW_OUTLOADER_INITCHECK &CrFwBaseCmpDefInitCheck + +/** + * The function implementing the Initialization Action of the OutLoader component. + * The OutLoader component is derived from the Base Component and it therefore + * inherits its Initialization Procedure (see CrFwInitProc.h). + * The initialization procedure must be configured with two actions: + * the Initialization Action and the Initiation Check. + * This constant defines the function implementing the Initialization Action + * for the the OutLoader component. + * This value of this constant must be a function pointer of type: + * FwPrAction_t. + * As default value for this adaptation point, function ::CrFwBaseCmpDefInitAction + * defined on the Base Component may be used. + * + * The value of the constant in this file is the one used for the test cases + * of CrFwOutLoaderTestCases.h. + */ +#define CR_FW_OUTLOADER_INITACTION &CrFwBaseCmpDefInitAction + +/** + * The function implementing the Configuration Check of the OutLoader component. + * The OutLoader component is derived from the Base Component and it therefore + * inherits its Configuration Procedure (see CrFwResetProc.h). + * The configuration procedure must be configured with two actions: + * the Configuration Action and the Configuration Check. + * This constant defines the function implementing the Configuration Check + * for the the OutLoader component. + * This value of this constant must be a function pointer of type: + * FwPrAction_t. + * As default value for this adaptation point, function ::CrFwBaseCmpDefConfigCheck + * defined on the Base Component may be used. + * + * The value of the constant in this file is the one used for the test cases + * of CrFwOutLoaderTestCases.h. + */ +#define CR_FW_OUTLOADER_CONFIGCHECK &CrFwBaseCmpDefConfigCheck + +/** + * The function implementing the Configuration Action of the OutLoader component. + * The OutLoader component is derived from the Base Component and it therefore + * inherits its Configuration Procedure (see CrFwResetProc.h). + * The configuration procedure must be configured with two actions: + * the Configuration Action and the Configuration Check. + * This constant defines the function implementing the Configuration Action + * for the the OutLoader component. + * This value of this constant must be a function pointer of type: + * FwPrAction_t. + * As default value for this adaptation point, function ::CrFwBaseCmpDefConfigAction + * defined on the Base Component may be used. + * + * The value of the constant in this file is the one used for the test cases + * of CrFwOutLoaderTestCases.h. + */ +#define CR_FW_OUTLOADER_CONFIGACTION &CrFwBaseCmpDefConfigAction + +/** + * The function implementing the Shutdown Action of the OutLoader component. + * The OutLoader component is derived from the Base Component and it therefore + * inherits its Shutdown Action (see CrFwBaseCmp.h). + * This constant defines the shutdown function for the the OutLoader component. + * The value of this constant must be a function pointer of type: + * FwSmAction_t. + * As default value for this adaptation point, function ::CrFwBaseCmpDefShutdownAction + * defined on the Base Component may be used. + * + * The value of the constant in this file is the one used for the test cases + * of CrFwOutLoaderTestCases.h. + */ +#define CR_FW_OUTLOADER_SHUTDOWNACTION &CrFwBaseCmpDefShutdownAction + +#endif /* CRFW_OUTLOADER_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwOutManagerUserPar.h b/CrIa/src/CrConfigIa/CrFwOutManagerUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..cdb51375b08b52ca27c4f661ff963e0638a19267 --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwOutManagerUserPar.h @@ -0,0 +1,40 @@ +/** + * @file CrFwOutManagerUserPar.h + * @ingroup CrIaDemo + * + * User-modifiable parameters for the OutManager components of the IASW + * Application. + * + * \see CrFwOutManager.h + * + * The parameters defined in this file determine the configuration of the + * OutManager Components. + * + * The value of these parameters cannot be changed dynamically. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_OUTMANAGER_USERPAR_H_ +#define CRFW_OUTMANAGER_USERPAR_H_ + +/** + * The number of OutManager components in the application. + * The value of this constant must be smaller than the range of the ::CrFwCounterU1_t + * integer type. + */ +#define CR_FW_NOF_OUTMANAGER 3 + +/** + * The sizes of the Pending OutComponent List (POCL) of the OutManager + * components. Each OutManager has one POCL. + * + * This constant defines the size of the POCL of the i-th OutManager. The size + * of a POCL must be a positive integer (i.e. it is not legal to define a + * zero-size POCL) in the range of the ::CrFwCounterU2_t type. + */ + +#define CR_FW_OUTMANAGER_POCLSIZE {74, 10, 10} /* SEM/HK/OTHER, 13:OBC/GRND: values from DD-001 issue 2.2 p31 */ + +#endif /* CRFW_OUTMANAGER_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwOutRegistryUserPar.h b/CrIa/src/CrConfigIa/CrFwOutRegistryUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..17e95cb300350198c0900841e683e1bdf705c101 --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwOutRegistryUserPar.h @@ -0,0 +1,115 @@ +/** + * @file CrFwOutRegistryUserPar.h + * @ingroup CrIaConfig + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief User-modifiable parameters for the OutRegistry component. + * + * \see CrFwOutRegistry.h + * + * This header file defines the set of services to be provided by the IASW + * Application. + * + * A service is defined in terms of the following characteristics: + * - The service type identifier + * - The service sub-type identifier + * - The range of discriminant values for that service type and sub-type + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef CRFW_OUTREGISTRY_USERPAR_H_ +#define CRFW_OUTREGISTRY_USERPAR_H_ + +/** + * The maximum number of commands or reports which can be tracked by the + * OutRegistry. + * + * This constant must be smaller than the range of CrFwTrackingIndex_t. + */ +#define CR_FW_OUTREGISTRY_N 10 /* value taken from DD-001, issue 2.2, p31 */ + +/** + * The total number of out-going service types/sub-types offered by the + * application. + * + * An application supports a number of service types and, for each service + * type, it supports a number of sub-types. + * + * This constant defines the total number of [service type, service sub-type] + * pairs supported by the application. + * + * This constant must be smaller than the range of CrFwCmdRepIndex_t. + */ +#define CR_FW_OUTREGISTRY_NSERV 35 + +/** + * Definition of the range of out-going services supported by the application. + * + * An application supports a number of service types and, for each service + * type, it supports a number of sub-types. Each sub-type may support a range + * of discriminant values. + * + * Each line must conform to the type CrFwServDesc_t. + * + * \see CrFwServDesc_t + * + * The list of service descriptors must satisfy the following constraints: + * - The number of lines must be the same as CR_FW_OUTREGISTRY_NSERV. + * - The service types must be listed in increasing order. + * - The service sub-types within a service type must be listed in increasing order. + * - The set of service type and sub-types must be consistent with the service + * types and sub-types declared in the CR_FW_OUTCMP_INIT_KIND_DESC + * initializer. + * + * Compliance with the last three constraints is checked by + * CrFwAuxOutRegistryConfigCheck. + */ +#define CR_FW_OUTREGISTRY_INIT_SERV_DESC \ + {\ + { 1, 1, 0, 0, 1, 1, NULL},\ + { 1, 2, 0, 0, 1, 1, NULL},\ + { 1, 3, 0, 0, 1, 1, NULL},\ + { 1, 4, 0, 0, 1, 1, NULL},\ + { 1, 7, 0, 0, 1, 1, NULL},\ + { 1, 8, 0, 0, 1, 1, NULL},\ + { 3, 5, 0, 0, 1, 1, NULL},\ + { 3, 6, 0, 0, 1, 1, NULL},\ + { 3, 25, 50, 0, 1, 1, NULL},\ + { 3, 129, 0, 0, 1, 1, NULL},\ + { 5, 1, 310, 0, 1, 1, NULL},\ + { 5, 2, 330, 0, 1, 1, NULL},\ + { 5, 3, 1504, 0, 1, 1, NULL},\ + { 5, 4, 325, 0, 1, 1, NULL},\ + { 6, 6, 0, 0, 1, 1, NULL},\ + { 9, 129, 0, 0, 1, 1, NULL},\ + { 13, 1, 0, 0, 1, 1, NULL},\ + { 13, 2, 0, 0, 1, 1, NULL},\ + { 13, 3, 0, 0, 1, 1, NULL},\ + { 13, 4, 0, 0, 1, 1, NULL},\ + { 17, 2, 0, 0, 1, 1, NULL},\ + { 21, 1, 0, 0, 1, 1, NULL},\ + { 21, 2, 0, 0, 1, 1, NULL},\ + { 195, 1, 0, 0, 1, 1, NULL},\ + { 196, 1, 0, 0, 1, 1, NULL},\ + { 197, 1, 0, 0, 1, 1, NULL},\ + { 220, 3, 0, 0, 1, 1, NULL},\ + { 220, 4, 0, 0, 1, 1, NULL},\ + { 220, 11, 0, 0, 1, 1, NULL},\ + { 221, 1, 0, 0, 1, 1, NULL},\ + { 221, 2, 0, 0, 1, 1, NULL},\ + { 221, 3, 0, 0, 1, 1, NULL},\ + { 221, 4, 0, 0, 1, 1, NULL},\ + { 222, 3, 0, 0, 1, 1, NULL},\ + { 222, 4, 0, 0, 1, 1, NULL}\ + } + +#endif /* CRFW_OUTREGISTRY_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwOutStreamUserPar.h b/CrIa/src/CrConfigIa/CrFwOutStreamUserPar.h new file mode 100644 index 0000000000000000000000000000000000000000..94267fdc5998936917e8322da19277bff96eec18 --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwOutStreamUserPar.h @@ -0,0 +1,204 @@ +/** + * @file CrFwOutStreamUserPar.h + * @ingroup CrIaDemo + * + * User-modifiable parameters for the OutStream components of the IASW + * Application. + * + * \see CrFwOutStream.h + * + * The parameters defined in this file determine the configuration of the + * OutStream Components. + * + * The value of these parameters cannot be changed dynamically. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_OUTSTREAM_USERPAR_H_ +#define CRFW_OUTSTREAM_USERPAR_H_ + +/* Incudes */ +#include <CrIaIasw.h> + +#include <CrFwConstants.h> +#include <BaseCmp/CrFwResetProc.h> +#include <OutStream/CrFwOutStream.h> + +/** + * The number of OutStream components in the application. + * + * Normally, an application should instantiate one OutStream component for each + * destination to which a report or a command may be sent. + * + * The value of this constant must be smaller than the range of the + * <code>::CrFwCounterU1_t</code> integer type. + */ +#define CR_FW_NOF_OUTSTREAM 3 + +/** + * The sizes of the packet queues in the OutStream component. + * Each OutStream has one packet queue. + * This constant defines the size of the packet queue of the i-th OutStream. + * The size of the packet queue represents the maximum number of packets which + * may remain pending in the packet queue. + * The size of a packet queue must be a positive integer (i.e. it is not legal + * to define a zero-size packet queue). + * + * The packet sizes defined in this file are those used for the IASW + * Application. + */ +#define CR_FW_OUTSTREAM_PQSIZE {6,15,150} /* values from DD-001 issue 2.2 p31 */ + +/** + * The destinations of the OutStream components. + * + * The destination of an OutStream is the middleware node to which the + * OutStream sends its packet. + * + * Each OutStream has one (and only one) destination associated to it. A + * destination is defined by a non-negative integer. This array defines the + * destination of the i-th OutStream. + * + * The destinations defined in this file are those used for the IASW + * Application. + */ +#define CR_FW_OUTSTREAM_DEST {CR_FW_CLIENT_SEM, \ + CR_FW_CLIENT_OBC, \ + CR_FW_CLIENT_GRD} + +/** + * The number of groups of the OutStream components. This is positive number and + * defines the number of groups of the i-th OutStream. + * + * The number of groups defined in this file are those used for the IASW + * Application. + */ +#define CR_FW_OUTSTREAM_NOF_GROUPS {4,4,4} +/*#define CR_FW_OUTSTREAM_NOF_GROUPS {12,12,12,12}*/ + +/** + * The functions implementing the packet hand-over operations of the OutStream components. + * Each OutStream component needs to be able to hand-over a packet to the middleware. + * The function implementing this packet hand-over operation is one of the + * adaptation points of the framework. + * This array defines the packet hand-over operations for the OutStream. + * The items in the arrays must be function pointers of type: + * <code>::CrFwPcktHandover_t</code>. + * No default is defined at framework level for this function. + */ +#define CR_FW_OUTSTREAM_PCKTHANDOVER {&CrIbSemPcktHandoverPrepare, \ + &CrIbMilBusPcktHandoverPrepare, \ + &CrIbMilBusPcktHandoverPrepare} + +/** + * The functions implementing the Initialization Check of the OutStream + * components. + * + * The OutStream components are derived from the Base Component and they + * therefore inherit its Initialization Procedure. + * + * \see CrFwInitProc.h + * + * The initialization procedure must be configured with two actions. + * - The Initiation Check + * - The Initialization Action + * + * The items in the array must be function pointers of type FwPrAction_t. + * + * For the IASW application, no Initialization Check is required for the + * OutStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_OUTSTREAM_INITCHECK {&CrFwBaseCmpDefInitCheck, \ + &CrFwBaseCmpDefInitCheck, \ + &CrFwBaseCmpDefInitCheck} + +/** + * The functions implementing the Initialization Action of the OutStream + * components. + * + * The OutStream components are derived from the Base Component and they + * therefore inherit its Initialization Procedure. + * + * \see CrFwInitProc.h + * + * The initialization procedure must be configured with two actions. + * - The Initiation Check + * - The Initialization Action + * + * The items in the array must be function pointers of type FwPrAction_t + * + * For the IASW application, no Initialization Action is required for the + * OutStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_OUTSTREAM_INITACTION {&CrFwOutStreamDefInitAction, \ + &CrFwOutStreamDefInitAction, \ + &CrFwOutStreamDefInitAction} + +/** + * The functions implementing the Configuration Check of the OutStream + * components. + * + * The OutStream components are derived from the Base Component and they + * therefore inherit its Reset Procedure. + * + * \see CrFwResetProc.h + * + * The reset procedure must be configured with two actions + * - The Configuration Action + * - The Configuration Check + * + * The items in the array must be function pointers of type FwPrAction_t. + * + * For the IASW application, no Configuration Check is required for the + * OutStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_OUTSTREAM_CONFIGCHECK {&CrFwBaseCmpDefConfigCheck, \ + &CrFwBaseCmpDefConfigCheck, \ + &CrFwBaseCmpDefConfigCheck} + +/** + * The functions implementing the Configuration Action of the OutStream + * components. + * + * The OutStream components are derived from the Base Component and they + * therefore inherit its Reset Procedure. + * + * \see CrFwResetProc.h + * + * The reset procedure must be configured with two actions + * - The Configuration Action + * - The Configuration Check + * + * The items in the array must be function pointers of type FwPrAction_t. + * + * For the IASW application, no Configuration Action is required for the + * OutStream components. Therefore, the default base implementation is used. + */ +#define CR_FW_OUTSTREAM_CONFIGACTION {&CrFwOutStreamDefConfigAction, \ + &CrFwOutStreamDefConfigAction, \ + &CrFwOutStreamDefConfigAction} + +/** + * The functions implementing the Shutdown Action of the OutStream components. + * + * The OutStream components are derived from the Base Component and they + * therefore inherit its Reset Procedure. + * + * \see CrFwBaseCmp.h + * + * The reset procedure must be configured with two actions + * - The Configuration Action + * - The Configuration Check + * + * The items in the array must be function pointers of type FwSmAction_t. + * + * For the IASW application, no Shutdown Action is required for the OutStream + * components. Therefore, the default base implementation is used. + */ +#define CR_FW_OUTSTREAM_SHUTDOWNACTION {&CrFwOutStreamDefShutdownAction, \ + &CrFwOutStreamDefShutdownAction, \ + &CrFwOutStreamDefShutdownAction} + +#endif /* CRFW_OUTSTREAM_USERPAR_H_ */ diff --git a/CrIa/src/CrConfigIa/CrFwUserConstants.h b/CrIa/src/CrConfigIa/CrFwUserConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..2d5f74c78a2fdec1f7cbc22d75b8ca31ccaa845b --- /dev/null +++ b/CrIa/src/CrConfigIa/CrFwUserConstants.h @@ -0,0 +1,279 @@ +/** + * @file CrFwUserConstants.h + * @ingroup CrIaConfig + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Header file to define all user-configurable constants and types for the IASW + * Application. + * + * The content of this file is taken over unchanged from the framework-provided + * default with the exception of the following items: + * + * - The value of the application identifier (20 for the IASW). + * - The maximum value of the service type, sub-type and discriminant + * attributes + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRFW_USERCONSTANTS_H_ +#define CRFW_USERCONSTANTS_H_ + +/** Macro to suppress warnings about unused parameters */ +#define CRIA_UNUSED(x) (void)(x); + +/* in/out report values */ +#define CRIA_SUCCESS 1 +#define CRIA_FAILURE 0 + +/* PCAT values */ +#define CR_FW_PCAT_SEM_TC 0x0C +#define CR_FW_PCAT_SEM_TM 0x01 + +#define CR_FW_PCAT_DPU_TC 0x0C +#define CR_FW_PCAT_DPU_TM_OTHER 0x02 +#define CR_FW_PCAT_DPU_TM_SERV1_5_6 0x01 +#define CR_FW_PCAT_DPU_TM_SERV13 0x04 +#define CR_FW_PCAT_DPU_TM_SERV196 0x03 + + +/** Type used for instance identifiers. */ +typedef unsigned int CrFwInstanceId_t; + +/** Type used for the identifier of a component type. */ +typedef unsigned short int CrFwTypeId_t; + +/** Type used for the outcome of a check (see <code>::CrFwCmpData</code>). */ +typedef unsigned char CrFwOutcome_t; + +/** Type used for the sequence counter of commands or reports. */ +typedef unsigned short int CrFwSeqCnt_t; + +/** Type used for the time stamp of a command or report. */ +typedef struct CrFwTimeStamp { unsigned char t[6]; } CrFwTimeStamp_t; + +/** Type used for the service type of a command or report. */ +typedef unsigned char CrFwServType_t; + +/** Type used for the command or report sub-type. */ +typedef unsigned char CrFwServSubType_t; + +/** Type used for the destination or source group of a packet. */ +typedef unsigned char CrFwGroup_t; + +/** Type used for the command or report destination and source. */ +typedef unsigned char CrFwDestSrc_t; + +/** Type used for the discriminant of a command or report. */ +typedef unsigned short CrFwDiscriminant_t; + +/** Type for the index used to track the state of a component. */ +typedef unsigned short CrFwTrackingIndex_t; + +/** Type for the index of a command or report kind. */ +typedef unsigned short CrFwCmdRepKindIndex_t; + +/** Type for the component kind key in <code>CrFwInFactory.c</code> and <code>CrFwOutFactory.c</code>. */ +typedef unsigned int CrFwCmdRepKindKey_t; + +/** + * Type for the index in the pool of pre-allocated OutComponents in + * the OutFactory (see <code>CrFwOutFactory.h</code>). + */ +typedef unsigned char CrFwOutFactoryPoolIndex_t; + +/** + * Type for the index in the pool of pre-allocated incoming components in + * the InFactory (see <code>CrFwInFactory.h</code>). + */ +typedef unsigned char CrFwInFactoryPoolIndex_t; + +/** Type used for unsigned integers with a "short" range. */ +typedef unsigned char CrFwCounterU1_t; + +/** Type used for signed integers with a "short" range. */ +typedef signed char CrFwCounterS1_t; + +/** Type used for unsigned integers with a "medium" range. */ +typedef unsigned short CrFwCounterU2_t; + +/** Type for the packet length. */ +typedef unsigned short int CrFwPcktLength_t; + +/** Type for the TM/TC version number. The length of the version is 3 bits. */ +typedef unsigned char CrIaPcktVersion_t; + +/** + * Type for the TC sequence flags and TM segmentation flags. The length of the + * flags is 2 bits. + */ +typedef unsigned char CrIaPcktSeqFlags_t; + +/** Type for the TM/TC crc. The length of the crc is 16bits. */ +typedef unsigned short CrIaPcktCrc_t; + +/** + * Identifier for the errors reported through the error reporting interface of <code>CrFwRepErr.h</code>. + * When a framework component encounters a non-nominal situation during its normal operation, + * it reports it as an error using the services defined by the <code>CrFwRepErr.h</code> + * interface. + * Each error situation is characterized by an error code. + * This enumerated type defines all the error codes. + */ +typedef enum { + /** The packet queue of an OutStream is full (see <code>CrFwOutStream.h</code>) */ + crOutStreamPQFull =2, + /** The packet queue of an InStream is full (see <code>CrFwInStream.h</code>) */ + crInStreamPQFull =3, + /** An InStream has encountered a sequence counter error (see <code>CrFwInStream.h</code>) */ + crInStreamSCErr =4, + /** An OutComponent has an invalid destination (see <code>CrFwOutCmp.h</code>) */ + crOutCmpSendPcktInvDest =5, + /** The Pending OutComponent List (POCL) of an OutManager is full (see <code>CrFwOutManager.h</code>) */ + crOutManagerPoclFull =6, + /** The Pending Command/Report List (PCRL) of an InManager is full (see <code>CrFwInManager.h</code>) */ + crInManagerPcrlFull =7, + /** The InLoader has retrieved a packet with an invalid destination (see <code>CrFwInLoader.h</code>) */ + crInLoaderInvDest = 8, + /** An InReport or InCommand has failed its acceptance check */ + crInLoaderAccFail = 9, + /** An OutComponent has an illegal group */ + crOutStreamIllGroup = 10, + /** An incoming command or report has an illegal group */ + crInStreamIllGroup = 11, + /** An outgoing packet cannot be created **/ + crOutStreamNoMorePckt = 12, + /** An InReport cannot be created **/ + crInLoaderCreFail = 13, + /** An InReport cannot be loaded **/ + crInLoaderLdFail = 14 +} CrFwRepErrCode_t; + +/** + * Application error code for the framework components. + * An application error is declared when a framework function has been called by the + * application code with an illegal parameter values or in an illegal context and execution + * of the function with the illegal values would cause an internal framework data structure + * to be corrupted. + * + * Nominally, the application error code should be equal to: <code>::crNoAppErr</code>. + * If the application error code has a different value, then an application error has been + * encountered. + * If multiple errors have been encountered, the application error code reflects the + * most recent error. + */ +typedef enum { + /** No application errors have been detected. */ + crNoAppErr = 0, + /** An OutStream function was called on an object which is not an OutStream. */ + crNotOutStream = 1, + /** A framework function has been called with an illegal OutStream identifier. */ + crOutStreamIllId = 2, + /** + * A framework function has been called with a destination attribute which is + * not associated to any OutStream. + */ + crOutStreamUndefDest = 3, + /** + * A framework function has been called with a source attribute which is not + * associated to any InStream. + */ + crInStreamUndefDest = 4, + /** A packet allocation request has failed (see <code>::CrFwPcktMake</code>). */ + crPcktAllocationFail = 5, + /** A packet release request has encountered an error (see <code>::CrFwPcktRelease</code>). */ + crPcktRelErr = 6, + /** An InStream function was called on an object which is not an InStream. */ + crNotInStream = 7, + /** A framework function has been called with an illegal InStream identifier. */ + crInStreamIllId = 8, + /** An OutComponent function was called on an object which is not an OutComponent. */ + crNotOutCmp = 9, + /** An OutComponent allocation request has failed (see <code>::CrFwOutFactoryMakeOutCmp</code>). */ + crOutCmpAllocationFail = 10, + /** An OutComponent release request has encountered an error (see <code>::CrFwOutFactoryReleaseOutCmp</code>). */ + crOutCmpRelErr = 11, + /** A framework function was called with an illegal service type */ + crIllServType = 12, + /** A framework function was called with an illegal service sub-type */ + crIllServSubType = 13, + /** A framework function was called with an illegal discriminant */ + crIllDiscriminant = 14, + /** A framework function was called with an illegal type/sub-type pair for an OutComponent */ + crIllOutCmpType = 15, + /** A framework function was called with an illegal type/sub-type/discriminant triplet for an OutComponent */ + crIllOutCmpKind = 16, + /** A framework function has been called with an illegal OutManager identifier. */ + crOutManagerIllId = 17, + /** A framework function was called with an illegal type/sub-type/discriminant triplet for an InCommand */ + crIllInCmdKind = 18, + /** Allocation request for a packet for an InCommand has failed (see <code>::CrFwInFactoryMakeInCmd</code>). */ + crInCmdAllocationFail = 19, + /** A framework function was called with an illegal type/sub-type/discriminant triplet for an InReport */ + crIllInRepKind = 20, + /** Allocation request for an InReport has failed (see <code>::CrFwInFactoryMakeInRep</code>). */ + crInRepAllocationFail = 21, + /** An InReport release request has encountered an error (see <code>::CrFwInFactoryReleaseInRep</code>). */ + crInRepRelErr = 22, + /** An InCommand release request has encountered an error (see <code>::CrFwInFactoryReleaseInCmd</code>). */ + crInCmdRelErr = 23, + /** A framework function has been called with an illegal InManager identifier. */ + crInManagerIllId = 24 +} CrFwAppErrCode_t; + +/** The identifier of the IASW Application. */ +#define CR_FW_HOST_APP_ID 20 + +/** + * The identifier of the On-Board Computer (OBC) software. This is a service + * client to the IASW. + */ +#define CR_FW_CLIENT_OBC 12 + +/** + * The identifier for the Ground software. This is the value that is written + * into the PUS packet and is mapped to CR_FW_CLIENT_GRD in the IASW + * application. + */ +#define CR_FW_CLIENT_GRD_PUS 0 + +/** + * The identifier of the Ground (Grd) software. This is a service client to the + * IASW. + * + * Note that the specified Id in the PUS packet for Ground is 0. However, the + * Cordet framework does not recognize 0 as a valid number. For this + * application, 1 is used instead, and it is mapped correctly in + * CrFwPcktGetDest and CrFwPcktSetDest. + */ +#define CR_FW_CLIENT_GRD 1 + +/** + * The identifier of the HK Storage. This is a dummy packet destination. It has + * a dedicated OutStream allocated it. + */ +#define CR_FW_CLIENT_HK_STRG 21 + +/** + * The identifier of the Sensor Module (SEM) software. This is a service + * provider to the IASW. + */ +#define CR_FW_CLIENT_SEM 60 + +/** The number of bits reserved for the application identifier in a command or report identifier */ +#define CR_FW_NBITS_APP_ID 4 + +/** Maximum value of the service type attribute of InReports and InCommands for the IASW Application */ +#define CR_FW_MAX_SERV_TYPE 250 /* given the data type used, this is the maximum allowed value */ + +/** Maximum value of the service sub-type attribute of InReports and InCommands for the IASW Application */ +#define CR_FW_MAX_SERV_SUBTYPE 250 /* given the data type used, this is the maximum allowed value */ + +/** Maximum value of the discriminant attribute of InReports and InCommands for the IASW Application */ +#define CR_FW_MAX_DISCRIMINANT 65534 /* given the data type used, this is the maximum allowed value */ + +/** The number of framework components */ +#define CR_IA_NOF_FW_CMP 11 + +#endif /* CRFW_USERCONSTANTS_H_ */ diff --git a/CrIa/src/CrConfigIa/genOutReg.sh b/CrIa/src/CrConfigIa/genOutReg.sh new file mode 100755 index 0000000000000000000000000000000000000000..b0e26bac696de22d4f0746033b891d07f32e90a0 --- /dev/null +++ b/CrIa/src/CrConfigIa/genOutReg.sh @@ -0,0 +1,20 @@ +#!/bin/bash + + +FACTORY=`cat CrFwOutFactoryUserPar.h | sed -n "/CR_FW_OUTCMP_INIT_KIND_DESC/,/define/p" | awk -F "," '/{/{print $1, $2, $3}' | sed 1d | tr -d "{"` + + +function ersetze () +{ + tt=$1 + if [[ ${tt:0:2} == "CR" ]] + then + grep -R $tt ../ 2>/dev/null | awk -F "define" '/define/{print $2}' | awk -v m=$tt '{if ($1 == m) {print $2}}' + else + echo $tt + fi +} + +for i in $FACTORY; do ersetze $i; done | awk '{a=$0; getline b; getline c; print "\t\t\t{ " a ",\t" b ",\t" c ",\t 0, 1, 1, NULL},\\"}' + + diff --git a/CrIa/src/CrFwRepErr.c b/CrIa/src/CrFwRepErr.c new file mode 100644 index 0000000000000000000000000000000000000000..6c370b0513b24b5a7ec189c55f7beeaeed77c402 --- /dev/null +++ b/CrIa/src/CrFwRepErr.c @@ -0,0 +1,234 @@ +/** + * @file CrFwRepErr.c + * @ingroup CrIaDemo + * + * Implementation of the error reporting interface for the IASW Demo + * Application. + * + * \see CrFwRepErr.h + * + * This implementation writes the error reports to standard output. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#include <CrFramework/CrFwConstants.h> +#include <CrFramework/CrFwRepErr.h> + +#include <InRep/CrFwInRep.h> /* for CrFwInRepGetSeqCnt() */ +#include <InManager/CrFwInManager.h> /* for CrFwInManagerMake() */ + +#include <Services/General/CrIaConstants.h> +#include <CrIaIasw.h> +#include <CrIaPckt.h> +#include <CrFwUserConstants.h> + +#include <IfswUtilities.h> /* for SendTcAccRepFail() */ +#include <IfswDebug.h> + +unsigned short evt_data[2] = {0, 0}; + +/* high/low is arbitrary, med is because of definitions in OutFactoryUserPar */ + +static void do_report(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId) +{ + unsigned short tcFailureCode; + + CRFW_UNUSED(tcFailureCode); + + DEBUGP("CrFwRepErr: do_report: errCode = %d\n", errCode); + + /* see IASW ADD section 6.10 */ + switch (errCode) + { + /* --- LOW_SEV ERRORs ----------------------------------------------------------------------- */ + case crInStreamSCErr: + CrIaEvtRep(CRIA_SERV5_EVT_ERR_LOW_SEV, CRIA_SERV5_EVT_SEQ_CNT_ERR, evt_data, 4); + break; + + + /* --- MED_SEV ERRORs ----------------------------------------------------------------------- */ + case crInLoaderAccFail: + /* NOTE: if acceptance check fails for TC in-coming packets */ + DEBUGP("CrFwRepErr: crInLoaderAccFail - CMD: outcome = %d, typeId = %d, instanceId = %d\n", evt_data[1], typeId, instanceId); + tcFailureCode = ACK_CREATE_FAIL; + SendTcAccRepFail(NULL, tcFailureCode); + break; + + case crInLoaderCreFail: + break; + + case crInLoaderLdFail: + /* NOTE: for InRep this is handled by CrFwRepErrRep */ + break; + + case crInManagerPcrlFull: + /* NOTE: for InRep this is handled by CrFwRepErrRep */ + break; + + case crInLoaderInvDest: + /* NOTE: An event TM(5,3) will be generated also in case of wrong APID which deviates from the definition + in ECSS-E-70-41A: TM(1,2) with error code 0 = illegal APID (PAC error) */ + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INV_DEST, evt_data, 4); + break; + + case crInStreamPQFull: + evt_data[1] = instanceId; /* set InStream ID as data */ + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INSTRM_PQF, evt_data, 4); + break; + + case crOutCmpSendPcktInvDest: + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OCMP_INVD, evt_data, 4); + break; + + case crOutStreamIllGroup: + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OCMP_ILLGR, evt_data, 4); + break; + + case crInStreamIllGroup: + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_IN_ILLGR, evt_data, 4); + break; + + + /* --- HIGH_SEV ERRORs ----------------------------------------------------------------------- */ + + + + /* --- ENTRY in ERROR LOG -------------------------------------------------------------------- */ + case crOutStreamPQFull: + /* Entry in Error Log with ID ERR_OUTSTREAM_PQ_FULL and OutStream ID as data */ + evt_data[0] = instanceId; /* set OutStream ID as data */ + CrIaErrRep(CRIA_SERV5_EVT_ERR_HIGH_SEV, ERR_OUTSTREAM_PQ_FULL, evt_data, 4); + break; + + case crOutManagerPoclFull: + /* Entry in Error Log with ID ERR_POCL_FULL and POCL ID as data */ + evt_data[0] = instanceId; /* set OutStream ID as data */ + CrIaErrRep(CRIA_SERV5_EVT_ERR_HIGH_SEV, ERR_POCL_FULL, evt_data, 4); + break; + + case crOutStreamNoMorePckt: + /* Entry in Error Log with ID ERR_OUTSTREAM_NO_PCKT and OutStream ID as data */ + evt_data[0] = instanceId; /* set OutStream ID as data */ + CrIaErrRep(CRIA_SERV5_EVT_ERR_HIGH_SEV, ERR_OUTCMP_NO_MORE_PCKT, evt_data, 4); + break; + } + + return; +} + +void CrFwRepErr(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId) +{ + do_report(errCode, typeId, instanceId); + + DEBUGP("CrFwRepErr: CrFwRepErr\n"); + + return; +} + +void CrFwRepErrDestSrc(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, CrFwDestSrc_t destSrc) +{ + evt_data[0] = (unsigned short)(instanceId & 0xFFFF); /* NOTE: instanceId is truncated to 16 bit */ + evt_data[1] = destSrc; + + DEBUGP("CrFwRepErr: CrFwRepErrDestSrc\n"); + + do_report(errCode, typeId, instanceId); + + return; +} + +void CrFwRepErrGroup(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, CrFwGroup_t group) +{ + evt_data[0] = (unsigned short)(instanceId & 0xFFFF); /* NOTE: instanceId is truncated to 16 bit */ + evt_data[1] = group; + + DEBUGP("CrFwRepErr: CrFwRepErrGroup\n"); + + do_report(errCode, typeId, instanceId); + + return; +} + +void CrFwRepErrSeqCnt(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, CrFwSeqCnt_t expSeqCnt, CrFwSeqCnt_t actSeqCnt) +{ + evt_data[0] = expSeqCnt; + evt_data[1] = actSeqCnt; + + DEBUGP("CrFwRepErr: CrFwRepErrSeqCnt\n"); + + if (expSeqCnt != 16384) /* exclude report, when SSC from SEM wraps around, because the counter only uses 14 bits */ + do_report(errCode, typeId, instanceId); + + return; +} + +void CrFwRepErrInstanceIdAndOutcome(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, CrFwInstanceId_t secondaryInstanceId, CrFwOutcome_t outcome) +{ + evt_data[0] = (unsigned short)(secondaryInstanceId & 0xFFFF); /* NOTE: secondaryInstanceId is truncated to 16 bit */ + evt_data[1] = outcome; + + DEBUGP("CrFwRepErr: CrFwRepErrInstanceIdAndOutcome\n"); + + do_report(errCode, typeId, instanceId); + + return; +} + +void CrFwRepErrInstanceIdAndDest(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, CrFwInstanceId_t instanceId, CrFwInstanceId_t secondaryInstanceId, CrFwDestSrc_t dest) +{ + evt_data[0] = (unsigned short)(secondaryInstanceId & 0xFFFF); /* NOTE: secondaryInstanceId is truncated to 16 bit */ + evt_data[1] = dest; + + DEBUGP("CrFwRepErr: CrFwRepErrInstanceIdAndDest\n"); + + do_report(errCode, typeId, instanceId); + + return; +} + +void CrFwRepErrPckt(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, + CrFwInstanceId_t instanceId, CrFwPckt_t pckt) +{ + CrFwSeqCnt_t ssc; + + CRFW_UNUSED(errCode); + CRFW_UNUSED(typeId); + CRFW_UNUSED(instanceId); + + DEBUGP("CrFwRepErr: CrFwRepErrPckt\n"); + + ssc = CrFwPcktGetSeqCnt(pckt); + /* load source sequence counter ssc into evt_data */ + evt_data[0] = ssc; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INREP_CR_FAIL, evt_data, 4); + + return; +} + +void CrFwRepErrRep(CrFwRepErrCode_t errCode, CrFwTypeId_t typeId, + CrFwInstanceId_t instanceId, FwSmDesc_t rep) +{ + CrFwSeqCnt_t ssc; + + CRFW_UNUSED(typeId); + CRFW_UNUSED(instanceId); + + DEBUGP("CrFwRepErr: CrFwRepErrRep\n"); + + ssc = CrFwInRepGetSeqCnt(rep); + /* load source sequence counter ssc into evt_data */ + evt_data[0] = ssc; + if (errCode == crInLoaderLdFail) + { + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_PCRL2_FULL, evt_data, 4); + } + else + { + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INREP_CR_FAIL, evt_data, 4); + } + + return; +} + diff --git a/CrIa/src/CrFwRepInCmdOutcome.c b/CrIa/src/CrFwRepInCmdOutcome.c new file mode 100644 index 0000000000000000000000000000000000000000..a5f42de18460c87adc74194a874404cb979973f3 --- /dev/null +++ b/CrIa/src/CrFwRepInCmdOutcome.c @@ -0,0 +1,115 @@ +#include "IfswDebug.h" +/** + * @file CrFwRepInCmdOutcome.c + * @ingroup CrIaDemo + * + * Implementation of the error reporting interface of the IASW Application. + * + * \see CrFwRepErr.h + * + * This implementation writes the InCommand Outcome Reports to standard output. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#include <stdlib.h> +#include <string.h> + +/* Include Framework Files */ +#include "CrFwConstants.h" +#include "CrFwRepInCmdOutcome.h" +#include <CrConfigIa/CrFwUserConstants.h> +#include <FwProfile/FwSmConfig.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> + +#include <IfswUtilities.h> +#include <Services/General/CrIaConstants.h> + + +/*-----------------------------------------------------------------------------------------*/ +void CrFwRepInCmdOutcomeCreFail(CrFwRepInCmdOutcome_t outcome, CrFwOutcome_t failCode, CrFwPckt_t pckt) +{ + CRFW_UNUSED(failCode); + + switch (outcome) + { + case crCmdAckCreFail: + DEBUGP("CrFwRepInCmdOutcomeCreFail: InCmd had invalid type or no more resources are available\n"); + SendTcAccRepFail(pckt, ACK_CREATE_FAIL); + break; + + default: + break; + } + + return; +} + +void CrFwRepInCmdOutcome(CrFwRepInCmdOutcome_t outcome, CrFwInstanceId_t instanceId, CrFwServType_t servType, + CrFwServSubType_t servSubType, CrFwDiscriminant_t disc, CrFwOutcome_t failCode, FwSmDesc_t inCmd) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(inCmd); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + CRFW_UNUSED(pckt); + + if (failCode != 0) + { + + DEBUGP("CrFwRepInCmdOutcome: unexpected outcome report for InCommand %d, service type %d,\n",instanceId,servType); + DEBUGP(" service sub-type %d, and discriminant %d\n",servSubType,disc); + DEBUGP(" FAILURE CODE: %d\n", failCode); + + switch (outcome) + { + + case crCmdAckAccFail: + DEBUGP("crCmdAckAccFail: Failure Code: %d, Outcome: %d, Instance ID: %d, inCmd: %d\n", failCode, outcome, instanceId, (unsigned int)inCmd); + break; + + case crCmdAckStrFail: + DEBUGP("crCmdAckStrFail: Failure Code: %d, Outcome: %d, Instance ID: %d, inCmd: %d\n", failCode, outcome, instanceId, (unsigned int)inCmd); + break; + + case crCmdAckPrgFail: + DEBUGP("crCmdAckPrgFail: Failure Code: %d, Outcome: %d, Instance ID: %d, inCmd: %d\n", failCode, outcome, instanceId, (unsigned int)inCmd); + break; + + case crCmdAckTrmFail: + DEBUGP("crCmdAckTrmFail: Failure Code: %d, Outcome: %d, Instance ID: %d, inCmd: %d\n", failCode, outcome, instanceId, (unsigned int)inCmd); + break; + + default: + DEBUGP("crCmdAck: else (outcome = %d)\n", outcome); + break; + + } + } + + else /* failCode == 0 */ + { + + switch (outcome) + { + + case crCmdAckLdFail: + DEBUGP("crCmdAckLdFail: Serv(%d, %d), Failure Code: %d, Outcome: %d, Instance ID: %d, inCmd: %d\n", servType, servSubType, failCode, outcome, instanceId, (unsigned int)inCmd); + SendTcAccRepFail(pckt, ACK_PCRL1_FULL); + break; + + default: + /* no error */ + break; + } + + } + + return; +} diff --git a/CrIa/src/CrIaDataPool.c b/CrIa/src/CrIaDataPool.c new file mode 100644 index 0000000000000000000000000000000000000000..e662c0208943099d62fed4faa9a7b643d3f0f80b --- /dev/null +++ b/CrIa/src/CrIaDataPool.c @@ -0,0 +1,7988 @@ +#include "CrIaDataPool.h" +#include "CrIaDataPoolId.h" +#include <string.h> + +#ifndef ISOLATED +#include <InFactory/CrFwInFactory.h> +#include <OutFactory/CrFwOutFactory.h> +#include <InManager/CrFwInManager.h> +#include <OutManager/CrFwOutManager.h> +#include <InStream/CrFwInStream.h> +#include <OutStream/CrFwOutStream.h> +#include <InCmd/CrFwInCmd.h> +#include <InRep/CrFwInRep.h> +#include <FwProfile/FwPrCore.h> /* for FwPrGetCurNode() */ + +#include <CrIaIasw.h> +#include "IfswDebug.h" +#else +#include <stdio.h> +#define x_printf printf +#endif + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +unsigned int useMaxAcquisitionNum = 1; /* Mantis 2168 */ + +/** Initialization of the structure holding of data pool variables and parameter items for CORDET. */ +#ifdef PC_TARGET +struct DataPoolCordet dpCordet; +struct DataPoolCordet dpCordetInit = { +#else +struct DataPoolCordet dpCordet = { +#endif /* PC_TARGET */ + /* ID: 2, value: 0, name: AppErrCode, multiplicity: 1 */ + 0, + /* ID: 3, value: 0, name: NofAllocatedInRep, multiplicity: 1 */ + 0, + /* ID: 4, value: 0, name: MaxNOfInRep, multiplicity: 1 */ + 0, + /* ID: 5, value: 0, name: NofAllocatedInCmd, multiplicity: 1 */ + 0, + /* ID: 6, value: 0, name: MaxNOfInCmd, multiplicity: 1 */ + 0, + /* ID: 7, value: 0, name: Sem_NOfPendingInCmp, multiplicity: 1 */ + 0, + /* ID: 8, value: 0, name: Sem_PCRLSize, multiplicity: 1 */ + 0, + /* ID: 9, value: 0, name: Sem_NOfLoadedInCmp, multiplicity: 1 */ + 0, + /* ID: 10, value: 0, name: GrdObc_NOfPendingInCmp, multiplicity: 1 */ + 0, + /* ID: 11, value: 0, name: GrdObc_PCRLSize, multiplicity: 1 */ + 0, + /* ID: 12, value: 0, name: NOfAllocatedOutCmp, multiplicity: 1 */ + 0, + /* ID: 13, value: 0, name: MaxNOfOutCmp, multiplicity: 1 */ + 0, + /* ID: 14, value: 0, name: NOfInstanceId, multiplicity: 1 */ + 0, + /* ID: 15, value: 0, name: OutMg1_NOfPendingOutCmp, multiplicity: 1 */ + 0, + /* ID: 16, value: 0, name: OutMg1_POCLSize, multiplicity: 1 */ + 0, + /* ID: 17, value: 0, name: OutMg1_NOfLoadedOutCmp, multiplicity: 1 */ + 0, + /* ID: 18, value: 0, name: OutMg2_NOfPendingOutCmp, multiplicity: 1 */ + 0, + /* ID: 19, value: 0, name: OutMg2_POCLSize, multiplicity: 1 */ + 0, + /* ID: 20, value: 0, name: OutMg2_NOfLoadedOutCmp, multiplicity: 1 */ + 0, + /* ID: 21, value: 0, name: OutMg3_NOfPendingOutCmp, multiplicity: 1 */ + 0, + /* ID: 22, value: 0, name: OutMg3_POCLSize, multiplicity: 1 */ + 0, + /* ID: 23, value: 0, name: OutMg3_NOfLoadedOutCmp, multiplicity: 1 */ + 0, + /* ID: 24, value: 0, name: InSem_SeqCnt, multiplicity: 1 */ + 0, + /* ID: 25, value: 0, name: InSem_NOfPendingPckts, multiplicity: 1 */ + 0, + /* ID: 26, value: 0, name: InSem_NOfGroups, multiplicity: 1 */ + 0, + /* ID: 27, value: 0, name: InSem_PcktQueueSize, multiplicity: 1 */ + 0, + /* ID: 28, value: 0, name: InSem_Src, multiplicity: 1 */ + 0, + /* ID: 29, value: 0, name: InObc_NOfPendingPckts, multiplicity: 1 */ + 0, + /* ID: 30, value: 0, name: InObc_NOfGroups, multiplicity: 1 */ + 0, + /* ID: 31, value: 0, name: InObc_PcktQueueSize, multiplicity: 1 */ + 0, + /* ID: 32, value: 0, name: InObc_Src, multiplicity: 1 */ + 0, + /* ID: 33, value: 0, name: InGrd_NOfPendingPckts, multiplicity: 1 */ + 0, + /* ID: 34, value: 0, name: InGrd_NOfGroups, multiplicity: 1 */ + 0, + /* ID: 35, value: 0, name: InGrd_PcktQueueSize, multiplicity: 1 */ + 0, + /* ID: 36, value: 0, name: InGrd_Src, multiplicity: 1 */ + 0, + /* ID: 37, value: 0, name: OutSem_Dest, multiplicity: 1 */ + 0, + /* ID: 38, value: 0, name: OutSem_SeqCnt, multiplicity: 1 */ + 0, + /* ID: 39, value: 0, name: OutSem_NOfPendingPckts, multiplicity: 1 */ + 0, + /* ID: 40, value: 0, name: OutSem_NOfGroups, multiplicity: 1 */ + 0, + /* ID: 41, value: 0, name: OutSem_PcktQueueSize, multiplicity: 1 */ + 0, + /* ID: 42, value: 0, name: OutObc_Dest, multiplicity: 1 */ + 0, + /* ID: 43, value: 0, name: OutObc_SeqCnt_Group0, multiplicity: 1 */ + 0, + /* ID: 44, value: 0, name: OutObc_SeqCnt_Group1, multiplicity: 1 */ + 0, + /* ID: 45, value: 0, name: OutObc_NOfPendingPckts, multiplicity: 1 */ + 0, + /* ID: 46, value: 0, name: OutObc_NOfGroups, multiplicity: 1 */ + 0, + /* ID: 47, value: 0, name: OutObc_PcktQueueSize, multiplicity: 1 */ + 0, + /* ID: 48, value: 0, name: OutGrd_Dest, multiplicity: 1 */ + 0, + /* ID: 49, value: 0, name: OutGrd_SeqCnt_Group0, multiplicity: 1 */ + 0, + /* ID: 50, value: 0, name: OutGrd_SeqCnt_Group1, multiplicity: 1 */ + 0, + /* ID: 51, value: 0, name: OutGrd_SeqCnt_Group2, multiplicity: 1 */ + 0, + /* ID: 52, value: 0, name: OutGrd_NOfPendingPckts, multiplicity: 1 */ + 0, + /* ID: 53, value: 0, name: OutGrd_NOfGroups, multiplicity: 1 */ + 0, + /* ID: 54, value: 0, name: OutGrd_PcktQueueSize, multiplicity: 1 */ + 0 +}; + +/** Initialization of the structure holding of data pool variables and parameter items for IASW. */ +#ifdef PC_TARGET +struct DataPoolIasw dpIasw; +struct DataPoolIasw dpIaswInit = { +#else +struct DataPoolIasw dpIasw = { +#endif /* PC_TARGET */ + /* ID: 1, value: 0, name: buildNumber, multiplicity: 1 */ + 0, + /* ID: 55, value: 1, name: sibNFull, multiplicity: 1 */ + 1, + /* ID: 56, value: 1, name: cibNFull, multiplicity: 1 */ + 1, + /* ID: 57, value: 1, name: gibNFull, multiplicity: 1 */ + 1, + /* ID: 58, value: 1, name: sibNWin, multiplicity: 1 */ + 1, + /* ID: 59, value: 1, name: cibNWin, multiplicity: 1 */ + 1, + /* ID: 60, value: 1, name: gibNWin, multiplicity: 1 */ + 1, + /* ID: 61, value: 1024, name: sibSizeFull, multiplicity: 1 */ + 1024, + /* ID: 62, value: 1024, name: cibSizeFull, multiplicity: 1 */ + 1024, + /* ID: 63, value: 1024, name: gibSizeFull, multiplicity: 1 */ + 1024, + /* ID: 64, value: 1024, name: sibSizeWin, multiplicity: 1 */ + 1024, + /* ID: 65, value: 1024, name: cibSizeWin, multiplicity: 1 */ + 1024, + /* ID: 66, value: 1024, name: gibSizeWin, multiplicity: 1 */ + 1024, + /* ID: 67, value: 0, name: sibIn, multiplicity: 1 */ + 0, + /* ID: 68, value: 0, name: sibOut, multiplicity: 1 */ + 0, + /* ID: 69, value: 0, name: cibIn, multiplicity: 1 */ + 0, + /* ID: 70, value: 0, name: gibIn, multiplicity: 1 */ + 0, + /* ID: 71, value: 0, name: gibOut, multiplicity: 1 */ + 0, + /* ID: 72, value: STOPPED, name: sdbState, multiplicity: 1 */ + 0, + /* ID: 73, value: 0, name: sdbStateCnt, multiplicity: 1 */ + 0, + /* ID: 74, value: 0, name: OffsetX, multiplicity: 1 */ + 0, + /* ID: 75, value: 0, name: OffsetY, multiplicity: 1 */ + 0, + /* ID: 76, value: 51200, name: TargetLocationX, multiplicity: 1 */ + 51200, + /* ID: 77, value: 51200, name: TargetLocationY, multiplicity: 1 */ + 51200, + /* ID: 78, value: 0, name: IntegStartTimeCrs, multiplicity: 1 */ + 0, + /* ID: 79, value: 0, name: IntegStartTimeFine, multiplicity: 1 */ + 0, + /* ID: 80, value: 0, name: IntegEndTimeCrs, multiplicity: 1 */ + 0, + /* ID: 81, value: 0, name: IntegEndTimeFine, multiplicity: 1 */ + 0, + /* ID: 82, value: 0, name: DataCadence, multiplicity: 1 */ + 0, + /* ID: 83, value: 0, name: ValidityStatus, multiplicity: 1 */ + 0, + /* ID: 84, value: 0, name: NOfTcAcc, multiplicity: 1 */ + 0, + /* ID: 85, value: 0, name: NOfAccFailedTc, multiplicity: 1 */ + 0, + /* ID: 86, value: 0, name: SeqCntLastAccTcFromObc, multiplicity: 1 */ + 0, + /* ID: 87, value: 0, name: SeqCntLastAccTcFromGrd, multiplicity: 1 */ + 0, + /* ID: 88, value: 0, name: SeqCntLastAccFailTc, multiplicity: 1 */ + 0, + /* ID: 89, value: 0, name: NOfStartFailedTc, multiplicity: 1 */ + 0, + /* ID: 90, value: 0, name: SeqCntLastStartFailTc, multiplicity: 1 */ + 0, + /* ID: 91, value: 0, name: NOfTcTerm, multiplicity: 1 */ + 0, + /* ID: 92, value: 0, name: NOfTermFailedTc, multiplicity: 1 */ + 0, + /* ID: 93, value: 0, name: SeqCntLastTermFailTc, multiplicity: 1 */ + 0, + /* ID: 94, value: Auto, name: RdlSidList, multiplicity: 10 */ + {1,2,3,4,5,6,0,0,0,0}, + /* ID: 95, value: Auto, name: isRdlFree, multiplicity: 10 */ + {0,0,0,0,0,0,1,1,1,1}, + /* ID: 96, value: 0, name: RdlCycCntList, multiplicity: 10 */ + {0,0,0,0,0,0,0,0,0,0}, + /* ID: 97, value: Auto, name: RdlPeriodList, multiplicity: 10 */ + {160,0,32,8,0,160,0,0,0,0}, + /* ID: 98, value: Auto, name: RdlEnabledList, multiplicity: 10 */ + {1,0,0,0,0,0,0,0,0,0}, + /* ID: 99, value: 0, name: RdlDestList, multiplicity: 10 */ + {0,0,0,0,0,0,0,0,0,0}, + /* ID: 100, value: Auto, name: RdlDataItemList_0, multiplicity: 250 */ +{BUILDNUMBER_ID,APPERRCODE_ID,SIBNFULL_ID,CIBNFULL_ID,GIBNFULL_ID,SIBNWIN_ID,CIBNWIN_ID,GIBNWIN_ID,SIBSIZEFULL_ID,CIBSIZEFULL_ID,GIBSIZEFULL_ID,SIBSIZEWIN_ID,CIBSIZEWIN_ID,GIBSIZEWIN_ID,SIBIN_ID,SIBOUT_ID,CIBIN_ID,GIBIN_ID,GIBOUT_ID,SDBSTATE_ID,NOFTCACC_ID,NOFACCFAILEDTC_ID,SEQCNTLASTACCTCFROMOBC_ID,SEQCNTLASTACCTCFROMGRD_ID,SEQCNTLASTACCFAILTC_ID,NOFSTARTFAILEDTC_ID,SEQCNTLASTSTARTFAILTC_ID,NOFTCTERM_ID,NOFTERMFAILEDTC_ID,SEQCNTLASTTERMFAILTC_ID,SDU2STATE_ID,SDU4STATE_ID,SDSCOUNTER_ID,FDCHECKTTMSTATE_ID,FDCHECKSDSCSTATE_ID,FDCHECKCOMERRSTATE_ID,FDCHECKTIMEOUTSTATE_ID,FDCHECKSAFEMODESTATE_ID,FDCHECKALIVESTATE_ID,FDCHECKSEMANOEVTSTATE_ID,FDCHECKSEMLIMITSTATE_ID,FDCHECKDPUHKSTATE_ID,FDCHECKCENTCONSSTATE_ID,FDCHECKRESSTATE_ID,FDCHECKSEMCONS_ID,SEMSTATE_ID,SEMOPERSTATE_ID,SCISUBMODE_ID,IASWSTATE_ID,IASWCYCLECNT_ID,PREPSCIENCENODE_ID,CONTROLLEDSWITCHOFFNODE_ID,ALGOCENT0STATE_ID,ALGOCENT1STATE_ID,ALGOACQ1STATE_ID,ALGOCCSTATE_ID,ALGOTTC1STATE_ID,ALGOTTC2STATE_ID,ALGOSAAEVALSTATE_ID,ISSAAACTIVE_ID,SAACOUNTER_ID,ALGOSDSEVALSTATE_ID,ISSDSACTIVE_ID,OBSERVATIONID_ID,CENTVALPROCOUTPUT_ID,SAVEIMAGESNODE_ID,ACQFULLDROPNODE_ID,CALFULLSNAPNODE_ID,SCIWINNODE_ID,FBFLOADNODE_ID,FBFSAVENODE_ID,TRANSFBFTOGRNDNODE_ID,NOMSCINODE_ID,ADC_P3V3_ID,ADC_P5V_ID,ADC_P1V8_ID,ADC_P2V5_ID,ADC_N5V_ID,ADC_PGND_ID,ADC_TEMPOH1A_ID,ADC_TEMP1_ID,ADC_TEMPOH2A_ID,ADC_TEMPOH1B_ID,ADC_TEMPOH3A_ID,ADC_TEMPOH2B_ID,ADC_TEMPOH4A_ID,ADC_TEMPOH3B_ID,ADC_TEMPOH4B_ID,SEM_P15V_ID,SEM_P30V_ID,SEM_P5V0_ID,SEM_P7V0_ID,SEM_N5V0_ID,ISWATCHDOGENABLED_ID,ISSYNCHRONIZED_ID,NOFERRLOGENTRIES_ID,CORE0LOAD_ID,CORE1LOAD_ID,INTERRUPTRATE_ID,UPTIME_ID,IRL1_ID,IRL2_ID,SEMROUTE_ID,SPW1BYTESIN_ID,SPW1BYTESOUT_ID,EDACSINGLEFAULTS_ID,EDACLASTSINGLEFAIL_ID,CPU2PROCSTATUS_ID,CE_COUNTER_ID,CE_VERSION_ID,CE_INTEGRITY_ID,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 101, value: Auto, name: RdlDataItemList_1, multiplicity: 250 */ +{RDLENABLEDLIST_ID,EVTFILTERDEF_ID,EVTENABLEDLIST_ID,FDGLBENABLE_ID,RPGLBENABLE_ID,FDCHECKTTMEXTEN_ID,RPTTMEXTEN_ID,FDCHECKTTMCNTTHR_ID,TTC_LL_ID,TTC_UL_ID,TTM_LIM_ID,FDCHECKSDSCEXTEN_ID,RPSDSCEXTEN_ID,FDCHECKSDSCCNTTHR_ID,FDCHECKCOMERREXTEN_ID,RPCOMERREXTEN_ID,FDCHECKCOMERRCNTTHR_ID,FDCHECKTIMEOUTEXTEN_ID,RPTIMEOUTEXTEN_ID,FDCHECKTIMEOUTCNTTHR_ID,SEM_TO_POWERON_ID,SEM_TO_SAFE_ID,SEM_TO_STAB_ID,SEM_TO_TEMP_ID,SEM_TO_CCD_ID,SEM_TO_DIAG_ID,SEM_TO_STANDBY_ID,FDCHECKSAFEMODEEXTEN_ID,RPSAFEMODEEXTEN_ID,FDCHECKSAFEMODECNTTHR_ID,FDCHECKALIVEEXTEN_ID,RPALIVEEXTEN_ID,FDCHECKALIVECNTTHR_ID,SEM_HK_DEF_PER_ID,FDCHECKSEMANOEVTEXTEN_ID,RPSEMANOEVTEXTEN_ID,FDCHECKSEMANOEVTCNTTHR_ID,SEMANOEVTRESP_1_ID,SEMANOEVTRESP_2_ID,SEMANOEVTRESP_3_ID,SEMANOEVTRESP_4_ID,SEMANOEVTRESP_5_ID,SEMANOEVTRESP_6_ID,SEMANOEVTRESP_7_ID,SEMANOEVTRESP_8_ID,SEMANOEVTRESP_9_ID,SEMANOEVTRESP_10_ID,SEMANOEVTRESP_11_ID,SEMANOEVTRESP_12_ID,SEMANOEVTRESP_13_ID,SEMANOEVTRESP_14_ID,SEMANOEVTRESP_15_ID,SEMANOEVTRESP_16_ID,SEMANOEVTRESP_17_ID,SEMANOEVTRESP_18_ID,SEMANOEVTRESP_19_ID,SEMANOEVTRESP_20_ID,SEMANOEVTRESP_21_ID,SEMANOEVTRESP_22_ID,SEMANOEVTRESP_23_ID,SEMANOEVTRESP_24_ID,SEMANOEVTRESP_25_ID,SEMANOEVTRESP_26_ID,SEMANOEVTRESP_27_ID,SEMANOEVTRESP_28_ID,SEMANOEVTRESP_29_ID,FDCHECKSEMLIMITEXTEN_ID,RPSEMLIMITEXTEN_ID,FDCHECKSEMLIMITCNTTHR_ID,SEM_LIM_DEL_T_ID,FDCHECKDPUHKEXTEN_ID,RPDPUHKEXTEN_ID,FDCHECKDPUHKCNTTHR_ID,FDCHECKCENTCONSEXTEN_ID,RPCENTCONSEXTEN_ID,FDCHECKCENTCONSCNTTHR_ID,FDCHECKRESEXTEN_ID,RPRESEXTEN_ID,FDCHECKRESCNTTHR_ID,CPU1_USAGE_MAX_ID,MEM_USAGE_MAX_ID,FDCHECKSEMCONSEXTEN_ID,RPSEMCONSEXTEN_ID,FDCHECKSEMCONSCNTTHR_ID,SEM_INIT_T1_ID,SEM_INIT_T2_ID,SEM_OPER_T1_ID,SEM_SHUTDOWN_T1_ID,SEM_SHUTDOWN_T11_ID,SEM_SHUTDOWN_T12_ID,SEM_SHUTDOWN_T2_ID,CTRLD_SWITCH_OFF_T1_ID,ALGOCENT0ENABLED_ID,ALGOCENT1ENABLED_ID,CENT_EXEC_PHASE_ID,ALGOACQ1ENABLED_ID,ALGOCCENABLED_ID,STCK_ORDER_ID,ALGOTTC1ENABLED_ID,TTC1_EXEC_PER_ID,TTC1_LL_FRT_ID,TTC1_LL_AFT_ID,TTC1_UL_FRT_ID,TTC1_UL_AFT_ID,ALGOTTC2ENABLED_ID,TTC2_EXEC_PER_ID,TTC2_REF_TEMP_ID,TTC2_OFFSETA_ID,TTC2_OFFSETF_ID,TTC2_PA_ID,TTC2_DA_ID,TTC2_IA_ID,TTC2_PF_ID,TTC2_DF_ID,TTC2_IF_ID,SAA_EXEC_PHASE_ID,SAA_EXEC_PER_ID,SDS_EXEC_PHASE_ID,SDS_EXEC_PER_ID,SDS_FORCED_ID,SDS_INHIBITED_ID,EARTH_OCCULT_ACTIVE_ID,CENT_OFFSET_LIM_ID,CENT_FROZEN_LIM_ID,SEM_SERV1_1_FORWARD_ID,SEM_SERV1_2_FORWARD_ID,SEM_SERV1_7_FORWARD_ID,SEM_SERV1_8_FORWARD_ID,SEM_SERV3_1_FORWARD_ID,SEM_SERV3_2_FORWARD_ID,TEMP_SEM_SCU_LW_ID,TEMP_SEM_PCU_LW_ID,VOLT_SCU_P3_4_LW_ID,VOLT_SCU_P5_LW_ID,TEMP_FEE_CCD_LW_ID,TEMP_FEE_STRAP_LW_ID,TEMP_FEE_ADC_LW_ID,TEMP_FEE_BIAS_LW_ID,TEMP_FEE_DEB_LW_ID,VOLT_FEE_VOD_LW_ID,VOLT_FEE_VRD_LW_ID,VOLT_FEE_VOG_LW_ID,VOLT_FEE_VSS_LW_ID,VOLT_FEE_CCD_LW_ID,VOLT_FEE_CLK_LW_ID,VOLT_FEE_ANA_P5_LW_ID,VOLT_FEE_ANA_N5_LW_ID,VOLT_FEE_ANA_P3_3_LW_ID,CURR_FEE_CLK_BUF_LW_ID,VOLT_SCU_FPGA_P1_5_LW_ID,CURR_SCU_P3_4_LW_ID,TEMP_SEM_SCU_UW_ID,TEMP_SEM_PCU_UW_ID,VOLT_SCU_P3_4_UW_ID,VOLT_SCU_P5_UW_ID,TEMP_FEE_CCD_UW_ID,TEMP_FEE_STRAP_UW_ID,TEMP_FEE_ADC_UW_ID,TEMP_FEE_BIAS_UW_ID,TEMP_FEE_DEB_UW_ID,VOLT_FEE_VOD_UW_ID,VOLT_FEE_VRD_UW_ID,VOLT_FEE_VOG_UW_ID,VOLT_FEE_VSS_UW_ID,VOLT_FEE_CCD_UW_ID,VOLT_FEE_CLK_UW_ID,VOLT_FEE_ANA_P5_UW_ID,VOLT_FEE_ANA_N5_UW_ID,VOLT_FEE_ANA_P3_3_UW_ID,CURR_FEE_CLK_BUF_UW_ID,VOLT_SCU_FPGA_P1_5_UW_ID,CURR_SCU_P3_4_UW_ID,TEMP_SEM_SCU_LA_ID,TEMP_SEM_PCU_LA_ID,VOLT_SCU_P3_4_LA_ID,VOLT_SCU_P5_LA_ID,TEMP_FEE_CCD_LA_ID,TEMP_FEE_STRAP_LA_ID,TEMP_FEE_ADC_LA_ID,TEMP_FEE_BIAS_LA_ID,TEMP_FEE_DEB_LA_ID,VOLT_FEE_VOD_LA_ID,VOLT_FEE_VRD_LA_ID,VOLT_FEE_VOG_LA_ID,VOLT_FEE_VSS_LA_ID,VOLT_FEE_CCD_LA_ID,VOLT_FEE_CLK_LA_ID,VOLT_FEE_ANA_P5_LA_ID,VOLT_FEE_ANA_N5_LA_ID,VOLT_FEE_ANA_P3_3_LA_ID,CURR_FEE_CLK_BUF_LA_ID,VOLT_SCU_FPGA_P1_5_LA_ID,CURR_SCU_P3_4_LA_ID,TEMP_SEM_SCU_UA_ID,TEMP_SEM_PCU_UA_ID,VOLT_SCU_P3_4_UA_ID,VOLT_SCU_P5_UA_ID,TEMP_FEE_CCD_UA_ID,TEMP_FEE_STRAP_UA_ID,TEMP_FEE_ADC_UA_ID,TEMP_FEE_BIAS_UA_ID,TEMP_FEE_DEB_UA_ID,VOLT_FEE_VOD_UA_ID,VOLT_FEE_VRD_UA_ID,VOLT_FEE_VOG_UA_ID,VOLT_FEE_VSS_UA_ID,VOLT_FEE_CCD_UA_ID,VOLT_FEE_CLK_UA_ID,VOLT_FEE_ANA_P5_UA_ID,VOLT_FEE_ANA_N5_UA_ID,VOLT_FEE_ANA_P3_3_UA_ID,CURR_FEE_CLK_BUF_UA_ID,VOLT_SCU_FPGA_P1_5_UA_ID,CURR_SCU_P3_4_UA_ID,SEM_SERV5_1_FORWARD_ID,SEM_SERV5_2_FORWARD_ID,SEM_SERV5_3_FORWARD_ID,SEM_SERV5_4_FORWARD_ID,ACQFULLDROPT1_ID,ACQFULLDROPT2_ID,CALFULLSNAPT1_ID,CALFULLSNAPT2_ID,SCIWINT1_ID,SCIWINT2_ID,ADC_P3V3_U_ID,ADC_P5V_U_ID,ADC_P1V8_U_ID,ADC_P2V5_U_ID,ADC_N5V_L_ID,ADC_PGND_U_ID,ADC_PGND_L_ID,ADC_TEMPOH1A_U_ID,ADC_TEMP1_U_ID,ADC_TEMPOH2A_U_ID,ADC_TEMPOH1B_U_ID,ADC_TEMPOH3A_U_ID,ADC_TEMPOH2B_U_ID,ADC_TEMPOH4A_U_ID,ADC_TEMPOH3B_U_ID,ADC_TEMPOH4B_U_ID,SEM_P15V_U_ID,SEM_P30V_U_ID,SEM_P5V0_U_ID,SEM_P7V0_U_ID,SEM_N5V0_L_ID,HBSEMPASSWORD_ID,0,0,0,0}, + /* ID: 102, value: Auto, name: RdlDataItemList_2, multiplicity: 250 */ +{NOFALLOCATEDINREP_ID,NOFALLOCATEDINCMD_ID,SEM_NOFPENDINGINCMP_ID,SEM_NOFLOADEDINCMP_ID,GRDOBC_NOFPENDINGINCMP_ID,NOFALLOCATEDOUTCMP_ID,NOFINSTANCEID_ID,OUTMG1_NOFPENDINGOUTCMP_ID,OUTMG1_NOFLOADEDOUTCMP_ID,OUTMG2_NOFPENDINGOUTCMP_ID,OUTMG2_NOFLOADEDOUTCMP_ID,OUTMG3_NOFPENDINGOUTCMP_ID,OUTMG3_NOFLOADEDOUTCMP_ID,INSEM_NOFPENDINGPCKTS_ID,INOBC_NOFPENDINGPCKTS_ID,INGRD_NOFPENDINGPCKTS_ID,OUTSEM_NOFPENDINGPCKTS_ID,OUTOBC_NOFPENDINGPCKTS_ID,OUTGRD_NOFPENDINGPCKTS_ID,SDBSTATECNT_ID,LASTPATCHEDADDR_ID,LASTDUMPADDR_ID,SDU2BLOCKCNT_ID,SDU4BLOCKCNT_ID,FDCHECKTTMINTEN_ID,RPTTMINTEN_ID,FDCHECKTTMCNT_ID,FDCHECKTTMSPCNT_ID,FDCHECKSDSCINTEN_ID,RPSDSCINTEN_ID,FDCHECKSDSCCNT_ID,FDCHECKSDSCSPCNT_ID,FDCHECKCOMERRINTEN_ID,RPCOMERRINTEN_ID,FDCHECKCOMERRCNT_ID,FDCHECKCOMERRSPCNT_ID,FDCHECKTIMEOUTINTEN_ID,RPTIMEOUTINTEN_ID,FDCHECKTIMEOUTCNT_ID,FDCHECKTIMEOUTSPCNT_ID,FDCHECKSAFEMODEINTEN_ID,RPSAFEMODEINTEN_ID,FDCHECKSAFEMODECNT_ID,FDCHECKSAFEMODESPCNT_ID,FDCHECKALIVEINTEN_ID,RPALIVEINTEN_ID,FDCHECKALIVECNT_ID,FDCHECKALIVESPCNT_ID,FDCHECKSEMANOEVTINTEN_ID,RPSEMANOEVTINTEN_ID,FDCHECKSEMANOEVTCNT_ID,FDCHECKSEMANOEVTSPCNT_ID,FDCHECKSEMLIMITINTEN_ID,RPSEMLIMITINTEN_ID,FDCHECKSEMLIMITCNT_ID,FDCHECKSEMLIMITSPCNT_ID,FDCHECKDPUHKINTEN_ID,RPDPUHKINTEN_ID,FDCHECKDPUHKCNT_ID,FDCHECKDPUHKSPCNT_ID,FDCHECKCENTCONSINTEN_ID,RPCENTCONSINTEN_ID,FDCHECKCENTCONSCNT_ID,FDCHECKCENTCONSSPCNT_ID,FDCHECKRESINTEN_ID,RPRESINTEN_ID,FDCHECKRESCNT_ID,FDCHECKRESSPCNT_ID,FDCHECKSEMCONSINTEN_ID,RPSEMCONSINTEN_ID,FDCHECKSEMCONSCNT_ID,FDCHECKSEMCONSSPCNT_ID,SEMSTATECNT_ID,SEMOPERSTATECNT_ID,IMAGECYCLECNT_ID,ACQIMAGECNT_ID,LASTSEMPCKT_ID,IASWSTATECNT_ID,PREPSCIENCECNT_ID,CONTROLLEDSWITCHOFFCNT_ID,ALGOCENT0CNT_ID,ALGOCENT1CNT_ID,ALGOACQ1CNT_ID,ALGOCCCNT_ID,ALGOTTC1CNT_ID,TTC1AVTEMPAFT_ID,TTC1AVTEMPFRT_ID,ALGOTTC2CNT_ID,INTTIMEAFT_ID,ONTIMEAFT_ID,INTTIMEFRONT_ID,ONTIMEFRONT_ID,HBSEM_ID,SEMEVTCOUNTER_ID,PEXPTIME_ID,PIMAGEREP_ID,PACQNUM_ID,PDATAOS_ID,PCCDRDMODE_ID,PWINPOSX_ID,PWINPOSY_ID,PWINSIZEX_ID,PWINSIZEY_ID,PDTACQSRC_ID,PTEMPCTRLTARGET_ID,PVOLTFEEVOD_ID,PVOLTFEEVRD_ID,PVOLTFEEVSS_ID,PHEATTEMPFPACCD_ID,PHEATTEMPFEESTRAP_ID,PHEATTEMPFEEANACH_ID,PHEATTEMPSPARE_ID,PSTEPENDIAGCCD_ID,PSTEPENDIAGFEE_ID,PSTEPENDIAGTEMP_ID,PSTEPENDIAGANA_ID,PSTEPENDIAGEXPOS_ID,PSTEPDEBDIAGCCD_ID,PSTEPDEBDIAGFEE_ID,PSTEPDEBDIAGTEMP_ID,PSTEPDEBDIAGANA_ID,PSTEPDEBDIAGEXPOS_ID,SAVEIMAGESCNT_ID,SAVEIMAGES_PSAVETARGET_ID,SAVEIMAGES_PFBFINIT_ID,SAVEIMAGES_PFBFEND_ID,ACQFULLDROPCNT_ID,ACQFULLDROP_PEXPTIME_ID,ACQFULLDROP_PIMAGEREP_ID,CALFULLSNAPCNT_ID,CALFULLSNAP_PEXPTIME_ID,CALFULLSNAP_PIMAGEREP_ID,CALFULLSNAP_PNMBIMAGES_ID,CALFULLSNAP_PCENTSEL_ID,SCIWINCNT_ID,SCIWIN_PNMBIMAGES_ID,SCIWIN_PCCDRDMODE_ID,SCIWIN_PEXPTIME_ID,SCIWIN_PIMAGEREP_ID,SCIWIN_PWINPOSX_ID,SCIWIN_PWINPOSY_ID,SCIWIN_PWINSIZEX_ID,SCIWIN_PWINSIZEY_ID,SCIWIN_PCENTSEL_ID,FBFLOADCNT_ID,FBFSAVECNT_ID,FBFLOAD_PFBFID_ID,FBFLOAD_PFBFNBLOCKS_ID,FBFLOAD_PFBFRAMAREAID_ID,FBFLOAD_PFBFRAMADDR_ID,FBFSAVE_PFBFID_ID,FBFSAVE_PFBFNBLOCKS_ID,FBFSAVE_PFBFRAMAREAID_ID,FBFSAVE_PFBFRAMADDR_ID,FBFLOADBLOCKCOUNTER_ID,FBFSAVEBLOCKCOUNTER_ID,TRANSFBFTOGRNDCNT_ID,TRANSFBFTOGRND_PNMBFBF_ID,TRANSFBFTOGRND_PFBFINIT_ID,TRANSFBFTOGRND_PFBFSIZE_ID,NOMSCICNT_ID,NOMSCI_PACQFLAG_ID,NOMSCI_PCAL1FLAG_ID,NOMSCI_PSCIFLAG_ID,NOMSCI_PCAL2FLAG_ID,NOMSCI_PCIBNFULL_ID,NOMSCI_PCIBSIZEFULL_ID,NOMSCI_PSIBNFULL_ID,NOMSCI_PSIBSIZEFULL_ID,NOMSCI_PGIBNFULL_ID,NOMSCI_PGIBSIZEFULL_ID,NOMSCI_PSIBNWIN_ID,NOMSCI_PSIBSIZEWIN_ID,NOMSCI_PCIBNWIN_ID,NOMSCI_PCIBSIZEWIN_ID,NOMSCI_PGIBNWIN_ID,NOMSCI_PGIBSIZEWIN_ID,NOMSCI_PEXPTIMEACQ_ID,NOMSCI_PIMAGEREPACQ_ID,NOMSCI_PEXPTIMECAL1_ID,NOMSCI_PIMAGEREPCAL1_ID,NOMSCI_PNMBIMAGESCAL1_ID,NOMSCI_PCENTSELCAL1_ID,NOMSCI_PNMBIMAGESSCI_ID,NOMSCI_PCCDRDMODESCI_ID,NOMSCI_PEXPTIMESCI_ID,NOMSCI_PIMAGEREPSCI_ID,NOMSCI_PWINPOSXSCI_ID,NOMSCI_PWINPOSYSCI_ID,NOMSCI_PWINSIZEXSCI_ID,NOMSCI_PWINSIZEYSCI_ID,NOMSCI_PCENTSELSCI_ID,NOMSCI_PEXPTIMECAL2_ID,NOMSCI_PIMAGEREPCAL2_ID,NOMSCI_PNMBIMAGESCAL2_ID,NOMSCI_PCENTSELCAL2_ID,NOMSCI_PSAVETARGET_ID,NOMSCI_PFBFINIT_ID,NOMSCI_PFBFEND_ID,NOMSCI_PSTCKORDERCAL1_ID,NOMSCI_PSTCKORDERSCI_ID,NOMSCI_PSTCKORDERCAL2_ID,CONFIGSDB_PSDBCMD_ID,CONFIGSDB_PCIBNFULL_ID,CONFIGSDB_PCIBSIZEFULL_ID,CONFIGSDB_PSIBNFULL_ID,CONFIGSDB_PSIBSIZEFULL_ID,CONFIGSDB_PGIBNFULL_ID,CONFIGSDB_PGIBSIZEFULL_ID,CONFIGSDB_PSIBNWIN_ID,CONFIGSDB_PSIBSIZEWIN_ID,CONFIGSDB_PCIBNWIN_ID,CONFIGSDB_PCIBSIZEWIN_ID,CONFIGSDB_PGIBNWIN_ID,CONFIGSDB_PGIBSIZEWIN_ID,HBSEMCOUNTER_ID,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 103, value: Auto, name: RdlDataItemList_3, multiplicity: 250 */ +{ADC_P3V3_RAW_ID,ADC_P5V_RAW_ID,ADC_P1V8_RAW_ID,ADC_P2V5_RAW_ID,ADC_N5V_RAW_ID,ADC_PGND_RAW_ID,ADC_TEMPOH1A_RAW_ID,ADC_TEMP1_RAW_ID,ADC_TEMPOH2A_RAW_ID,ADC_TEMPOH1B_RAW_ID,ADC_TEMPOH3A_RAW_ID,ADC_TEMPOH2B_RAW_ID,ADC_TEMPOH4A_RAW_ID,ADC_TEMPOH3B_RAW_ID,ADC_TEMPOH4B_RAW_ID,SEM_P15V_RAW_ID,SEM_P30V_RAW_ID,SEM_P5V0_RAW_ID,SEM_P7V0_RAW_ID,SEM_N5V0_RAW_ID,MISSEDMSGCNT_ID,MISSEDPULSECNT_ID,ISERRLOGVALID_ID,WCET_1_ID,WCET_2_ID,WCET_3_ID,WCET_4_ID,WCET_5_ID,WCETAVER_1_ID,WCETAVER_2_ID,WCETAVER_3_ID,WCETAVER_4_ID,WCETAVER_5_ID,WCETMAX_1_ID,WCETMAX_2_ID,WCETMAX_3_ID,WCETMAX_4_ID,WCETMAX_5_ID,NOFNOTIF_1_ID,NOFNOTIF_2_ID,NOFNOTIF_3_ID,NOFNOTIF_4_ID,NOFNOTIF_5_ID,NOFFUNCEXEC_1_ID,NOFFUNCEXEC_2_ID,NOFFUNCEXEC_3_ID,NOFFUNCEXEC_4_ID,NOFFUNCEXEC_5_ID,WCETTIMESTAMPFINE_1_ID,WCETTIMESTAMPFINE_2_ID,WCETTIMESTAMPFINE_3_ID,WCETTIMESTAMPFINE_4_ID,WCETTIMESTAMPFINE_5_ID,WCETTIMESTAMPCOARSE_1_ID,WCETTIMESTAMPCOARSE_2_ID,WCETTIMESTAMPCOARSE_3_ID,WCETTIMESTAMPCOARSE_4_ID,WCETTIMESTAMPCOARSE_5_ID,FLASHCONTSTEPCNT_ID,CYCLICALACTIVITIESCTR_ID,OBCINPUTBUFFERPACKETS_ID,GRNDINPUTBUFFERPACKETS_ID,MILBUSBYTESIN_ID,MILBUSBYTESOUT_ID,MILBUSDROPPEDBYTES_ID,IRL1_AHBSTAT_ID,IRL1_GRGPIO_6_ID,IRL1_GRTIMER_ID,IRL1_GPTIMER_0_ID,IRL1_GPTIMER_1_ID,IRL1_GPTIMER_2_ID,IRL1_GPTIMER_3_ID,IRL1_IRQMP_ID,IRL1_B1553BRM_ID,IRL2_GRSPW2_0_ID,IRL2_GRSPW2_1_ID,SPW1TXDESCAVAIL_ID,SPW1RXPCKTAVAIL_ID,MILCUCCOARSETIME_ID,MILCUCFINETIME_ID,CUCCOARSETIME_ID,CUCFINETIME_ID,SRAM1SCRCURRADDR_ID,SRAM2SCRCURRADDR_ID,SRAM1SCRLENGTH_ID,SRAM2SCRLENGTH_ID,EDACSINGLEREPAIRED_ID,EDACDOUBLEFAULTS_ID,EDACDOUBLEFADDR_ID,HEARTBEAT_ENABLED_ID,S1ALLOCDBS_ID,S1ALLOCSW_ID,S1ALLOCHEAP_ID,S1ALLOCFLASH_ID,S1ALLOCAUX_ID,S1ALLOCRES_ID,S1ALLOCSWAP_ID,S2ALLOCSCIHEAP_ID,FPGA_VERSION_ID,FPGA_DPU_STATUS_ID,FPGA_DPU_ADDRESS_ID,FPGA_RESET_STATUS_ID,FPGA_SEM_STATUS_ID,FPGA_OPER_HEATER_STATUS_ID,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 104, value: Auto, name: RdlDataItemList_4, multiplicity: 250 */ +{SEM_ON_CODE_ID,SEM_OFF_CODE_ID,ACQ_PH_ID,MILFRAMEDELAY_ID,EL1_CHIP_ID,EL2_CHIP_ID,EL1_ADDR_ID,EL2_ADDR_ID,ERR_LOG_ENB_ID,FBF_BLCK_WR_DUR_ID,FBF_BLCK_RD_DUR_ID,THR_MA_A_1_ID,THR_MA_A_2_ID,THR_MA_A_3_ID,THR_MA_A_4_ID,THR_MA_A_5_ID,OTA_TM1A_NOM_ID,OTA_TM1A_RED_ID,OTA_TM1B_NOM_ID,OTA_TM1B_RED_ID,OTA_TM2A_NOM_ID,OTA_TM2A_RED_ID,OTA_TM2B_NOM_ID,OTA_TM2B_RED_ID,OTA_TM3A_NOM_ID,OTA_TM3A_RED_ID,OTA_TM3B_NOM_ID,OTA_TM3B_RED_ID,OTA_TM4A_NOM_ID,OTA_TM4A_RED_ID,OTA_TM4B_NOM_ID,OTA_TM4B_RED_ID,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 105, value: Auto, name: RdlDataItemList_5, multiplicity: 250 */ +{SEM_HK_TS_DEF_CRS_ID,SEM_HK_TS_DEF_FINE_ID,SEM_HK_TS_EXT_CRS_ID,SEM_HK_TS_EXT_FINE_ID,STAT_MODE_ID,STAT_FLAGS_ID,STAT_LAST_SPW_ERR_ID,STAT_LAST_ERR_ID_ID,STAT_LAST_ERR_FREQ_ID,STAT_NUM_CMD_RECEIVED_ID,STAT_NUM_CMD_EXECUTED_ID,STAT_NUM_DATA_SENT_ID,STAT_SCU_PROC_DUTY_CL_ID,STAT_SCU_NUM_AHB_ERR_ID,STAT_SCU_NUM_AHB_CERR_ID,STAT_SCU_NUM_LUP_ERR_ID,TEMP_SEM_SCU_ID,TEMP_SEM_PCU_ID,VOLT_SCU_P3_4_ID,VOLT_SCU_P5_ID,TEMP_FEE_CCD_ID,TEMP_FEE_STRAP_ID,TEMP_FEE_ADC_ID,TEMP_FEE_BIAS_ID,TEMP_FEE_DEB_ID,VOLT_FEE_VOD_ID,VOLT_FEE_VRD_ID,VOLT_FEE_VOG_ID,VOLT_FEE_VSS_ID,VOLT_FEE_CCD_ID,VOLT_FEE_CLK_ID,VOLT_FEE_ANA_P5_ID,VOLT_FEE_ANA_N5_ID,VOLT_FEE_ANA_P3_3_ID,CURR_FEE_CLK_BUF_ID,VOLT_SCU_FPGA_P1_5_ID,CURR_SCU_P3_4_ID,STAT_NUM_SPW_ERR_CRE_ID,STAT_NUM_SPW_ERR_ESC_ID,STAT_NUM_SPW_ERR_DISC_ID,STAT_NUM_SPW_ERR_PAR_ID,STAT_NUM_SPW_ERR_WRSY_ID,STAT_NUM_SPW_ERR_INVA_ID,STAT_NUM_SPW_ERR_EOP_ID,STAT_NUM_SPW_ERR_RXAH_ID,STAT_NUM_SPW_ERR_TXAH_ID,STAT_NUM_SPW_ERR_TXBL_ID,STAT_NUM_SPW_ERR_TXLE_ID,STAT_NUM_SP_ERR_RX_ID,STAT_NUM_SP_ERR_TX_ID,STAT_HEAT_PWM_FPA_CCD_ID,STAT_HEAT_PWM_FEE_STR_ID,STAT_HEAT_PWM_FEE_ANA_ID,STAT_HEAT_PWM_SPARE_ID,STAT_HEAT_PWM_FLAGS_ID,STAT_OBTIME_SYNC_DELTA_ID,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 106, value: Auto, name: RdlDataItemList_6, multiplicity: 250 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 107, value: 0, name: RdlDataItemList_7, multiplicity: 250 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 108, value: 0, name: RdlDataItemList_8, multiplicity: 250 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 109, value: 0, name: RdlDataItemList_9, multiplicity: 250 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 110, value: 0, name: DEBUG_VAR, multiplicity: 20 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 111, value: 1073741824, name: DEBUG_VAR_ADDR, multiplicity: 20 */ + {1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824,1073741824}, + /* ID: 112, value: 5, name: EVTFILTERDEF, multiplicity: 1 */ + 5, + /* ID: 113, value: 5, name: evtEnabledList, multiplicity: 60 */ + {5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5}, + /* ID: 114, value: 0, name: lastPatchedAddr, multiplicity: 1 */ + 0, + /* ID: 115, value: 0, name: lastDumpAddr, multiplicity: 1 */ + 0, + /* ID: 116, value: STOPPED, name: sdu2State, multiplicity: 1 */ + 0, + /* ID: 117, value: STOPPED, name: sdu4State, multiplicity: 1 */ + 0, + /* ID: 118, value: 0, name: sdu2StateCnt, multiplicity: 1 */ + 0, + /* ID: 119, value: 0, name: sdu4StateCnt, multiplicity: 1 */ + 0, + /* ID: 120, value: 0, name: sdu2BlockCnt, multiplicity: 1 */ + 0, + /* ID: 121, value: 0, name: sdu4BlockCnt, multiplicity: 1 */ + 0, + /* ID: 122, value: 0, name: sdu2RemSize, multiplicity: 1 */ + 0, + /* ID: 123, value: 0, name: sdu4RemSize, multiplicity: 1 */ + 0, + /* ID: 124, value: 4294967295, name: sdu2DownTransferSize, multiplicity: 1 */ + 0xffffffff, + /* ID: 125, value: 4294967295, name: sdu4DownTransferSize, multiplicity: 1 */ + 0xffffffff, + /* ID: 126, value: 0, name: sdsCounter, multiplicity: 1 */ + 0, + /* ID: 127, value: 1, name: FdGlbEnable, multiplicity: 1 */ + 1, + /* ID: 128, value: 1, name: RpGlbEnable, multiplicity: 1 */ + 1, + /* ID: 129, value: STOPPED, name: FdCheckTTMState, multiplicity: 1 */ + 0, + /* ID: 130, value: 0, name: FdCheckTTMIntEn, multiplicity: 1 */ + 0, + /* ID: 131, value: 1, name: FdCheckTTMExtEn, multiplicity: 1 */ + 1, + /* ID: 132, value: 1, name: RpTTMIntEn, multiplicity: 1 */ + 1, + /* ID: 133, value: 1, name: RpTTMExtEn, multiplicity: 1 */ + 1, + /* ID: 134, value: 0, name: FdCheckTTMCnt, multiplicity: 1 */ + 0, + /* ID: 135, value: 0, name: FdCheckTTMSpCnt, multiplicity: 1 */ + 0, + /* ID: 136, value: 3, name: FdCheckTTMCntThr, multiplicity: 1 */ + 3, + /* ID: 137, value: -24, name: TTC_LL, multiplicity: 1 */ + -24, + /* ID: 138, value: -5, name: TTC_UL, multiplicity: 1 */ + -5, + /* ID: 139, value: 0.5, name: TTM_LIM, multiplicity: 1 */ + 0.5, + /* ID: 140, value: STOPPED, name: FdCheckSDSCState, multiplicity: 1 */ + 0, + /* ID: 141, value: 1, name: FdCheckSDSCIntEn, multiplicity: 1 */ + 1, + /* ID: 142, value: 0, name: FdCheckSDSCExtEn, multiplicity: 1 */ + 0, + /* ID: 143, value: 1, name: RpSDSCIntEn, multiplicity: 1 */ + 1, + /* ID: 144, value: 1, name: RpSDSCExtEn, multiplicity: 1 */ + 1, + /* ID: 145, value: 0, name: FdCheckSDSCCnt, multiplicity: 1 */ + 0, + /* ID: 146, value: 0, name: FdCheckSDSCSpCnt, multiplicity: 1 */ + 0, + /* ID: 147, value: 3, name: FdCheckSDSCCntThr, multiplicity: 1 */ + 3, + /* ID: 148, value: STOPPED, name: FdCheckComErrState, multiplicity: 1 */ + 0, + /* ID: 149, value: 0, name: FdCheckComErrIntEn, multiplicity: 1 */ + 0, + /* ID: 150, value: 1, name: FdCheckComErrExtEn, multiplicity: 1 */ + 1, + /* ID: 151, value: 1, name: RpComErrIntEn, multiplicity: 1 */ + 1, + /* ID: 152, value: 1, name: RpComErrExtEn, multiplicity: 1 */ + 1, + /* ID: 153, value: 0, name: FdCheckComErrCnt, multiplicity: 1 */ + 0, + /* ID: 154, value: 0, name: FdCheckComErrSpCnt, multiplicity: 1 */ + 0, + /* ID: 155, value: 3, name: FdCheckComErrCntThr, multiplicity: 1 */ + 3, + /* ID: 156, value: STOPPED, name: FdCheckTimeOutState, multiplicity: 1 */ + 0, + /* ID: 157, value: 0, name: FdCheckTimeOutIntEn, multiplicity: 1 */ + 0, + /* ID: 158, value: 1, name: FdCheckTimeOutExtEn, multiplicity: 1 */ + 1, + /* ID: 159, value: 1, name: RpTimeOutIntEn, multiplicity: 1 */ + 1, + /* ID: 160, value: 1, name: RpTimeOutExtEn, multiplicity: 1 */ + 1, + /* ID: 161, value: 0, name: FdCheckTimeOutCnt, multiplicity: 1 */ + 0, + /* ID: 162, value: 0, name: FdCheckTimeOutSpCnt, multiplicity: 1 */ + 0, + /* ID: 163, value: 1, name: FdCheckTimeOutCntThr, multiplicity: 1 */ + 1, + /* ID: 164, value: 512, name: SEM_TO_POWERON, multiplicity: 1 */ + 512, + /* ID: 165, value: 264, name: SEM_TO_SAFE, multiplicity: 1 */ + 264, + /* ID: 166, value: 264, name: SEM_TO_STAB, multiplicity: 1 */ + 264, + /* ID: 167, value: 99999999, name: SEM_TO_TEMP, multiplicity: 1 */ + 99999999, + /* ID: 168, value: 88, name: SEM_TO_CCD, multiplicity: 1 */ + 88, + /* ID: 169, value: 88, name: SEM_TO_DIAG, multiplicity: 1 */ + 88, + /* ID: 170, value: 176, name: SEM_TO_STANDBY, multiplicity: 1 */ + 176, + /* ID: 171, value: STOPPED, name: FdCheckSafeModeState, multiplicity: 1 */ + 0, + /* ID: 172, value: 0, name: FdCheckSafeModeIntEn, multiplicity: 1 */ + 0, + /* ID: 173, value: 1, name: FdCheckSafeModeExtEn, multiplicity: 1 */ + 1, + /* ID: 174, value: 1, name: RpSafeModeIntEn, multiplicity: 1 */ + 1, + /* ID: 175, value: 1, name: RpSafeModeExtEn, multiplicity: 1 */ + 1, + /* ID: 176, value: 0, name: FdCheckSafeModeCnt, multiplicity: 1 */ + 0, + /* ID: 177, value: 0, name: FdCheckSafeModeSpCnt, multiplicity: 1 */ + 0, + /* ID: 178, value: 1, name: FdCheckSafeModeCntThr, multiplicity: 1 */ + 1, + /* ID: 179, value: STOPPED, name: FdCheckAliveState, multiplicity: 1 */ + 0, + /* ID: 180, value: 0, name: FdCheckAliveIntEn, multiplicity: 1 */ + 0, + /* ID: 181, value: 1, name: FdCheckAliveExtEn, multiplicity: 1 */ + 1, + /* ID: 182, value: 1, name: RpAliveIntEn, multiplicity: 1 */ + 1, + /* ID: 183, value: 1, name: RpAliveExtEn, multiplicity: 1 */ + 1, + /* ID: 184, value: 0, name: FdCheckAliveCnt, multiplicity: 1 */ + 0, + /* ID: 185, value: 0, name: FdCheckAliveSpCnt, multiplicity: 1 */ + 0, + /* ID: 186, value: 1, name: FdCheckAliveCntThr, multiplicity: 1 */ + 1, + /* ID: 187, value: 504, name: SEM_HK_DEF_PER, multiplicity: 1 */ + 504, + /* ID: 188, value: 1, name: SEMALIVE_DELAYEDSEMHK, multiplicity: 1 */ + 1, + /* ID: 189, value: STOPPED, name: FdCheckSemAnoEvtState, multiplicity: 1 */ + 0, + /* ID: 190, value: 0, name: FdCheckSemAnoEvtIntEn, multiplicity: 1 */ + 0, + /* ID: 191, value: 1, name: FdCheckSemAnoEvtExtEn, multiplicity: 1 */ + 1, + /* ID: 192, value: 1, name: RpSemAnoEvtIntEn, multiplicity: 1 */ + 1, + /* ID: 193, value: 1, name: RpSemAnoEvtExtEn, multiplicity: 1 */ + 1, + /* ID: 194, value: 0, name: FdCheckSemAnoEvtCnt, multiplicity: 1 */ + 0, + /* ID: 195, value: 0, name: FdCheckSemAnoEvtSpCnt, multiplicity: 1 */ + 0, + /* ID: 196, value: 1, name: FdCheckSemAnoEvtCntThr, multiplicity: 1 */ + 1, + /* ID: 197, value: NO_ACT, name: semAnoEvtResp_1, multiplicity: 1 */ + 1, + /* ID: 198, value: NO_ACT, name: semAnoEvtResp_2, multiplicity: 1 */ + 1, + /* ID: 199, value: NO_ACT, name: semAnoEvtResp_3, multiplicity: 1 */ + 1, + /* ID: 200, value: NO_ACT, name: semAnoEvtResp_4, multiplicity: 1 */ + 1, + /* ID: 201, value: NO_ACT, name: semAnoEvtResp_5, multiplicity: 1 */ + 1, + /* ID: 202, value: NO_ACT, name: semAnoEvtResp_6, multiplicity: 1 */ + 1, + /* ID: 203, value: NO_ACT, name: semAnoEvtResp_7, multiplicity: 1 */ + 1, + /* ID: 204, value: NO_ACT, name: semAnoEvtResp_8, multiplicity: 1 */ + 1, + /* ID: 205, value: NO_ACT, name: semAnoEvtResp_9, multiplicity: 1 */ + 1, + /* ID: 206, value: NO_ACT, name: semAnoEvtResp_10, multiplicity: 1 */ + 1, + /* ID: 207, value: NO_ACT, name: semAnoEvtResp_11, multiplicity: 1 */ + 1, + /* ID: 208, value: NO_ACT, name: semAnoEvtResp_12, multiplicity: 1 */ + 1, + /* ID: 209, value: NO_ACT, name: semAnoEvtResp_13, multiplicity: 1 */ + 1, + /* ID: 210, value: NO_ACT, name: semAnoEvtResp_14, multiplicity: 1 */ + 1, + /* ID: 211, value: NO_ACT, name: semAnoEvtResp_15, multiplicity: 1 */ + 1, + /* ID: 212, value: NO_ACT, name: semAnoEvtResp_16, multiplicity: 1 */ + 1, + /* ID: 213, value: NO_ACT, name: semAnoEvtResp_17, multiplicity: 1 */ + 1, + /* ID: 214, value: NO_ACT, name: semAnoEvtResp_18, multiplicity: 1 */ + 1, + /* ID: 215, value: NO_ACT, name: semAnoEvtResp_19, multiplicity: 1 */ + 1, + /* ID: 216, value: NO_ACT, name: semAnoEvtResp_20, multiplicity: 1 */ + 1, + /* ID: 217, value: NO_ACT, name: semAnoEvtResp_21, multiplicity: 1 */ + 1, + /* ID: 218, value: NO_ACT, name: semAnoEvtResp_22, multiplicity: 1 */ + 1, + /* ID: 219, value: NO_ACT, name: semAnoEvtResp_23, multiplicity: 1 */ + 1, + /* ID: 220, value: NO_ACT, name: semAnoEvtResp_24, multiplicity: 1 */ + 1, + /* ID: 221, value: NO_ACT, name: semAnoEvtResp_25, multiplicity: 1 */ + 1, + /* ID: 222, value: NO_ACT, name: semAnoEvtResp_26, multiplicity: 1 */ + 1, + /* ID: 223, value: NO_ACT, name: semAnoEvtResp_27, multiplicity: 1 */ + 1, + /* ID: 224, value: NO_ACT, name: semAnoEvtResp_28, multiplicity: 1 */ + 1, + /* ID: 225, value: NO_ACT, name: semAnoEvtResp_29, multiplicity: 1 */ + 1, + /* ID: 226, value: STOPPED, name: FdCheckSemLimitState, multiplicity: 1 */ + 0, + /* ID: 227, value: 0, name: FdCheckSemLimitIntEn, multiplicity: 1 */ + 0, + /* ID: 228, value: 1, name: FdCheckSemLimitExtEn, multiplicity: 1 */ + 1, + /* ID: 229, value: 1, name: RpSemLimitIntEn, multiplicity: 1 */ + 1, + /* ID: 230, value: 1, name: RpSemLimitExtEn, multiplicity: 1 */ + 1, + /* ID: 231, value: 0, name: FdCheckSemLimitCnt, multiplicity: 1 */ + 0, + /* ID: 232, value: 0, name: FdCheckSemLimitSpCnt, multiplicity: 1 */ + 0, + /* ID: 233, value: 1, name: FdCheckSemLimitCntThr, multiplicity: 1 */ + 1, + /* ID: 234, value: 336, name: SEM_LIM_DEL_T, multiplicity: 1 */ + 336, + /* ID: 235, value: STOPPED, name: FdCheckDpuHkState, multiplicity: 1 */ + 0, + /* ID: 236, value: 0, name: FdCheckDpuHkIntEn, multiplicity: 1 */ + 0, + /* ID: 237, value: 1, name: FdCheckDpuHkExtEn, multiplicity: 1 */ + 1, + /* ID: 238, value: 1, name: RpDpuHkIntEn, multiplicity: 1 */ + 1, + /* ID: 239, value: 1, name: RpDpuHkExtEn, multiplicity: 1 */ + 1, + /* ID: 240, value: 0, name: FdCheckDpuHkCnt, multiplicity: 1 */ + 0, + /* ID: 241, value: 0, name: FdCheckDpuHkSpCnt, multiplicity: 1 */ + 0, + /* ID: 242, value: 3, name: FdCheckDpuHkCntThr, multiplicity: 1 */ + 3, + /* ID: 243, value: STOPPED, name: FdCheckCentConsState, multiplicity: 1 */ + 0, + /* ID: 244, value: 0, name: FdCheckCentConsIntEn, multiplicity: 1 */ + 0, + /* ID: 245, value: 1, name: FdCheckCentConsExtEn, multiplicity: 1 */ + 1, + /* ID: 246, value: 1, name: RpCentConsIntEn, multiplicity: 1 */ + 1, + /* ID: 247, value: 1, name: RpCentConsExtEn, multiplicity: 1 */ + 1, + /* ID: 248, value: 0, name: FdCheckCentConsCnt, multiplicity: 1 */ + 0, + /* ID: 249, value: 0, name: FdCheckCentConsSpCnt, multiplicity: 1 */ + 0, + /* ID: 250, value: 1200, name: FdCheckCentConsCntThr, multiplicity: 1 */ + 1200, + /* ID: 251, value: STOPPED, name: FdCheckResState, multiplicity: 1 */ + 0, + /* ID: 252, value: 0, name: FdCheckResIntEn, multiplicity: 1 */ + 0, + /* ID: 253, value: 1, name: FdCheckResExtEn, multiplicity: 1 */ + 1, + /* ID: 254, value: 1, name: RpResIntEn, multiplicity: 1 */ + 1, + /* ID: 255, value: 1, name: RpResExtEn, multiplicity: 1 */ + 1, + /* ID: 256, value: 0, name: FdCheckResCnt, multiplicity: 1 */ + 0, + /* ID: 257, value: 0, name: FdCheckResSpCnt, multiplicity: 1 */ + 0, + /* ID: 258, value: 3, name: FdCheckResCntThr, multiplicity: 1 */ + 3, + /* ID: 259, value: 0.99, name: CPU1_USAGE_MAX, multiplicity: 1 */ + 0.99, + /* ID: 260, value: 0.95, name: MEM_USAGE_MAX, multiplicity: 1 */ + 0.95, + /* ID: 261, value: STOPPED, name: FdCheckSemCons, multiplicity: 1 */ + 0, + /* ID: 262, value: 0, name: FdCheckSemConsIntEn, multiplicity: 1 */ + 0, + /* ID: 263, value: 1, name: FdCheckSemConsExtEn, multiplicity: 1 */ + 1, + /* ID: 264, value: 1, name: RpSemConsIntEn, multiplicity: 1 */ + 1, + /* ID: 265, value: 1, name: RpSemConsExtEn, multiplicity: 1 */ + 1, + /* ID: 266, value: 0, name: FdCheckSemConsCnt, multiplicity: 1 */ + 0, + /* ID: 267, value: 0, name: FdCheckSemConsSpCnt, multiplicity: 1 */ + 0, + /* ID: 268, value: 640, name: FdCheckSemConsCntThr, multiplicity: 1 */ + 640, + /* ID: 269, value: STOPPED, name: semState, multiplicity: 1 */ + 0, + /* ID: 270, value: STOPPED, name: semOperState, multiplicity: 1 */ + 0, + /* ID: 271, value: 0, name: semStateCnt, multiplicity: 1 */ + 0, + /* ID: 272, value: 0, name: semOperStateCnt, multiplicity: 1 */ + 0, + /* ID: 273, value: 0, name: imageCycleCnt, multiplicity: 1 */ + 0, + /* ID: 274, value: 0, name: acqImageCnt, multiplicity: 1 */ + 0, + /* ID: 275, value: FAINT, name: sciSubMode, multiplicity: 1 */ + 0, + /* ID: 276, value: 0, name: LastSemPckt, multiplicity: 1 */ + 0, + /* ID: 277, value: 37, name: SEM_ON_CODE, multiplicity: 1 */ + 37, + /* ID: 278, value: 154, name: SEM_OFF_CODE, multiplicity: 1 */ + 154, + /* ID: 279, value: 4, name: SEM_INIT_T1, multiplicity: 1 */ + 4, + /* ID: 280, value: 320, name: SEM_INIT_T2, multiplicity: 1 */ + 320, + /* ID: 281, value: 480, name: SEM_OPER_T1, multiplicity: 1 */ + 480, + /* ID: 282, value: 54, name: SEM_SHUTDOWN_T1, multiplicity: 1 */ + 54, + /* ID: 283, value: 54, name: SEM_SHUTDOWN_T11, multiplicity: 1 */ + 54, + /* ID: 284, value: 582, name: SEM_SHUTDOWN_T12, multiplicity: 1 */ + 582, + /* ID: 285, value: 4, name: SEM_SHUTDOWN_T2, multiplicity: 1 */ + 4, + /* ID: 286, value: STOPPED, name: iaswState, multiplicity: 1 */ + 0, + /* ID: 287, value: 0, name: iaswStateCnt, multiplicity: 1 */ + 0, + /* ID: 288, value: 0, name: iaswCycleCnt, multiplicity: 1 */ + 0, + /* ID: 289, value: STOPPED, name: prepScienceNode, multiplicity: 1 */ + 0, + /* ID: 290, value: 0, name: prepScienceCnt, multiplicity: 1 */ + 0, + /* ID: 291, value: STOPPED, name: controlledSwitchOffNode, multiplicity: 1 */ + 0, + /* ID: 292, value: 0, name: controlledSwitchOffCnt, multiplicity: 1 */ + 0, + /* ID: 293, value: 60, name: CTRLD_SWITCH_OFF_T1, multiplicity: 1 */ + 60, + /* ID: 294, value: STOPPED, name: algoCent0State, multiplicity: 1 */ + 0, + /* ID: 295, value: 0, name: algoCent0Cnt, multiplicity: 1 */ + 0, + /* ID: 296, value: 0, name: algoCent0Enabled, multiplicity: 1 */ + 0, + /* ID: 297, value: STOPPED, name: algoCent1State, multiplicity: 1 */ + 0, + /* ID: 298, value: 0, name: algoCent1Cnt, multiplicity: 1 */ + 0, + /* ID: 299, value: 0, name: algoCent1Enabled, multiplicity: 1 */ + 0, + /* ID: 300, value: 4, name: CENT_EXEC_PHASE, multiplicity: 1 */ + 4, + /* ID: 301, value: STOPPED, name: algoAcq1State, multiplicity: 1 */ + 0, + /* ID: 302, value: 0, name: algoAcq1Cnt, multiplicity: 1 */ + 0, + /* ID: 303, value: 0, name: algoAcq1Enabled, multiplicity: 1 */ + 0, + /* ID: 304, value: 32, name: ACQ_PH, multiplicity: 1 */ + 32, + /* ID: 305, value: STOPPED, name: algoCcState, multiplicity: 1 */ + 0, + /* ID: 306, value: 0, name: algoCcCnt, multiplicity: 1 */ + 0, + /* ID: 307, value: 1, name: algoCcEnabled, multiplicity: 1 */ + 1, + /* ID: 308, value: 1, name: STCK_ORDER, multiplicity: 1 */ + 1, + /* ID: 309, value: STOPPED, name: algoTTC1State, multiplicity: 1 */ + 0, + /* ID: 310, value: 0, name: algoTTC1Cnt, multiplicity: 1 */ + 0, + /* ID: 311, value: 0, name: algoTTC1Enabled, multiplicity: 1 */ + 0, + /* ID: 312, value: 1, name: TTC1_EXEC_PHASE, multiplicity: 1 */ + 1, + /* ID: 313, value: 40, name: TTC1_EXEC_PER, multiplicity: 1 */ + 40, + /* ID: 314, value: -24, name: TTC1_LL_FRT, multiplicity: 1 */ + -24, + /* ID: 315, value: -24, name: TTC1_LL_AFT, multiplicity: 1 */ + -24, + /* ID: 316, value: -5, name: TTC1_UL_FRT, multiplicity: 1 */ + -5, + /* ID: 317, value: -5, name: TTC1_UL_AFT, multiplicity: 1 */ + -5, + /* ID: 318, value: 0, name: ttc1AvTempAft, multiplicity: 1 */ + 0, + /* ID: 319, value: 0, name: ttc1AvTempFrt, multiplicity: 1 */ + 0, + /* ID: 320, value: STOPPED, name: algoTTC2State, multiplicity: 1 */ + 0, + /* ID: 321, value: 0, name: algoTTC2Cnt, multiplicity: 1 */ + 0, + /* ID: 322, value: 1, name: algoTTC2Enabled, multiplicity: 1 */ + 1, + /* ID: 323, value: 80, name: TTC2_EXEC_PER, multiplicity: 1 */ + 80, + /* ID: 324, value: -10, name: TTC2_REF_TEMP, multiplicity: 1 */ + -10, + /* ID: 325, value: 2.5, name: TTC2_OFFSETA, multiplicity: 1 */ + 2.5, + /* ID: 326, value: 3.7, name: TTC2_OFFSETF, multiplicity: 1 */ + 3.7, + /* ID: 327, value: 0, name: intTimeAft, multiplicity: 1 */ + 0, + /* ID: 328, value: 0, name: onTimeAft, multiplicity: 1 */ + 0, + /* ID: 329, value: 0, name: intTimeFront, multiplicity: 1 */ + 0, + /* ID: 330, value: 0, name: onTimeFront, multiplicity: 1 */ + 0, + /* ID: 331, value: 10, name: TTC2_PA, multiplicity: 1 */ + 10, + /* ID: 332, value: 0, name: TTC2_DA, multiplicity: 1 */ + 0, + /* ID: 333, value: 0.003, name: TTC2_IA, multiplicity: 1 */ + 0.003, + /* ID: 334, value: 10, name: TTC2_PF, multiplicity: 1 */ + 10, + /* ID: 335, value: 0, name: TTC2_DF, multiplicity: 1 */ + 0, + /* ID: 336, value: 0.003, name: TTC2_IF, multiplicity: 1 */ + 0.003, + /* ID: 337, value: STOPPED, name: algoSaaEvalState, multiplicity: 1 */ + 0, + /* ID: 338, value: 0, name: algoSaaEvalCnt, multiplicity: 1 */ + 0, + /* ID: 339, value: 0, name: algoSaaEvalEnabled, multiplicity: 1 */ + 0, + /* ID: 340, value: 1, name: SAA_EXEC_PHASE, multiplicity: 1 */ + 1, + /* ID: 341, value: 40, name: SAA_EXEC_PER, multiplicity: 1 */ + 40, + /* ID: 342, value: 0, name: isSaaActive, multiplicity: 1 */ + 0, + /* ID: 343, value: 0, name: saaCounter, multiplicity: 1 */ + 0, + /* ID: 344, value: 0, name: pInitSaaCounter, multiplicity: 1 */ + 0, + /* ID: 345, value: STOPPED, name: algoSdsEvalState, multiplicity: 1 */ + 0, + /* ID: 346, value: 0, name: algoSdsEvalCnt, multiplicity: 1 */ + 0, + /* ID: 347, value: 1, name: algoSdsEvalEnabled, multiplicity: 1 */ + 1, + /* ID: 348, value: 1, name: SDS_EXEC_PHASE, multiplicity: 1 */ + 1, + /* ID: 349, value: 40, name: SDS_EXEC_PER, multiplicity: 1 */ + 40, + /* ID: 350, value: 0, name: isSdsActive, multiplicity: 1 */ + 0, + /* ID: 351, value: 0, name: SDS_FORCED, multiplicity: 1 */ + 0, + /* ID: 352, value: 0, name: SDS_INHIBITED, multiplicity: 1 */ + 0, + /* ID: 353, value: 0, name: EARTH_OCCULT_ACTIVE, multiplicity: 1 */ + 0, + /* ID: 354, value: 21845, name: HEARTBEAT_D1, multiplicity: 1 */ + 21845, + /* ID: 355, value: 43690, name: HEARTBEAT_D2, multiplicity: 1 */ + 43690, + /* ID: 356, value: 1, name: HbSem, multiplicity: 1 */ + 1, + /* ID: 357, value: 0, name: starMap, multiplicity: 276 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 358, value: 0, name: observationId, multiplicity: 1 */ + 0, + /* ID: 359, value: 0, name: centValProcOutput, multiplicity: 1 */ + 0, + /* ID: 360, value: 0.5, name: CENT_OFFSET_LIM, multiplicity: 1 */ + 0.5, + /* ID: 361, value: 3, name: CENT_FROZEN_LIM, multiplicity: 1 */ + 3, + /* ID: 362, value: 0, name: SEM_SERV1_1_FORWARD, multiplicity: 1 */ + 0, + /* ID: 363, value: 1, name: SEM_SERV1_2_FORWARD, multiplicity: 1 */ + 1, + /* ID: 364, value: 0, name: SEM_SERV1_7_FORWARD, multiplicity: 1 */ + 0, + /* ID: 365, value: 1, name: SEM_SERV1_8_FORWARD, multiplicity: 1 */ + 1, + /* ID: 366, value: 0, name: SEM_SERV3_1_FORWARD, multiplicity: 1 */ + 0, + /* ID: 367, value: 0, name: SEM_SERV3_2_FORWARD, multiplicity: 1 */ + 0, + /* ID: 368, value: 0, name: SEM_HK_TS_DEF_CRS, multiplicity: 1 */ + 0, + /* ID: 369, value: 0, name: SEM_HK_TS_DEF_FINE, multiplicity: 1 */ + 0, + /* ID: 370, value: 0, name: SEM_HK_TS_EXT_CRS, multiplicity: 1 */ + 0, + /* ID: 371, value: 0, name: SEM_HK_TS_EXT_FINE, multiplicity: 1 */ + 0, + /* ID: 372, value: SAFE, name: STAT_MODE, multiplicity: 1 */ + 1, + /* ID: 373, value: 0, name: STAT_FLAGS, multiplicity: 1 */ + 0, + /* ID: 374, value: NO_ERR, name: STAT_LAST_SPW_ERR, multiplicity: 1 */ + 0, + /* ID: 375, value: 0, name: STAT_LAST_ERR_ID, multiplicity: 1 */ + 0, + /* ID: 376, value: 0, name: STAT_LAST_ERR_FREQ, multiplicity: 1 */ + 0, + /* ID: 377, value: 0, name: STAT_NUM_CMD_RECEIVED, multiplicity: 1 */ + 0, + /* ID: 378, value: 0, name: STAT_NUM_CMD_EXECUTED, multiplicity: 1 */ + 0, + /* ID: 379, value: 0, name: STAT_NUM_DATA_SENT, multiplicity: 1 */ + 0, + /* ID: 380, value: 0, name: STAT_SCU_PROC_DUTY_CL, multiplicity: 1 */ + 0, + /* ID: 381, value: 0, name: STAT_SCU_NUM_AHB_ERR, multiplicity: 1 */ + 0, + /* ID: 382, value: 0, name: STAT_SCU_NUM_AHB_CERR, multiplicity: 1 */ + 0, + /* ID: 383, value: 0, name: STAT_SCU_NUM_LUP_ERR, multiplicity: 1 */ + 0, + /* ID: 384, value: 0, name: TEMP_SEM_SCU, multiplicity: 1 */ + 0, + /* ID: 385, value: 0, name: TEMP_SEM_PCU, multiplicity: 1 */ + 0, + /* ID: 386, value: 0, name: VOLT_SCU_P3_4, multiplicity: 1 */ + 0, + /* ID: 387, value: 0, name: VOLT_SCU_P5, multiplicity: 1 */ + 0, + /* ID: 388, value: 0, name: TEMP_FEE_CCD, multiplicity: 1 */ + 0, + /* ID: 389, value: 0, name: TEMP_FEE_STRAP, multiplicity: 1 */ + 0, + /* ID: 390, value: 0, name: TEMP_FEE_ADC, multiplicity: 1 */ + 0, + /* ID: 391, value: 0, name: TEMP_FEE_BIAS, multiplicity: 1 */ + 0, + /* ID: 392, value: 0, name: TEMP_FEE_DEB, multiplicity: 1 */ + 0, + /* ID: 393, value: 0, name: VOLT_FEE_VOD, multiplicity: 1 */ + 0, + /* ID: 394, value: 0, name: VOLT_FEE_VRD, multiplicity: 1 */ + 0, + /* ID: 395, value: 0, name: VOLT_FEE_VOG, multiplicity: 1 */ + 0, + /* ID: 396, value: 0, name: VOLT_FEE_VSS, multiplicity: 1 */ + 0, + /* ID: 397, value: 0, name: VOLT_FEE_CCD, multiplicity: 1 */ + 0, + /* ID: 398, value: 0, name: VOLT_FEE_CLK, multiplicity: 1 */ + 0, + /* ID: 399, value: 0, name: VOLT_FEE_ANA_P5, multiplicity: 1 */ + 0, + /* ID: 400, value: 0, name: VOLT_FEE_ANA_N5, multiplicity: 1 */ + 0, + /* ID: 401, value: 0, name: VOLT_FEE_ANA_P3_3, multiplicity: 1 */ + 0, + /* ID: 402, value: 0, name: CURR_FEE_CLK_BUF, multiplicity: 1 */ + 0, + /* ID: 403, value: 0, name: VOLT_SCU_FPGA_P1_5, multiplicity: 1 */ + 0, + /* ID: 404, value: 0, name: CURR_SCU_P3_4, multiplicity: 1 */ + 0, + /* ID: 405, value: 0, name: STAT_NUM_SPW_ERR_CRE, multiplicity: 1 */ + 0, + /* ID: 406, value: 0, name: STAT_NUM_SPW_ERR_ESC, multiplicity: 1 */ + 0, + /* ID: 407, value: 0, name: STAT_NUM_SPW_ERR_DISC, multiplicity: 1 */ + 0, + /* ID: 408, value: 0, name: STAT_NUM_SPW_ERR_PAR, multiplicity: 1 */ + 0, + /* ID: 409, value: 0, name: STAT_NUM_SPW_ERR_WRSY, multiplicity: 1 */ + 0, + /* ID: 410, value: 0, name: STAT_NUM_SPW_ERR_INVA, multiplicity: 1 */ + 0, + /* ID: 411, value: 0, name: STAT_NUM_SPW_ERR_EOP, multiplicity: 1 */ + 0, + /* ID: 412, value: 0, name: STAT_NUM_SPW_ERR_RXAH, multiplicity: 1 */ + 0, + /* ID: 413, value: 0, name: STAT_NUM_SPW_ERR_TXAH, multiplicity: 1 */ + 0, + /* ID: 414, value: 0, name: STAT_NUM_SPW_ERR_TXBL, multiplicity: 1 */ + 0, + /* ID: 415, value: 0, name: STAT_NUM_SPW_ERR_TXLE, multiplicity: 1 */ + 0, + /* ID: 416, value: 0, name: STAT_NUM_SP_ERR_RX, multiplicity: 1 */ + 0, + /* ID: 417, value: 0, name: STAT_NUM_SP_ERR_TX, multiplicity: 1 */ + 0, + /* ID: 418, value: 0, name: STAT_HEAT_PWM_FPA_CCD, multiplicity: 1 */ + 0, + /* ID: 419, value: 0, name: STAT_HEAT_PWM_FEE_STR, multiplicity: 1 */ + 0, + /* ID: 420, value: 0, name: STAT_HEAT_PWM_FEE_ANA, multiplicity: 1 */ + 0, + /* ID: 421, value: 0, name: STAT_HEAT_PWM_SPARE, multiplicity: 1 */ + 0, + /* ID: 422, value: 0, name: STAT_HEAT_PWM_FLAGS, multiplicity: 1 */ + 0, + /* ID: 423, value: 0, name: STAT_OBTIME_SYNC_DELTA, multiplicity: 1 */ + 0, + /* ID: 424, value: -20, name: TEMP_SEM_SCU_LW, multiplicity: 1 */ + -20, + /* ID: 425, value: -20, name: TEMP_SEM_PCU_LW, multiplicity: 1 */ + -20, + /* ID: 426, value: 3.2, name: VOLT_SCU_P3_4_LW, multiplicity: 1 */ + 3.2, + /* ID: 427, value: 4.8, name: VOLT_SCU_P5_LW, multiplicity: 1 */ + 4.8, + /* ID: 428, value: -60, name: TEMP_FEE_CCD_LW, multiplicity: 1 */ + -60, + /* ID: 429, value: -20, name: TEMP_FEE_STRAP_LW, multiplicity: 1 */ + -20, + /* ID: 430, value: -20, name: TEMP_FEE_ADC_LW, multiplicity: 1 */ + -20, + /* ID: 431, value: -20, name: TEMP_FEE_BIAS_LW, multiplicity: 1 */ + -20, + /* ID: 432, value: -20, name: TEMP_FEE_DEB_LW, multiplicity: 1 */ + -20, + /* ID: 433, value: 0, name: VOLT_FEE_VOD_LW, multiplicity: 1 */ + 0, + /* ID: 434, value: 0, name: VOLT_FEE_VRD_LW, multiplicity: 1 */ + 0, + /* ID: 435, value: 0, name: VOLT_FEE_VOG_LW, multiplicity: 1 */ + 0, + /* ID: 436, value: 0, name: VOLT_FEE_VSS_LW, multiplicity: 1 */ + 0, + /* ID: 437, value: 0, name: VOLT_FEE_CCD_LW, multiplicity: 1 */ + 0, + /* ID: 438, value: 0, name: VOLT_FEE_CLK_LW, multiplicity: 1 */ + 0, + /* ID: 439, value: 0, name: VOLT_FEE_ANA_P5_LW, multiplicity: 1 */ + 0, + /* ID: 440, value: -6, name: VOLT_FEE_ANA_N5_LW, multiplicity: 1 */ + -6, + /* ID: 441, value: 0, name: VOLT_FEE_ANA_P3_3_LW, multiplicity: 1 */ + 0, + /* ID: 442, value: 0, name: CURR_FEE_CLK_BUF_LW, multiplicity: 1 */ + 0, + /* ID: 443, value: 1.3, name: VOLT_SCU_FPGA_P1_5_LW, multiplicity: 1 */ + 1.3, + /* ID: 444, value: 50, name: CURR_SCU_P3_4_LW, multiplicity: 1 */ + 50, + /* ID: 445, value: 80, name: TEMP_SEM_SCU_UW, multiplicity: 1 */ + 80, + /* ID: 446, value: 80, name: TEMP_SEM_PCU_UW, multiplicity: 1 */ + 80, + /* ID: 447, value: 3.8, name: VOLT_SCU_P3_4_UW, multiplicity: 1 */ + 3.8, + /* ID: 448, value: 5.6, name: VOLT_SCU_P5_UW, multiplicity: 1 */ + 5.6, + /* ID: 449, value: 40, name: TEMP_FEE_CCD_UW, multiplicity: 1 */ + 40, + /* ID: 450, value: 60, name: TEMP_FEE_STRAP_UW, multiplicity: 1 */ + 60, + /* ID: 451, value: 60, name: TEMP_FEE_ADC_UW, multiplicity: 1 */ + 60, + /* ID: 452, value: 60, name: TEMP_FEE_BIAS_UW, multiplicity: 1 */ + 60, + /* ID: 453, value: 60, name: TEMP_FEE_DEB_UW, multiplicity: 1 */ + 60, + /* ID: 454, value: 32, name: VOLT_FEE_VOD_UW, multiplicity: 1 */ + 32, + /* ID: 455, value: 19, name: VOLT_FEE_VRD_UW, multiplicity: 1 */ + 19, + /* ID: 456, value: 3.5, name: VOLT_FEE_VOG_UW, multiplicity: 1 */ + 3.5, + /* ID: 457, value: 10, name: VOLT_FEE_VSS_UW, multiplicity: 1 */ + 10, + /* ID: 458, value: 37, name: VOLT_FEE_CCD_UW, multiplicity: 1 */ + 37, + /* ID: 459, value: 17, name: VOLT_FEE_CLK_UW, multiplicity: 1 */ + 17, + /* ID: 460, value: 7, name: VOLT_FEE_ANA_P5_UW, multiplicity: 1 */ + 7, + /* ID: 461, value: 0, name: VOLT_FEE_ANA_N5_UW, multiplicity: 1 */ + 0, + /* ID: 462, value: 4, name: VOLT_FEE_ANA_P3_3_UW, multiplicity: 1 */ + 4, + /* ID: 463, value: 100, name: CURR_FEE_CLK_BUF_UW, multiplicity: 1 */ + 100, + /* ID: 464, value: 1.7, name: VOLT_SCU_FPGA_P1_5_UW, multiplicity: 1 */ + 1.7, + /* ID: 465, value: 700, name: CURR_SCU_P3_4_UW, multiplicity: 1 */ + 700, + /* ID: 466, value: -30, name: TEMP_SEM_SCU_LA, multiplicity: 1 */ + -30, + /* ID: 467, value: -30, name: TEMP_SEM_PCU_LA, multiplicity: 1 */ + -30, + /* ID: 468, value: 3, name: VOLT_SCU_P3_4_LA, multiplicity: 1 */ + 3, + /* ID: 469, value: 4.5, name: VOLT_SCU_P5_LA, multiplicity: 1 */ + 4.5, + /* ID: 470, value: -60, name: TEMP_FEE_CCD_LA, multiplicity: 1 */ + -60, + /* ID: 471, value: -30, name: TEMP_FEE_STRAP_LA, multiplicity: 1 */ + -30, + /* ID: 472, value: -30, name: TEMP_FEE_ADC_LA, multiplicity: 1 */ + -30, + /* ID: 473, value: -30, name: TEMP_FEE_BIAS_LA, multiplicity: 1 */ + -30, + /* ID: 474, value: -30, name: TEMP_FEE_DEB_LA, multiplicity: 1 */ + -30, + /* ID: 475, value: 0, name: VOLT_FEE_VOD_LA, multiplicity: 1 */ + 0, + /* ID: 476, value: 0, name: VOLT_FEE_VRD_LA, multiplicity: 1 */ + 0, + /* ID: 477, value: 0, name: VOLT_FEE_VOG_LA, multiplicity: 1 */ + 0, + /* ID: 478, value: 0, name: VOLT_FEE_VSS_LA, multiplicity: 1 */ + 0, + /* ID: 479, value: 0, name: VOLT_FEE_CCD_LA, multiplicity: 1 */ + 0, + /* ID: 480, value: 0, name: VOLT_FEE_CLK_LA, multiplicity: 1 */ + 0, + /* ID: 481, value: 0, name: VOLT_FEE_ANA_P5_LA, multiplicity: 1 */ + 0, + /* ID: 482, value: -7, name: VOLT_FEE_ANA_N5_LA, multiplicity: 1 */ + -7, + /* ID: 483, value: 0, name: VOLT_FEE_ANA_P3_3_LA, multiplicity: 1 */ + 0, + /* ID: 484, value: 0, name: CURR_FEE_CLK_BUF_LA, multiplicity: 1 */ + 0, + /* ID: 485, value: 1, name: VOLT_SCU_FPGA_P1_5_LA, multiplicity: 1 */ + 1, + /* ID: 486, value: 0, name: CURR_SCU_P3_4_LA, multiplicity: 1 */ + 0, + /* ID: 487, value: 90, name: TEMP_SEM_SCU_UA, multiplicity: 1 */ + 90, + /* ID: 488, value: 90, name: TEMP_SEM_PCU_UA, multiplicity: 1 */ + 90, + /* ID: 489, value: 4, name: VOLT_SCU_P3_4_UA, multiplicity: 1 */ + 4, + /* ID: 490, value: 5.8, name: VOLT_SCU_P5_UA, multiplicity: 1 */ + 5.8, + /* ID: 491, value: 40, name: TEMP_FEE_CCD_UA, multiplicity: 1 */ + 40, + /* ID: 492, value: 70, name: TEMP_FEE_STRAP_UA, multiplicity: 1 */ + 70, + /* ID: 493, value: 70, name: TEMP_FEE_ADC_UA, multiplicity: 1 */ + 70, + /* ID: 494, value: 70, name: TEMP_FEE_BIAS_UA, multiplicity: 1 */ + 70, + /* ID: 495, value: 70, name: TEMP_FEE_DEB_UA, multiplicity: 1 */ + 70, + /* ID: 496, value: 33, name: VOLT_FEE_VOD_UA, multiplicity: 1 */ + 33, + /* ID: 497, value: 20, name: VOLT_FEE_VRD_UA, multiplicity: 1 */ + 20, + /* ID: 498, value: 4, name: VOLT_FEE_VOG_UA, multiplicity: 1 */ + 4, + /* ID: 499, value: 11, name: VOLT_FEE_VSS_UA, multiplicity: 1 */ + 11, + /* ID: 500, value: 38, name: VOLT_FEE_CCD_UA, multiplicity: 1 */ + 38, + /* ID: 501, value: 20, name: VOLT_FEE_CLK_UA, multiplicity: 1 */ + 20, + /* ID: 502, value: 8, name: VOLT_FEE_ANA_P5_UA, multiplicity: 1 */ + 8, + /* ID: 503, value: 0, name: VOLT_FEE_ANA_N5_UA, multiplicity: 1 */ + 0, + /* ID: 504, value: 5, name: VOLT_FEE_ANA_P3_3_UA, multiplicity: 1 */ + 5, + /* ID: 505, value: 200, name: CURR_FEE_CLK_BUF_UA, multiplicity: 1 */ + 200, + /* ID: 506, value: 3, name: VOLT_SCU_FPGA_P1_5_UA, multiplicity: 1 */ + 3, + /* ID: 507, value: 900, name: CURR_SCU_P3_4_UA, multiplicity: 1 */ + 900, + /* ID: 508, value: 0, name: semEvtCounter, multiplicity: 1 */ + 0, + /* ID: 509, value: 0, name: SEM_SERV5_1_FORWARD, multiplicity: 1 */ + 0, + /* ID: 510, value: 1, name: SEM_SERV5_2_FORWARD, multiplicity: 1 */ + 1, + /* ID: 511, value: 1, name: SEM_SERV5_3_FORWARD, multiplicity: 1 */ + 1, + /* ID: 512, value: 1, name: SEM_SERV5_4_FORWARD, multiplicity: 1 */ + 1, + /* ID: 513, value: 0, name: pExpTime, multiplicity: 1 */ + 0, + /* ID: 514, value: 0, name: pImageRep, multiplicity: 1 */ + 0, + /* ID: 515, value: 604800, name: pAcqNum, multiplicity: 1 */ + 604800, + /* ID: 516, value: NO, name: pDataOs, multiplicity: 1 */ + 0, + /* ID: 517, value: FAINT, name: pCcdRdMode, multiplicity: 1 */ + 0, + /* ID: 518, value: 0, name: pWinPosX, multiplicity: 1 */ + 0, + /* ID: 519, value: 1, name: pWinPosY, multiplicity: 1 */ + 1, + /* ID: 520, value: 200, name: pWinSizeX, multiplicity: 1 */ + 200, + /* ID: 521, value: 200, name: pWinSizeY, multiplicity: 1 */ + 200, + /* ID: 522, value: CCD, name: pDtAcqSrc, multiplicity: 1 */ + 0, + /* ID: 523, value: CCD_FEE, name: pTempCtrlTarget, multiplicity: 1 */ + 3, + /* ID: 524, value: 30.8, name: pVoltFeeVod, multiplicity: 1 */ + 30.8, + /* ID: 525, value: 17.8, name: pVoltFeeVrd, multiplicity: 1 */ + 17.8, + /* ID: 526, value: 8.8, name: pVoltFeeVss, multiplicity: 1 */ + 8.8, + /* ID: 527, value: -40, name: pHeatTempFpaCCd, multiplicity: 1 */ + -40, + /* ID: 528, value: -10, name: pHeatTempFeeStrap, multiplicity: 1 */ + -10, + /* ID: 529, value: -10, name: pHeatTempFeeAnach, multiplicity: 1 */ + -10, + /* ID: 530, value: -10, name: pHeatTempSpare, multiplicity: 1 */ + -10, + /* ID: 531, value: YES, name: pStepEnDiagCcd, multiplicity: 1 */ + 1, + /* ID: 532, value: YES, name: pStepEnDiagFee, multiplicity: 1 */ + 1, + /* ID: 533, value: YES, name: pStepEnDiagTemp, multiplicity: 1 */ + 1, + /* ID: 534, value: YES, name: pStepEnDiagAna, multiplicity: 1 */ + 1, + /* ID: 535, value: NO, name: pStepEnDiagExpos, multiplicity: 1 */ + 0, + /* ID: 536, value: OFF, name: pStepDebDiagCcd, multiplicity: 1 */ + 0, + /* ID: 537, value: OFF, name: pStepDebDiagFee, multiplicity: 1 */ + 0, + /* ID: 538, value: OFF, name: pStepDebDiagTemp, multiplicity: 1 */ + 0, + /* ID: 539, value: OFF, name: pStepDebDiagAna, multiplicity: 1 */ + 0, + /* ID: 540, value: OFF, name: pStepDebDiagExpos, multiplicity: 1 */ + 0, + /* ID: 541, value: 1, name: SEM_SERV220_6_FORWARD, multiplicity: 1 */ + 1, + /* ID: 542, value: 1, name: SEM_SERV220_12_FORWARD, multiplicity: 1 */ + 1, + /* ID: 543, value: 1, name: SEM_SERV222_6_FORWARD, multiplicity: 1 */ + 1, + /* ID: 544, value: STOPPED, name: saveImagesNode, multiplicity: 1 */ + 0, + /* ID: 545, value: 0, name: saveImagesCnt, multiplicity: 1 */ + 0, + /* ID: 546, value: GROUND, name: SaveImages_pSaveTarget, multiplicity: 1 */ + 0, + /* ID: 547, value: 1, name: SaveImages_pFbfInit, multiplicity: 1 */ + 1, + /* ID: 548, value: 1, name: SaveImages_pFbfEnd, multiplicity: 1 */ + 1, + /* ID: 549, value: STOPPED, name: acqFullDropNode, multiplicity: 1 */ + 0, + /* ID: 550, value: 0, name: acqFullDropCnt, multiplicity: 1 */ + 0, + /* ID: 551, value: 0, name: AcqFullDrop_pExpTime, multiplicity: 1 */ + 0, + /* ID: 552, value: 0, name: AcqFullDrop_pImageRep, multiplicity: 1 */ + 0, + /* ID: 553, value: 8, name: acqFullDropT1, multiplicity: 1 */ + 8, + /* ID: 554, value: 8, name: acqFullDropT2, multiplicity: 1 */ + 8, + /* ID: 555, value: STOPPED, name: calFullSnapNode, multiplicity: 1 */ + 0, + /* ID: 556, value: 0, name: calFullSnapCnt, multiplicity: 1 */ + 0, + /* ID: 557, value: 0, name: CalFullSnap_pExpTime, multiplicity: 1 */ + 0, + /* ID: 558, value: 0, name: CalFullSnap_pImageRep, multiplicity: 1 */ + 0, + /* ID: 559, value: 0, name: CalFullSnap_pNmbImages, multiplicity: 1 */ + 0, + /* ID: 560, value: DEF_CENT, name: CalFullSnap_pCentSel, multiplicity: 1 */ + 2, + /* ID: 561, value: 8, name: calFullSnapT1, multiplicity: 1 */ + 8, + /* ID: 562, value: 8, name: calFullSnapT2, multiplicity: 1 */ + 8, + /* ID: 563, value: STOPPED, name: SciWinNode, multiplicity: 1 */ + 0, + /* ID: 564, value: 0, name: SciWinCnt, multiplicity: 1 */ + 0, + /* ID: 565, value: 0, name: SciWin_pNmbImages, multiplicity: 1 */ + 0, + /* ID: 566, value: FAINT, name: SciWin_pCcdRdMode, multiplicity: 1 */ + 0, + /* ID: 567, value: 0, name: SciWin_pExpTime, multiplicity: 1 */ + 0, + /* ID: 568, value: 0, name: SciWin_pImageRep, multiplicity: 1 */ + 0, + /* ID: 569, value: 0, name: SciWin_pWinPosX, multiplicity: 1 */ + 0, + /* ID: 570, value: 1, name: SciWin_pWinPosY, multiplicity: 1 */ + 1, + /* ID: 571, value: 200, name: SciWin_pWinSizeX, multiplicity: 1 */ + 200, + /* ID: 572, value: 200, name: SciWin_pWinSizeY, multiplicity: 1 */ + 200, + /* ID: 573, value: NO_CENT, name: SciWin_pCentSel, multiplicity: 1 */ + 1, + /* ID: 574, value: 8, name: sciWinT1, multiplicity: 1 */ + 8, + /* ID: 575, value: 8, name: sciWinT2, multiplicity: 1 */ + 8, + /* ID: 576, value: STOPPED, name: fbfLoadNode, multiplicity: 1 */ + 0, + /* ID: 577, value: 0, name: fbfLoadCnt, multiplicity: 1 */ + 0, + /* ID: 578, value: STOPPED, name: fbfSaveNode, multiplicity: 1 */ + 0, + /* ID: 579, value: 0, name: fbfSaveCnt, multiplicity: 1 */ + 0, + /* ID: 580, value: 0, name: FbfLoad_pFbfId, multiplicity: 1 */ + 0, + /* ID: 581, value: 0, name: FbfLoad_pFbfNBlocks, multiplicity: 1 */ + 0, + /* ID: 582, value: 0, name: FbfLoad_pFbfRamAreaId, multiplicity: 1 */ + 0, + /* ID: 583, value: 0, name: FbfLoad_pFbfRamAddr, multiplicity: 1 */ + 0, + /* ID: 584, value: 0, name: FbfSave_pFbfId, multiplicity: 1 */ + 0, + /* ID: 585, value: 3, name: FbfSave_pFbfNBlocks, multiplicity: 1 */ + 3, + /* ID: 586, value: 0, name: FbfSave_pFbfRamAreaId, multiplicity: 1 */ + 0, + /* ID: 587, value: 0, name: FbfSave_pFbfRamAddr, multiplicity: 1 */ + 0, + /* ID: 588, value: 0, name: fbfLoadBlockCounter, multiplicity: 1 */ + 0, + /* ID: 589, value: 0, name: fbfSaveBlockCounter, multiplicity: 1 */ + 0, + /* ID: 590, value: STOPPED, name: transFbfToGrndNode, multiplicity: 1 */ + 0, + /* ID: 591, value: 0, name: transFbfToGrndCnt, multiplicity: 1 */ + 0, + /* ID: 592, value: 0, name: TransFbfToGrnd_pNmbFbf, multiplicity: 1 */ + 0, + /* ID: 593, value: 0, name: TransFbfToGrnd_pFbfInit, multiplicity: 1 */ + 0, + /* ID: 594, value: 0, name: TransFbfToGrnd_pFbfSize, multiplicity: 1 */ + 0, + /* ID: 595, value: STOPPED, name: nomSciNode, multiplicity: 1 */ + 0, + /* ID: 596, value: 0, name: nomSciCnt, multiplicity: 1 */ + 0, + /* ID: 597, value: 0, name: NomSci_pAcqFlag, multiplicity: 1 */ + 0, + /* ID: 598, value: 0, name: NomSci_pCal1Flag, multiplicity: 1 */ + 0, + /* ID: 599, value: 0, name: NomSci_pSciFlag, multiplicity: 1 */ + 0, + /* ID: 600, value: 0, name: NomSci_pCal2Flag, multiplicity: 1 */ + 0, + /* ID: 601, value: 0, name: NomSci_pCibNFull, multiplicity: 1 */ + 0, + /* ID: 602, value: 0, name: NomSci_pCibSizeFull, multiplicity: 1 */ + 0, + /* ID: 603, value: 0, name: NomSci_pSibNFull, multiplicity: 1 */ + 0, + /* ID: 604, value: 0, name: NomSci_pSibSizeFull, multiplicity: 1 */ + 0, + /* ID: 605, value: 0, name: NomSci_pGibNFull, multiplicity: 1 */ + 0, + /* ID: 606, value: 0, name: NomSci_pGibSizeFull, multiplicity: 1 */ + 0, + /* ID: 607, value: 0, name: NomSci_pSibNWin, multiplicity: 1 */ + 0, + /* ID: 608, value: 0, name: NomSci_pSibSizeWin, multiplicity: 1 */ + 0, + /* ID: 609, value: 0, name: NomSci_pCibNWin, multiplicity: 1 */ + 0, + /* ID: 610, value: 0, name: NomSci_pCibSizeWin, multiplicity: 1 */ + 0, + /* ID: 611, value: 0, name: NomSci_pGibNWin, multiplicity: 1 */ + 0, + /* ID: 612, value: 0, name: NomSci_pGibSizeWin, multiplicity: 1 */ + 0, + /* ID: 613, value: 0, name: NomSci_pExpTimeAcq, multiplicity: 1 */ + 0, + /* ID: 614, value: 0, name: NomSci_pImageRepAcq, multiplicity: 1 */ + 0, + /* ID: 615, value: 0, name: NomSci_pExpTimeCal1, multiplicity: 1 */ + 0, + /* ID: 616, value: 0, name: NomSci_pImageRepCal1, multiplicity: 1 */ + 0, + /* ID: 617, value: 0, name: NomSci_pNmbImagesCal1, multiplicity: 1 */ + 0, + /* ID: 618, value: NO_CENT, name: NomSci_pCentSelCal1, multiplicity: 1 */ + 1, + /* ID: 619, value: 0, name: NomSci_pNmbImagesSci, multiplicity: 1 */ + 0, + /* ID: 620, value: FAINT, name: NomSci_pCcdRdModeSci, multiplicity: 1 */ + 0, + /* ID: 621, value: 0, name: NomSci_pExpTimeSci, multiplicity: 1 */ + 0, + /* ID: 622, value: 0, name: NomSci_pImageRepSci, multiplicity: 1 */ + 0, + /* ID: 623, value: 0, name: NomSci_pWinPosXSci, multiplicity: 1 */ + 0, + /* ID: 624, value: 1, name: NomSci_pWinPosYSci, multiplicity: 1 */ + 1, + /* ID: 625, value: 200, name: NomSci_pWinSizeXSci, multiplicity: 1 */ + 200, + /* ID: 626, value: 200, name: NomSci_pWinSizeYSci, multiplicity: 1 */ + 200, + /* ID: 627, value: NO_CENT, name: NomSci_pCentSelSci, multiplicity: 1 */ + 1, + /* ID: 628, value: 0, name: NomSci_pExpTimeCal2, multiplicity: 1 */ + 0, + /* ID: 629, value: 0, name: NomSci_pImageRepCal2, multiplicity: 1 */ + 0, + /* ID: 630, value: 0, name: NomSci_pNmbImagesCal2, multiplicity: 1 */ + 0, + /* ID: 631, value: NO_CENT, name: NomSci_pCentSelCal2, multiplicity: 1 */ + 1, + /* ID: 632, value: GROUND, name: NomSci_pSaveTarget, multiplicity: 1 */ + 0, + /* ID: 633, value: 0, name: NomSci_pFbfInit, multiplicity: 1 */ + 0, + /* ID: 634, value: 0, name: NomSci_pFbfEnd, multiplicity: 1 */ + 0, + /* ID: 635, value: 0, name: NomSci_pStckOrderCal1, multiplicity: 1 */ + 0, + /* ID: 636, value: 0, name: NomSci_pStckOrderSci, multiplicity: 1 */ + 0, + /* ID: 637, value: 0, name: NomSci_pStckOrderCal2, multiplicity: 1 */ + 0, + /* ID: 638, value: RESET, name: ConfigSdb_pSdbCmd, multiplicity: 1 */ + 0, + /* ID: 639, value: 0, name: ConfigSdb_pCibNFull, multiplicity: 1 */ + 0, + /* ID: 640, value: 0, name: ConfigSdb_pCibSizeFull, multiplicity: 1 */ + 0, + /* ID: 641, value: 0, name: ConfigSdb_pSibNFull, multiplicity: 1 */ + 0, + /* ID: 642, value: 0, name: ConfigSdb_pSibSizeFull, multiplicity: 1 */ + 0, + /* ID: 643, value: 0, name: ConfigSdb_pGibNFull, multiplicity: 1 */ + 0, + /* ID: 644, value: 0, name: ConfigSdb_pGibSizeFull, multiplicity: 1 */ + 0, + /* ID: 645, value: 0, name: ConfigSdb_pSibNWin, multiplicity: 1 */ + 0, + /* ID: 646, value: 0, name: ConfigSdb_pSibSizeWin, multiplicity: 1 */ + 0, + /* ID: 647, value: 0, name: ConfigSdb_pCibNWin, multiplicity: 1 */ + 0, + /* ID: 648, value: 0, name: ConfigSdb_pCibSizeWin, multiplicity: 1 */ + 0, + /* ID: 649, value: 0, name: ConfigSdb_pGibNWin, multiplicity: 1 */ + 0, + /* ID: 650, value: 0, name: ConfigSdb_pGibSizeWin, multiplicity: 1 */ + 0, + /* ID: 651, value: 0, name: ADC_P3V3, multiplicity: 1 */ + 0, + /* ID: 652, value: 0, name: ADC_P5V, multiplicity: 1 */ + 0, + /* ID: 653, value: 0, name: ADC_P1V8, multiplicity: 1 */ + 0, + /* ID: 654, value: 0, name: ADC_P2V5, multiplicity: 1 */ + 0, + /* ID: 655, value: 0, name: ADC_N5V, multiplicity: 1 */ + 0, + /* ID: 656, value: 0, name: ADC_PGND, multiplicity: 1 */ + 0, + /* ID: 657, value: 0, name: ADC_TEMPOH1A, multiplicity: 1 */ + 0, + /* ID: 658, value: 0, name: ADC_TEMP1, multiplicity: 1 */ + 0, + /* ID: 659, value: 0, name: ADC_TEMPOH2A, multiplicity: 1 */ + 0, + /* ID: 660, value: 0, name: ADC_TEMPOH1B, multiplicity: 1 */ + 0, + /* ID: 661, value: 0, name: ADC_TEMPOH3A, multiplicity: 1 */ + 0, + /* ID: 662, value: 0, name: ADC_TEMPOH2B, multiplicity: 1 */ + 0, + /* ID: 663, value: 0, name: ADC_TEMPOH4A, multiplicity: 1 */ + 0, + /* ID: 664, value: 0, name: ADC_TEMPOH3B, multiplicity: 1 */ + 0, + /* ID: 665, value: 0, name: ADC_TEMPOH4B, multiplicity: 1 */ + 0, + /* ID: 666, value: 0, name: SEM_P15V, multiplicity: 1 */ + 0, + /* ID: 667, value: 0, name: SEM_P30V, multiplicity: 1 */ + 0, + /* ID: 668, value: 0, name: SEM_P5V0, multiplicity: 1 */ + 0, + /* ID: 669, value: 0, name: SEM_P7V0, multiplicity: 1 */ + 0, + /* ID: 670, value: 0, name: SEM_N5V0, multiplicity: 1 */ + 0, + /* ID: 671, value: 0, name: ADC_P3V3_RAW, multiplicity: 1 */ + 0, + /* ID: 672, value: 0, name: ADC_P5V_RAW, multiplicity: 1 */ + 0, + /* ID: 673, value: 0, name: ADC_P1V8_RAW, multiplicity: 1 */ + 0, + /* ID: 674, value: 0, name: ADC_P2V5_RAW, multiplicity: 1 */ + 0, + /* ID: 675, value: 0, name: ADC_N5V_RAW, multiplicity: 1 */ + 0, + /* ID: 676, value: 0, name: ADC_PGND_RAW, multiplicity: 1 */ + 0, + /* ID: 677, value: 0, name: ADC_TEMPOH1A_RAW, multiplicity: 1 */ + 0, + /* ID: 678, value: 0, name: ADC_TEMP1_RAW, multiplicity: 1 */ + 0, + /* ID: 679, value: 0, name: ADC_TEMPOH2A_RAW, multiplicity: 1 */ + 0, + /* ID: 680, value: 0, name: ADC_TEMPOH1B_RAW, multiplicity: 1 */ + 0, + /* ID: 681, value: 0, name: ADC_TEMPOH3A_RAW, multiplicity: 1 */ + 0, + /* ID: 682, value: 0, name: ADC_TEMPOH2B_RAW, multiplicity: 1 */ + 0, + /* ID: 683, value: 0, name: ADC_TEMPOH4A_RAW, multiplicity: 1 */ + 0, + /* ID: 684, value: 0, name: ADC_TEMPOH3B_RAW, multiplicity: 1 */ + 0, + /* ID: 685, value: 0, name: ADC_TEMPOH4B_RAW, multiplicity: 1 */ + 0, + /* ID: 686, value: 0, name: SEM_P15V_RAW, multiplicity: 1 */ + 0, + /* ID: 687, value: 0, name: SEM_P30V_RAW, multiplicity: 1 */ + 0, + /* ID: 688, value: 0, name: SEM_P5V0_RAW, multiplicity: 1 */ + 0, + /* ID: 689, value: 0, name: SEM_P7V0_RAW, multiplicity: 1 */ + 0, + /* ID: 690, value: 0, name: SEM_N5V0_RAW, multiplicity: 1 */ + 0, + /* ID: 691, value: 3.9, name: ADC_P3V3_U, multiplicity: 1 */ + 3.9, + /* ID: 692, value: 6.4, name: ADC_P5V_U, multiplicity: 1 */ + 6.4, + /* ID: 693, value: 2.1, name: ADC_P1V8_U, multiplicity: 1 */ + 2.1, + /* ID: 694, value: 3.4, name: ADC_P2V5_U, multiplicity: 1 */ + 3.4, + /* ID: 695, value: -6.4, name: ADC_N5V_L, multiplicity: 1 */ + -6.4, + /* ID: 696, value: 1, name: ADC_PGND_U, multiplicity: 1 */ + 1, + /* ID: 697, value: -1, name: ADC_PGND_L, multiplicity: 1 */ + -1, + /* ID: 698, value: 60, name: ADC_TEMPOH1A_U, multiplicity: 1 */ + 60, + /* ID: 699, value: 60, name: ADC_TEMP1_U, multiplicity: 1 */ + 60, + /* ID: 700, value: 60, name: ADC_TEMPOH2A_U, multiplicity: 1 */ + 60, + /* ID: 701, value: 60, name: ADC_TEMPOH1B_U, multiplicity: 1 */ + 60, + /* ID: 702, value: 60, name: ADC_TEMPOH3A_U, multiplicity: 1 */ + 60, + /* ID: 703, value: 60, name: ADC_TEMPOH2B_U, multiplicity: 1 */ + 60, + /* ID: 704, value: 60, name: ADC_TEMPOH4A_U, multiplicity: 1 */ + 60, + /* ID: 705, value: 60, name: ADC_TEMPOH3B_U, multiplicity: 1 */ + 60, + /* ID: 706, value: 60, name: ADC_TEMPOH4B_U, multiplicity: 1 */ + 60, + /* ID: 707, value: 18.6, name: SEM_P15V_U, multiplicity: 1 */ + 18.6, + /* ID: 708, value: 36.3, name: SEM_P30V_U, multiplicity: 1 */ + 36.3, + /* ID: 709, value: 8.2, name: SEM_P5V0_U, multiplicity: 1 */ + 8.2, + /* ID: 710, value: 9.6, name: SEM_P7V0_U, multiplicity: 1 */ + 9.6, + /* ID: 711, value: -8.1, name: SEM_N5V0_L, multiplicity: 1 */ + -8.1, + /* ID: 712, value: 0, name: HbSemPassword, multiplicity: 1 */ + 0, + /* ID: 713, value: 0, name: HbSemCounter, multiplicity: 1 */ + 0, + /* ID: 726, value: 115, name: MAX_SEM_PCKT_CYC, multiplicity: 1 */ + 115, + /* ID: 798, value: 0, name: SemPwrOnTimestamp, multiplicity: 1 */ + 0, + /* ID: 799, value: 0, name: SemPwrOffTimestamp, multiplicity: 1 */ + 0, + /* ID: 800, value: 0, name: IASW_EVT_CTR, multiplicity: 1 */ + 0, + /* ID: 834, value: 1073741824, name: Sram1ScrCurrAddr, multiplicity: 1 */ + 1073741824, + /* ID: 835, value: 67108864, name: Sram2ScrCurrAddr, multiplicity: 1 */ + 67108864, + /* ID: 836, value: 1024, name: Sram1ScrLength, multiplicity: 1 */ + 1024, + /* ID: 837, value: 1024, name: Sram2ScrLength, multiplicity: 1 */ + 1024, + /* ID: 838, value: 0, name: EdacSingleRepaired, multiplicity: 1 */ + 0, + /* ID: 839, value: 0, name: EdacSingleFaults, multiplicity: 1 */ + 0, + /* ID: 840, value: 0, name: EdacLastSingleFail, multiplicity: 1 */ + 0, + /* ID: 843, value: IDLE, name: Cpu2ProcStatus, multiplicity: 1 */ + 0, + /* ID: 853, value: AMANMVA, name: TaAlgoId, multiplicity: 1 */ + 3, + /* ID: 854, value: 111, name: TAACQALGOID, multiplicity: 1 */ + 111, + /* ID: 855, value: 0, name: TASPARE32, multiplicity: 1 */ + 0, + /* ID: 856, value: 12000, name: TaTimingPar1, multiplicity: 1 */ + 12000, + /* ID: 857, value: 2000, name: TaTimingPar2, multiplicity: 1 */ + 2000, + /* ID: 858, value: 10, name: TaDistanceThrd, multiplicity: 1 */ + 10, + /* ID: 859, value: 10, name: TaIterations, multiplicity: 1 */ + 10, + /* ID: 860, value: 8, name: TaRebinningFact, multiplicity: 1 */ + 8, + /* ID: 861, value: 35000, name: TaDetectionThrd, multiplicity: 1 */ + 35000, + /* ID: 862, value: 0, name: TaSeReducedExtr, multiplicity: 1 */ + 0, + /* ID: 863, value: 392, name: TaSeReducedRadius, multiplicity: 1 */ + 392, + /* ID: 864, value: 5, name: TaSeTolerance, multiplicity: 1 */ + 5, + /* ID: 865, value: 15, name: TaMvaTolerance, multiplicity: 1 */ + 15, + /* ID: 866, value: 3, name: TaAmaTolerance, multiplicity: 1 */ + 3, + /* ID: 867, value: 200, name: TAPOINTUNCERT, multiplicity: 1 */ + 200, + /* ID: 868, value: 10000, name: TATARGETSIG, multiplicity: 1 */ + 10000, + /* ID: 869, value: 20, name: TANROFSTARS, multiplicity: 1 */ + 20, + /* ID: 870, value: 0.2029259, name: TaMaxSigFract, multiplicity: 1 */ + 0.2029259, + /* ID: 871, value: 1753.5, name: TaBias, multiplicity: 1 */ + 1753.5, + /* ID: 872, value: 0.04, name: TaDark, multiplicity: 1 */ + 0.04, + /* ID: 873, value: 2.9533725, name: TaSkyBg, multiplicity: 1 */ + 2.9533725, + /* ID: 874, value: 16, name: COGBITS, multiplicity: 1 */ + 16, + /* ID: 875, value: -1, name: CENT_MULT_X, multiplicity: 1 */ + -1, + /* ID: 876, value: -1, name: CENT_MULT_Y, multiplicity: 1 */ + -1, + /* ID: 877, value: 0, name: CENT_OFFSET_X, multiplicity: 1 */ + 0, + /* ID: 878, value: 0, name: CENT_OFFSET_Y, multiplicity: 1 */ + 0, + /* ID: 879, value: 0, name: CENT_MEDIANFILTER, multiplicity: 1 */ + 0, + /* ID: 880, value: 51, name: CENT_DIM_X, multiplicity: 1 */ + 51, + /* ID: 881, value: 51, name: CENT_DIM_Y, multiplicity: 1 */ + 51, + /* ID: 882, value: 1, name: CENT_CHECKS, multiplicity: 1 */ + 1, + /* ID: 883, value: 400, name: CEN_SIGMALIMIT, multiplicity: 1 */ + 400, + /* ID: 884, value: 400, name: CEN_SIGNALLIMIT, multiplicity: 1 */ + 400, + /* ID: 885, value: 1000, name: CEN_MEDIAN_THRD, multiplicity: 1 */ + 1000, + /* ID: 886, value: 512, name: OPT_AXIS_X, multiplicity: 1 */ + 512, + /* ID: 887, value: 512, name: OPT_AXIS_Y, multiplicity: 1 */ + 512, + /* ID: 888, value: 0, name: DIST_CORR, multiplicity: 1 */ + 0, + /* ID: 889, value: 10, name: pStckOrderSci, multiplicity: 1 */ + 10, + /* ID: 890, value: 200, name: pWinSizeXSci, multiplicity: 1 */ + 200, + /* ID: 891, value: 200, name: pWinSizeYSci, multiplicity: 1 */ + 200, + /* ID: 892, value: CIRCULAR, name: SdpImageAptShape, multiplicity: 1 */ + 1, + /* ID: 893, value: 200, name: SdpImageAptX, multiplicity: 1 */ + 200, + /* ID: 894, value: 200, name: SdpImageAptY, multiplicity: 1 */ + 200, + /* ID: 895, value: CIRCULAR, name: SdpImgttAptShape, multiplicity: 1 */ + 1, + /* ID: 896, value: 31, name: SdpImgttAptX, multiplicity: 1 */ + 31, + /* ID: 897, value: 31, name: SdpImgttAptY, multiplicity: 1 */ + 31, + /* ID: 898, value: 1, name: SdpImgttStckOrder, multiplicity: 1 */ + 1, + /* ID: 899, value: 1, name: SdpLosStckOrder, multiplicity: 1 */ + 1, + /* ID: 900, value: 1, name: SdpLblkStckOrder, multiplicity: 1 */ + 1, + /* ID: 901, value: 1, name: SdpLdkStckOrder, multiplicity: 1 */ + 1, + /* ID: 902, value: 1, name: SdpRdkStckOrder, multiplicity: 1 */ + 1, + /* ID: 903, value: 1, name: SdpRblkStckOrder, multiplicity: 1 */ + 1, + /* ID: 904, value: 1, name: SdpTosStckOrder, multiplicity: 1 */ + 1, + /* ID: 905, value: 1, name: SdpTdkStckOrder, multiplicity: 1 */ + 1, + /* ID: 906, value: STATIC, name: SdpImgttStrat, multiplicity: 1 */ + 0, + /* ID: 907, value: 100, name: Sdp3StatAmpl, multiplicity: 1 */ + 100, + /* ID: 908, value: MEAN, name: SdpPhotStrat, multiplicity: 1 */ + 0, + /* ID: 909, value: 15, name: SdpPhotRcent, multiplicity: 1 */ + 15, + /* ID: 910, value: 30, name: SdpPhotRann1, multiplicity: 1 */ + 30, + /* ID: 911, value: 40, name: SdpPhotRann2, multiplicity: 1 */ + 40, + /* ID: 912, value: 0, name: SdpCrc, multiplicity: 1 */ + 0, + /* ID: 913, value: 0, name: CCPRODUCT, multiplicity: 1 */ + 0, + /* ID: 914, value: 0, name: CCSTEP, multiplicity: 1 */ + 0, + /* ID: 915, value: 0, name: XIB_FAILURES, multiplicity: 1 */ + 0, + /* ID: 916, value: 0, name: FEE_SIDE_A, multiplicity: 12 */ + {2,8,4,6,250,31,33,0,0,0,0,0}, /* NOTE: manually set the "assigned" ones from SEM FM UM 1.4 */ + /* ID: 917, value: 0, name: FEE_SIDE_B, multiplicity: 12 */ + {1,7,3,5,251,32,34,0,0,0,0,0}, /* NOTE: manually set the "assigned" ones from SEM FM UM 1.4 */ + /* ID: 918, value: 0, name: NLCBORDERS, multiplicity: 28 */ /* NOTE: manually set, 230 kHz */ + {7103, 13878, 27963, 62360, 80978, 96220, 114403, 120305, 121297, 122622, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223, 128223}, +/* old: ADU {3630, 7093, 14292, 31872, 41388, 49178, 58471, 61488, 61995, 62672, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535}, */ +/* old NLC: {1267, 2501, 3732, 4963, 6193, 7423, 8644, 9878, 11098, 12330, 15391, 18443, 21490, 24529, 27560, 30584, 33598, 36606, 39606, 42597, 45582, 48544, 51438, 54056, 55996, 57045, 58000, 65535}, */ + /* ID: 919, value: 0, name: NLCCOEFF_A, multiplicity: 28 */ /* NOTE: manually set, 230 kHz */ +{-1.9448292e-07, -2.5471461e-10, 6.1955157e-08, 8.1523396e-08, 8.4184145e-08, 5.7885295e-08, 2.3925561e-07, 2.139497e-05, 0.0012188126, -1.2927786e-05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, +/* old NLC: {1.6542972e+02, 1.3805946e+03, 2.5957595e+03, 3.8109244e+03, 5.0260894e+03, 6.2412543e+03, 7.4564192e+03, 8.6715841e+03, 9.8867490e+03, 1.1101914e+04, 1.2317079e+04, 1.5354991e+04, 1.8392903e+04, 2.1430816e+04, 2.4468728e+04, 2.7506640e+04, 3.0544552e+04, 3.3582465e+04, 3.6620377e+04, 3.9658289e+04, 4.2696202e+04, 4.5734114e+04, 4.8772026e+04, 5.1809938e+04, 5.4847851e+04, 5.7885763e+04, 6.0923675e+04, 6.5535000e+04}, */ + /* ID: 920, value: 0, name: NLCCOEFF_B, multiplicity: 28 */ /* NOTE: manually set, 230 kHz */ +{0.99773673, 0.99497384, 0.99497039, 0.99671569, 1.002324, 1.0054587, 1.0072233, 1.0159238, 1.2684748, 3.6876537, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, +/* old NLC: {9.3751570e-01, 9.7668084e-01, 9.8767829e-01, 9.8701867e-01, 9.8779389e-01, 9.8661244e-01, 9.9342212e-01, 9.8855860e-01, 9.9023516e-01, 9.9295951e-01, 9.8550757e-01, 9.9558868e-01, 9.9574776e-01, 9.9833593e-01, 1.0009162e+00, 1.0034410e+00, 1.0063064e+00, 1.0089037e+00, 1.0111977e+00, 1.0145322e+00, 1.0160308e+00, 1.0217782e+00, 1.0274503e+00, 1.0935509e+00, 1.2344498e+00, 2.1690294e+00, 3.8757727e+00, 5.6159531e+00}, */ + /* ID: 921, value: 0, name: NLCCOEFF_C, multiplicity: 28 */ /* NOTE: manually set, 230 kHz */ +{0.0, 7077.2753, 13817.994, 27844.636, 62225.153, 80915.779, 96254.514, 114647.32, 121388.7, 123848.02, 128710.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0, 134311.0}, +/* old NLC: {2.1035964e-05, 9.8874568e-06, -9.7833909e-07, 4.4254180e-07, 1.8741129e-07, -1.1474842e-06, 6.6864550e-06, -1.0666894e-05, 1.2025528e-05, -9.7924614e-06, 3.7430750e-06, -4.4891247e-07, 5.0102665e-07, 3.4847735e-07, 5.0050828e-07, 3.3247057e-07, 6.1518573e-07, 2.4643065e-07, 5.1617919e-07, 5.9553632e-07, -9.4537719e-08, 2.0202119e-06, -1.0518593e-07, 2.2938227e-05, 3.0887449e-05, 4.5085953e-04, 1.1759395e-03, 6.4678568e-04}, */ + /* ID: 922, value: 0, name: NLCCOEFF_D, multiplicity: 28 */ /* NOTE: manually set. For the order and meaning, see SdpNlcPhot.h */ +{650.0, 0.5111, 8.8, 22.0, 9.0, -5.75, -2.8951e-02, 3.0388e-02, -8.376e-03, 5.288e-03, -6.852e-03, -1.1206e-02, 0.0, 1.640e-03, 1.3978e-02, 0.0, 6.612e-03, 4.35e-03, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.106e-03, 0.0}, +/* old NLC: {-2.9341567e-09, -2.9341567e-09, 3.8471879e-10, -6.9107443e-11, -3.6159111e-10, 2.1240355e-09, -4.7341521e-09, 6.1297314e-09, -5.9611804e-09, 3.6626557e-09, -4.5659957e-10, 1.0372969e-10, -1.6690174e-11, 1.6673993e-11, -1.8479584e-11, 3.1167539e-11, -4.0776664e-11, 2.9891495e-11, 8.8190944e-12, -7.6901145e-11, 2.3618228e-10, -2.3919308e-10, 2.6532860e-09, 1.0122442e-09, 7.2160882e-08, 2.3037234e-07, -1.8475133e-07, -1.8475133e-07}, */ + /* ID: 923, value: 0, name: SdpGlobalBias, multiplicity: 1 */ + 0, + /* ID: 924, value: LOS, name: BiasOrigin, multiplicity: 1 */ + 1, + /* ID: 925, value: 0, name: SdpGlobalGain, multiplicity: 1 */ + 0, + /* ID: 926, value: 0x30150303, name: SdpWinImageCeKey, multiplicity: 1 */ + 0x30150303, + /* ID: 927, value: 0x20050303, name: SdpWinImgttCeKey, multiplicity: 1 */ + 0x20050303, + /* ID: 928, value: 0x10000000, name: SdpWinHdrCeKey, multiplicity: 1 */ + 0x10000000, + /* ID: 929, value: 0x40190403, name: SdpWinMLOSCeKey, multiplicity: 1 */ + 0x40190403, + /* ID: 930, value: 0xf0000000, name: SdpWinMLBLKCeKey, multiplicity: 1 */ + 0xf0000000, + /* ID: 931, value: 0x60190403, name: SdpWinMLDKCeKey, multiplicity: 1 */ + 0x60190403, + /* ID: 932, value: 0x70190403, name: SdpWinMRDKCeKey, multiplicity: 1 */ + 0x70190403, + /* ID: 933, value: 0xf0000000, name: SdpWinMRBLKCeKey, multiplicity: 1 */ + 0xf0000000, + /* ID: 934, value: 0x90100403, name: SdpWinMTOSCeKey, multiplicity: 1 */ + 0x90100403, + /* ID: 935, value: 0xa0100403, name: SdpWinMTDKCeKey, multiplicity: 1 */ + 0xa0100403, + /* ID: 936, value: 0x30200103, name: SdpFullImgCeKey, multiplicity: 1 */ + 0x30200103, + /* ID: 937, value: 0x10000000, name: SdpFullHdrCeKey, multiplicity: 1 */ + 0x10000000, + /* ID: 938, value: 0, name: CE_Timetag_crs, multiplicity: 1 */ + 0, + /* ID: 939, value: 0, name: CE_Timetag_fine, multiplicity: 1 */ + 0, + /* ID: 940, value: 0, name: CE_Counter, multiplicity: 1 */ + 0, + /* ID: 941, value: 0x6E0B, name: CE_Version, multiplicity: 1 */ + 0x6E0B, + /* ID: 942, value: 0, name: CE_Integrity, multiplicity: 1 */ + 0, + /* ID: 943, value: 412, name: CE_SemWindowPosX, multiplicity: 1 */ + 412, + /* ID: 944, value: 412, name: CE_SemWindowPosY, multiplicity: 1 */ + 412, + /* ID: 945, value: 200, name: CE_SemWindowSizeX, multiplicity: 1 */ + 200, + /* ID: 946, value: 200, name: CE_SemWindowSizeY, multiplicity: 1 */ + 200, + /* ID: 947, value: 0, name: SPILL_CTR, multiplicity: 1 */ + 0, + /* ID: 948, value: 5, name: RZIP_ITER1, multiplicity: 1 */ + 5, + /* ID: 949, value: 3, name: RZIP_ITER2, multiplicity: 1 */ + 3, + /* ID: 950, value: 5, name: RZIP_ITER3, multiplicity: 1 */ + 5, + /* ID: 951, value: 0, name: RZIP_ITER4, multiplicity: 1 */ + 0, + /* ID: 952, value: 0xffff, name: SdpLdkColMask, multiplicity: 1 */ + 0xffff, + /* ID: 953, value: 0xffff, name: SdpRdkColMask, multiplicity: 1 */ + 0xffff, + /* ID: 960, value: 0, name: GIBTOTRANSFER, multiplicity: 1 */ + 0, + /* ID: 961, value: 0, name: TRANSFERMODE, multiplicity: 1 */ + 0, + /* ID: 962, value: 0, name: S2TOTRANSFERSIZE, multiplicity: 1 */ + 0, + /* ID: 963, value: 0, name: S4TOTRANSFERSIZE, multiplicity: 1 */ + 0, + /* ID: 964, value: 0, name: TransferComplete, multiplicity: 1 */ + 0, + /* ID: 965, value: 0, name: NLCBORDERS_2, multiplicity: 28 */ + {28267, 62972, 97467, 111205, 117732, 121460, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000, 130000}, + /* ID: 966, value: 0, name: NLCCOEFF_A_2, multiplicity: 28 */ + {6.464197e-08, 1.0288715e-07, 8.8843558e-08, 9.3269555e-08, 7.873576e-06, 0.00020023889, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + /* ID: 967, value: 0, name: NLCCOEFF_B_2, multiplicity: 28 */ + {0.99206587, 0.9957203, 1.0028618, 1.0089911, 1.0115539, 1.1143296, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + /* ID: 968, value: 0, name: NLCCOEFF_C_2, multiplicity: 28 */ + {0.0, 28094.034, 62775.109, 97474.114, 111353.83, 118291.25, 125230, 125230, 125230, 125230, 125230, 125230, 125230, 125230, 125230, 133769, 133769, 133769, 133769, 133769, 133769, 133769, 133769, 133769, 133769, 133769, 133769, 133769}, + /* ID: 969, value: 0, name: RF100, multiplicity: 12 */ /* manually set. NOTE: both sides needed! */ + {31,32,33,34,0,0,0,0,0,0,0,0}, + /* ID: 970, value: 0, name: RF230, multiplicity: 12 */ /* manually set. NOTE: both sides needed! */ + {2,1,8,7,4,3,6,5,250,251,0,0}, + /* ID: 971, value: 1.0, name: distc1, multiplicity: 1 */ + 1.0, + /* ID: 972, value: 3.69355E-8, name: distc2, multiplicity: 1 */ + 3.69355E-8, + /* ID: 973, value: 7.03436E-15, name: distc3, multiplicity: 1 */ + 7.03436E-15, + /* ID: 974, value: 0, name: SPARE_UI_0, multiplicity: 1 */ + 0, + /* ID: 975, value: 0, name: SPARE_UI_1, multiplicity: 1 */ + 0, + /* ID: 976, value: 0, name: SPARE_UI_2, multiplicity: 1 */ + 0, + /* ID: 977, value: 0, name: SPARE_UI_3, multiplicity: 1 */ + 0, + /* ID: 978, value: 0, name: SPARE_UI_4, multiplicity: 1 */ + 0, + /* ID: 979, value: 0, name: SPARE_UI_5, multiplicity: 1 */ + 0, + /* ID: 980, value: 0, name: SPARE_UI_6, multiplicity: 1 */ + 0, + /* ID: 981, value: 0, name: SPARE_UI_7, multiplicity: 1 */ + 0, + /* ID: 982, value: 0, name: SPARE_UI_8, multiplicity: 1 */ + 0, + /* ID: 983, value: 0, name: SPARE_UI_9, multiplicity: 1 */ + 0, + /* ID: 984, value: 0, name: SPARE_UI_10, multiplicity: 1 */ + 0, + /* ID: 985, value: 0, name: SPARE_UI_11, multiplicity: 1 */ + 0, + /* ID: 986, value: 0, name: SPARE_UI_12, multiplicity: 1 */ + 0, + /* ID: 987, value: 0, name: SPARE_UI_13, multiplicity: 1 */ + 0, + /* ID: 988, value: 0, name: SPARE_UI_14, multiplicity: 1 */ + 0, + /* ID: 989, value: 0, name: SPARE_UI_15, multiplicity: 1 */ + 0, + /* ID: 990, value: 0, name: SPARE_F_0, multiplicity: 1 */ + 0, + /* ID: 991, value: 0, name: SPARE_F_1, multiplicity: 1 */ + 0, + /* ID: 992, value: 0, name: SPARE_F_2, multiplicity: 1 */ + 0, + /* ID: 993, value: 0, name: SPARE_F_3, multiplicity: 1 */ + 0, + /* ID: 994, value: 0, name: SPARE_F_4, multiplicity: 1 */ + 0, + /* ID: 995, value: 0, name: SPARE_F_5, multiplicity: 1 */ + 0, + /* ID: 996, value: 0, name: SPARE_F_6, multiplicity: 1 */ + 0, + /* ID: 997, value: 0, name: SPARE_F_7, multiplicity: 1 */ + 0, + /* ID: 998, value: 0, name: SPARE_F_8, multiplicity: 1 */ + 0, + /* ID: 999, value: 0, name: SPARE_F_9, multiplicity: 1 */ + 0, + /* ID: 1000, value: 0, name: SPARE_F_10, multiplicity: 1 */ + 0, + /* ID: 1001, value: 0, name: SPARE_F_11, multiplicity: 1 */ + 0, + /* ID: 1002, value: 0, name: SPARE_F_12, multiplicity: 1 */ + 0, + /* ID: 1003, value: 0, name: SPARE_F_13, multiplicity: 1 */ + 0, + /* ID: 1004, value: 0, name: SPARE_F_14, multiplicity: 1 */ + 0, + /* ID: 1005, value: 0, name: SPARE_F_15, multiplicity: 1 */ + 0 +}; + +/** Initialization of the structure holding of data pool variables and parameter items for IBSW. */ +#ifdef PC_TARGET +struct DataPoolIbsw dpIbsw; +struct DataPoolIbsw dpIbswInit = { +#else +struct DataPoolIbsw dpIbsw = { +#endif /* PC_TARGET */ + /* ID: 714, value: 1, name: isWatchdogEnabled, multiplicity: 1 */ + 1, + /* ID: 715, value: 0, name: isSynchronized, multiplicity: 1 */ + 0, + /* ID: 716, value: 0, name: missedMsgCnt, multiplicity: 1 */ + 0, + /* ID: 717, value: 0, name: missedPulseCnt, multiplicity: 1 */ + 0, + /* ID: 718, value: 20000, name: milFrameDelay, multiplicity: 1 */ + 20000, + /* ID: 719, value: CHIP1, name: EL1_CHIP, multiplicity: 1 */ + 0, + /* ID: 720, value: CHIP2, name: EL2_CHIP, multiplicity: 1 */ + 1, + /* ID: 721, value: 0, name: EL1_ADDR, multiplicity: 1 */ + 0, + /* ID: 722, value: 0, name: EL2_ADDR, multiplicity: 1 */ + 0, + /* ID: 723, value: 0, name: ERR_LOG_ENB, multiplicity: 1 */ + 0, + /* ID: 724, value: 0, name: isErrLogValid, multiplicity: 1 */ + 0, + /* ID: 725, value: 0, name: nOfErrLogEntries, multiplicity: 1 */ + 0, + /* ID: 727, value: 8, name: FBF_BLCK_WR_DUR, multiplicity: 1 */ + 8, + /* ID: 728, value: 8, name: FBF_BLCK_RD_DUR, multiplicity: 1 */ + 8, + /* ID: 729, value: 0, name: isFbfOpen, multiplicity: 250 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 730, value: 1, name: isFbfValid, multiplicity: 250 */ + {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, + /* ID: 731, value: 0, name: FBF_ENB, multiplicity: 250 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 732, value: CHIP2, name: FBF_CHIP, multiplicity: 250 */ + {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, + /* ID: 733, value: Auto, name: FBF_ADDR, multiplicity: 250 */ + {0x00400000,0x00800000,0x00c00000,0x01000000,0x01400000,0x01800000,0x01c00000,0x02400000,0x02800000,0x02c00000,0x03000000,0x03700000,0x03b00000,0x04500000,0x04900000,0x04d00000,0x05100000,0x05500000,0x05900000,0x05f00000,0x06300000,0x06700000,0x06b00000,0x06f00000,0x07300000,0x07700000,0x07d00000,0x08100000,0x08500000,0x08d00000,0x09100000,0x09500000,0x09c00000,0x0a000000,0x0a400000,0x0a800000,0x0ac00000,0x0b000000,0x0b400000,0x0ba00000,0x0be00000,0x0c200000,0x0c600000,0x0ca00000,0x0ce00000,0x0d200000,0x0d600000,0x0da00000,0x0e000000,0x0e400000,0x0e800000,0x0ee00000,0x0f400000,0x0f800000,0x0fd00000,0x10500000,0x10a00000,0x10e00000,0x11300000,0x11b00000,0x11f00000,0x12300000,0x12700000,0x12b00000,0x12f00000,0x13300000,0x13700000,0x14200000,0x14a00000,0x14e00000,0x15200000,0x15600000,0x15a00000,0x15e00000,0x16200000,0x16a00000,0x16e00000,0x17200000,0x17600000,0x17a00000,0x17e00000,0x18200000,0x18600000,0x18a00000,0x18e00000,0x19200000,0x19600000,0x19a00000,0x19f00000,0x1a300000,0x1a700000,0x1ac00000,0x1b400000,0x1b800000,0x1bf00000,0x1c300000,0x1c700000,0x1cb00000,0x1d700000,0x1db00000,0x1df00000,0x1e300000,0x1e700000,0x1eb00000,0x1ef00000,0x1f300000,0x1f700000,0x1fb00000,0x1ff00000,0x20300000,0x20700000,0x20b00000,0x20f00000,0x21300000,0x21700000,0x21b00000,0x22000000,0x22800000,0x22c00000,0x23000000,0x23400000,0x23800000,0x23e00000,0x24300000,0x24700000,0x24b00000,0x24f00000,0x25300000,0x25700000,0x25b00000,0x25f00000,0x26300000,0x26700000,0x26e00000,0x27200000,0x27600000,0x27a00000,0x27e00000,0x28200000,0x28600000,0x28a00000,0x28e00000,0x29200000,0x29b00000,0x29f00000,0x2a300000,0x2a700000,0x2ab00000,0x2af00000,0x2b500000,0x2b900000,0x2bd00000,0x2c100000,0x2c500000,0x2c900000,0x2cd00000,0x2d300000,0x2d700000,0x2df00000,0x2e300000,0x2e700000,0x2eb00000,0x2ef00000,0x2f500000,0x2f900000,0x2fd00000,0x30100000,0x30a00000,0x30e00000,0x31200000,0x31600000,0x31a00000,0x31e00000,0x32200000,0x32a00000,0x33200000,0x33600000,0x33a00000,0x33e00000,0x34200000,0x34600000,0x34a00000,0x34e00000,0x35200000,0x35600000,0x35a00000,0x35e00000,0x36200000,0x36800000,0x36c00000,0x37000000,0x37400000,0x37a00000,0x38100000,0x38500000,0x38a00000,0x39000000,0x39400000,0x39800000,0x39c00000,0x3a000000,0x3a400000,0x3a800000,0x3af00000,0x3b400000,0x3b800000,0x3bc00000,0x3c000000,0x3c400000,0x3c800000,0x3cc00000,0x3d000000,0x3d400000,0x3d800000,0x3dc00000,0x3e000000,0x3e400000,0x3e800000,0x3ec00000,0x3f000000,0x3f400000,0x3fa00000,0x3fe00000,0x40200000,0x40600000,0x40a00000,0x40e00000,0x41200000,0x41600000,0x41a00000,0x42100000,0x42500000,0x42900000,0x42d00000,0x43100000,0x43500000,0x43900000,0x43d00000,0x44100000,0x44500000,0x44a00000,0x45100000,0x45500000,0x45900000,0x45d00000,0x46400000,0x46800000,0x46c00000,0x47000000,0x47400000}, + /* ID: 734, value: 0, name: fbfNBlocks, multiplicity: 250 */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + /* ID: 735, value: 0.97, name: THR_MA_A_1, multiplicity: 1 */ + 0.97, + /* ID: 736, value: 0.97, name: THR_MA_A_2, multiplicity: 1 */ + 0.97, + /* ID: 737, value: 0.97, name: THR_MA_A_3, multiplicity: 1 */ + 0.97, + /* ID: 738, value: 0.97, name: THR_MA_A_4, multiplicity: 1 */ + 0.97, + /* ID: 739, value: 0.97, name: THR_MA_A_5, multiplicity: 1 */ + 0.97, + /* ID: 740, value: 0, name: wcet_1, multiplicity: 1 */ + 0, + /* ID: 741, value: 0, name: wcet_2, multiplicity: 1 */ + 0, + /* ID: 742, value: 0, name: wcet_3, multiplicity: 1 */ + 0, + /* ID: 743, value: 0, name: wcet_4, multiplicity: 1 */ + 0, + /* ID: 744, value: 0, name: wcet_5, multiplicity: 1 */ + 0, + /* ID: 745, value: 0, name: wcetAver_1, multiplicity: 1 */ + 0, + /* ID: 746, value: 0, name: wcetAver_2, multiplicity: 1 */ + 0, + /* ID: 747, value: 0, name: wcetAver_3, multiplicity: 1 */ + 0, + /* ID: 748, value: 0, name: wcetAver_4, multiplicity: 1 */ + 0, + /* ID: 749, value: 0, name: wcetAver_5, multiplicity: 1 */ + 0, + /* ID: 750, value: 0, name: wcetMax_1, multiplicity: 1 */ + 0, + /* ID: 751, value: 0, name: wcetMax_2, multiplicity: 1 */ + 0, + /* ID: 752, value: 0, name: wcetMax_3, multiplicity: 1 */ + 0, + /* ID: 753, value: 0, name: wcetMax_4, multiplicity: 1 */ + 0, + /* ID: 754, value: 0, name: wcetMax_5, multiplicity: 1 */ + 0, + /* ID: 755, value: 0, name: nOfNotif_1, multiplicity: 1 */ + 0, + /* ID: 756, value: 0, name: nOfNotif_2, multiplicity: 1 */ + 0, + /* ID: 757, value: 0, name: nOfNotif_3, multiplicity: 1 */ + 0, + /* ID: 758, value: 0, name: nOfNotif_4, multiplicity: 1 */ + 0, + /* ID: 759, value: 0, name: nOfNotif_5, multiplicity: 1 */ + 0, + /* ID: 760, value: 0, name: nofFuncExec_1, multiplicity: 1 */ + 0, + /* ID: 761, value: 0, name: nofFuncExec_2, multiplicity: 1 */ + 0, + /* ID: 762, value: 0, name: nofFuncExec_3, multiplicity: 1 */ + 0, + /* ID: 763, value: 0, name: nofFuncExec_4, multiplicity: 1 */ + 0, + /* ID: 764, value: 0, name: nofFuncExec_5, multiplicity: 1 */ + 0, + /* ID: 765, value: 0, name: wcetTimeStampFine_1, multiplicity: 1 */ + 0, + /* ID: 766, value: 0, name: wcetTimeStampFine_2, multiplicity: 1 */ + 0, + /* ID: 767, value: 0, name: wcetTimeStampFine_3, multiplicity: 1 */ + 0, + /* ID: 768, value: 0, name: wcetTimeStampFine_4, multiplicity: 1 */ + 0, + /* ID: 769, value: 0, name: wcetTimeStampFine_5, multiplicity: 1 */ + 0, + /* ID: 770, value: 0, name: wcetTimeStampCoarse_1, multiplicity: 1 */ + 0, + /* ID: 771, value: 0, name: wcetTimeStampCoarse_2, multiplicity: 1 */ + 0, + /* ID: 772, value: 0, name: wcetTimeStampCoarse_3, multiplicity: 1 */ + 0, + /* ID: 773, value: 0, name: wcetTimeStampCoarse_4, multiplicity: 1 */ + 0, + /* ID: 774, value: 0, name: wcetTimeStampCoarse_5, multiplicity: 1 */ + 0, + /* ID: 775, value: 0, name: flashContStepCnt, multiplicity: 1 */ + 0, + /* ID: 776, value: 99.43, name: OTA_TM1A_NOM, multiplicity: 1 */ + 99.43, + /* ID: 777, value: 98.94, name: OTA_TM1A_RED, multiplicity: 1 */ + 98.94, + /* ID: 778, value: 99.11, name: OTA_TM1B_NOM, multiplicity: 1 */ + 99.11, + /* ID: 779, value: 99.06, name: OTA_TM1B_RED, multiplicity: 1 */ + 99.06, + /* ID: 780, value: 99.02, name: OTA_TM2A_NOM, multiplicity: 1 */ + 99.02, + /* ID: 781, value: 98.93, name: OTA_TM2A_RED, multiplicity: 1 */ + 98.93, + /* ID: 782, value: 99.07, name: OTA_TM2B_NOM, multiplicity: 1 */ + 99.07, + /* ID: 783, value: 98.91, name: OTA_TM2B_RED, multiplicity: 1 */ + 98.91, + /* ID: 784, value: 98.74, name: OTA_TM3A_NOM, multiplicity: 1 */ + 98.74, + /* ID: 785, value: 98.61, name: OTA_TM3A_RED, multiplicity: 1 */ + 98.61, + /* ID: 786, value: 98.63, name: OTA_TM3B_NOM, multiplicity: 1 */ + 98.63, + /* ID: 787, value: 98.58, name: OTA_TM3B_RED, multiplicity: 1 */ + 98.58, + /* ID: 788, value: 98.35, name: OTA_TM4A_NOM, multiplicity: 1 */ + 98.35, + /* ID: 789, value: 98.5, name: OTA_TM4A_RED, multiplicity: 1 */ + 98.5, + /* ID: 790, value: 98.89, name: OTA_TM4B_NOM, multiplicity: 1 */ + 98.89, + /* ID: 791, value: 98.56, name: OTA_TM4B_RED, multiplicity: 1 */ + 98.56, + /* ID: 792, value: 0, name: Core0Load, multiplicity: 1 */ + 0, + /* ID: 793, value: 0, name: Core1Load, multiplicity: 1 */ + 0, + /* ID: 794, value: 0, name: InterruptRate, multiplicity: 1 */ + 0, + /* ID: 795, value: 0, name: CyclicalActivitiesCtr, multiplicity: 1 */ + 0, + /* ID: 796, value: 0, name: Uptime, multiplicity: 1 */ + 0, + /* ID: 797, value: 0, name: SemTick, multiplicity: 1 */ + 0, + /* ID: 801, value: 0, name: BAD_COPY_ID, multiplicity: 1 */ + 0, + /* ID: 802, value: 0, name: BAD_PASTE_ID, multiplicity: 1 */ + 0, + /* ID: 803, value: 0, name: ObcInputBufferPackets, multiplicity: 1 */ + 0, + /* ID: 804, value: 0, name: GrndInputBufferPackets, multiplicity: 1 */ + 0, + /* ID: 805, value: 0, name: MilBusBytesIn, multiplicity: 1 */ + 0, + /* ID: 806, value: 0, name: MilBusBytesOut, multiplicity: 1 */ + 0, + /* ID: 807, value: 0, name: MilBusDroppedBytes, multiplicity: 1 */ + 0, + /* ID: 808, value: 0, name: IRL1, multiplicity: 1 */ + 0, + /* ID: 809, value: 0, name: IRL1_AHBSTAT, multiplicity: 1 */ + 0, + /* ID: 810, value: 0, name: IRL1_GRGPIO_6, multiplicity: 1 */ + 0, + /* ID: 811, value: 0, name: IRL1_GRTIMER, multiplicity: 1 */ + 0, + /* ID: 812, value: 0, name: IRL1_GPTIMER_0, multiplicity: 1 */ + 0, + /* ID: 813, value: 0, name: IRL1_GPTIMER_1, multiplicity: 1 */ + 0, + /* ID: 814, value: 0, name: IRL1_GPTIMER_2, multiplicity: 1 */ + 0, + /* ID: 815, value: 0, name: IRL1_GPTIMER_3, multiplicity: 1 */ + 0, + /* ID: 816, value: 0, name: IRL1_IRQMP, multiplicity: 1 */ + 0, + /* ID: 817, value: 0, name: IRL1_B1553BRM, multiplicity: 1 */ + 0, + /* ID: 818, value: 0, name: IRL2, multiplicity: 1 */ + 0, + /* ID: 819, value: 0, name: IRL2_GRSPW2_0, multiplicity: 1 */ + 0, + /* ID: 820, value: 0, name: IRL2_GRSPW2_1, multiplicity: 1 */ + 0, + /* ID: 821, value: INACTIVE, name: SemRoute, multiplicity: 1 */ + 0, + /* ID: 822, value: 0, name: SpW0BytesIn, multiplicity: 1 */ + 0, + /* ID: 823, value: 0, name: SpW0BytesOut, multiplicity: 1 */ + 0, + /* ID: 824, value: 0, name: SpW1BytesIn, multiplicity: 1 */ + 0, + /* ID: 825, value: 0, name: SpW1BytesOut, multiplicity: 1 */ + 0, + /* ID: 826, value: 0, name: Spw0TxDescAvail, multiplicity: 1 */ + 0, + /* ID: 827, value: 0, name: Spw0RxPcktAvail, multiplicity: 1 */ + 0, + /* ID: 828, value: 0, name: Spw1TxDescAvail, multiplicity: 1 */ + 0, + /* ID: 829, value: 0, name: Spw1RxPcktAvail, multiplicity: 1 */ + 0, + /* ID: 830, value: 0, name: MilCucCoarseTime, multiplicity: 1 */ + 0, + /* ID: 831, value: 0, name: MilCucFineTime, multiplicity: 1 */ + 0, + /* ID: 832, value: 0, name: CucCoarseTime, multiplicity: 1 */ + 0, + /* ID: 833, value: 0, name: CucFineTime, multiplicity: 1 */ + 0, + /* ID: 841, value: 0, name: EdacDoubleFaults, multiplicity: 1 */ + 0, + /* ID: 842, value: 0, name: EdacDoubleFAddr, multiplicity: 1 */ + 0, + /* ID: 844, value: 1, name: HEARTBEAT_ENABLED, multiplicity: 1 */ + 1, + /* ID: 845, value: 0, name: S1AllocDbs, multiplicity: 1 */ + 0, + /* ID: 846, value: 0, name: S1AllocSw, multiplicity: 1 */ + 0, + /* ID: 847, value: 0, name: S1AllocHeap, multiplicity: 1 */ + 0, + /* ID: 848, value: 0, name: S1AllocFlash, multiplicity: 1 */ + 0, + /* ID: 849, value: 0, name: S1AllocAux, multiplicity: 1 */ + 0, + /* ID: 850, value: 0, name: S1AllocRes, multiplicity: 1 */ + 0, + /* ID: 851, value: 0, name: S1AllocSwap, multiplicity: 1 */ + 0, + /* ID: 852, value: 0, name: S2AllocSciHeap, multiplicity: 1 */ + 0, + /* ID: 954, value: 0, name: FPGA_Version, multiplicity: 1 */ + 0, + /* ID: 955, value: 0, name: FPGA_DPU_Status, multiplicity: 1 */ + 0, + /* ID: 956, value: 0, name: FPGA_DPU_Address, multiplicity: 1 */ + 0, + /* ID: 957, value: 0, name: FPGA_RESET_Status, multiplicity: 1 */ + 0, + /* ID: 958, value: 0, name: FPGA_SEM_Status, multiplicity: 1 */ + 0, + /* ID: 959, value: 0, name: FPGA_Oper_Heater_Status, multiplicity: 1 */ + 0 +}; + +/** + * Initialization of the array holding the size of data pool items. + * Mapping rules of type to size: + * bool, char, uchar - 1 byte + * short, ushort, enum - 2 bytes + * int, uint, float - 4 bytes + * double - 8 bytes + * CUC - 6 bytes + */ +static unsigned int dataPoolSize[1006] = { + 0, /* ID: 0, unused */ + 4, /* ID: 1, type: uint, name: buildNumber */ + 1, /* ID: 2, type: uchar, name: AppErrCode */ + 1, /* ID: 3, type: uchar, name: NofAllocatedInRep */ + 1, /* ID: 4, type: uchar, name: MaxNOfInRep */ + 1, /* ID: 5, type: uchar, name: NofAllocatedInCmd */ + 1, /* ID: 6, type: uchar, name: MaxNOfInCmd */ + 1, /* ID: 7, type: uchar, name: Sem_NOfPendingInCmp */ + 1, /* ID: 8, type: uchar, name: Sem_PCRLSize */ + 1, /* ID: 9, type: uchar, name: Sem_NOfLoadedInCmp */ + 1, /* ID: 10, type: uchar, name: GrdObc_NOfPendingInCmp */ + 1, /* ID: 11, type: uchar, name: GrdObc_PCRLSize */ + 1, /* ID: 12, type: uchar, name: NOfAllocatedOutCmp */ + 1, /* ID: 13, type: uchar, name: MaxNOfOutCmp */ + 2, /* ID: 14, type: ushort, name: NOfInstanceId */ + 1, /* ID: 15, type: uchar, name: OutMg1_NOfPendingOutCmp */ + 1, /* ID: 16, type: uchar, name: OutMg1_POCLSize */ + 2, /* ID: 17, type: ushort, name: OutMg1_NOfLoadedOutCmp */ + 1, /* ID: 18, type: uchar, name: OutMg2_NOfPendingOutCmp */ + 1, /* ID: 19, type: uchar, name: OutMg2_POCLSize */ + 2, /* ID: 20, type: ushort, name: OutMg2_NOfLoadedOutCmp */ + 1, /* ID: 21, type: uchar, name: OutMg3_NOfPendingOutCmp */ + 1, /* ID: 22, type: uchar, name: OutMg3_POCLSize */ + 2, /* ID: 23, type: ushort, name: OutMg3_NOfLoadedOutCmp */ + 4, /* ID: 24, type: uint, name: InSem_SeqCnt */ + 2, /* ID: 25, type: ushort, name: InSem_NOfPendingPckts */ + 1, /* ID: 26, type: uchar, name: InSem_NOfGroups */ + 1, /* ID: 27, type: uchar, name: InSem_PcktQueueSize */ + 1, /* ID: 28, type: uchar, name: InSem_Src */ + 1, /* ID: 29, type: uchar, name: InObc_NOfPendingPckts */ + 1, /* ID: 30, type: uchar, name: InObc_NOfGroups */ + 1, /* ID: 31, type: uchar, name: InObc_PcktQueueSize */ + 1, /* ID: 32, type: uchar, name: InObc_Src */ + 1, /* ID: 33, type: uchar, name: InGrd_NOfPendingPckts */ + 1, /* ID: 34, type: uchar, name: InGrd_NOfGroups */ + 1, /* ID: 35, type: uchar, name: InGrd_PcktQueueSize */ + 1, /* ID: 36, type: uchar, name: InGrd_Src */ + 1, /* ID: 37, type: uchar, name: OutSem_Dest */ + 4, /* ID: 38, type: uint, name: OutSem_SeqCnt */ + 1, /* ID: 39, type: uchar, name: OutSem_NOfPendingPckts */ + 1, /* ID: 40, type: uchar, name: OutSem_NOfGroups */ + 1, /* ID: 41, type: uchar, name: OutSem_PcktQueueSize */ + 1, /* ID: 42, type: uchar, name: OutObc_Dest */ + 4, /* ID: 43, type: uint, name: OutObc_SeqCnt_Group0 */ + 4, /* ID: 44, type: uint, name: OutObc_SeqCnt_Group1 */ + 1, /* ID: 45, type: uchar, name: OutObc_NOfPendingPckts */ + 1, /* ID: 46, type: uchar, name: OutObc_NOfGroups */ + 1, /* ID: 47, type: uchar, name: OutObc_PcktQueueSize */ + 1, /* ID: 48, type: uchar, name: OutGrd_Dest */ + 4, /* ID: 49, type: uint, name: OutGrd_SeqCnt_Group0 */ + 4, /* ID: 50, type: uint, name: OutGrd_SeqCnt_Group1 */ + 4, /* ID: 51, type: uint, name: OutGrd_SeqCnt_Group2 */ + 1, /* ID: 52, type: uchar, name: OutGrd_NOfPendingPckts */ + 1, /* ID: 53, type: uchar, name: OutGrd_NOfGroups */ + 1, /* ID: 54, type: uchar, name: OutGrd_PcktQueueSize */ + 2, /* ID: 55, type: ushort, name: sibNFull */ + 2, /* ID: 56, type: ushort, name: cibNFull */ + 2, /* ID: 57, type: ushort, name: gibNFull */ + 2, /* ID: 58, type: ushort, name: sibNWin */ + 2, /* ID: 59, type: ushort, name: cibNWin */ + 2, /* ID: 60, type: ushort, name: gibNWin */ + 2, /* ID: 61, type: ushort, name: sibSizeFull */ + 2, /* ID: 62, type: ushort, name: cibSizeFull */ + 2, /* ID: 63, type: ushort, name: gibSizeFull */ + 2, /* ID: 64, type: ushort, name: sibSizeWin */ + 2, /* ID: 65, type: ushort, name: cibSizeWin */ + 2, /* ID: 66, type: ushort, name: gibSizeWin */ + 2, /* ID: 67, type: ushort, name: sibIn */ + 2, /* ID: 68, type: ushort, name: sibOut */ + 2, /* ID: 69, type: ushort, name: cibIn */ + 2, /* ID: 70, type: ushort, name: gibIn */ + 2, /* ID: 71, type: ushort, name: gibOut */ + 2, /* ID: 72, type: enum, name: sdbState */ + 4, /* ID: 73, type: uint, name: sdbStateCnt */ + 4, /* ID: 74, type: int, name: OffsetX */ + 4, /* ID: 75, type: int, name: OffsetY */ + 4, /* ID: 76, type: int, name: TargetLocationX */ + 4, /* ID: 77, type: int, name: TargetLocationY */ + 4, /* ID: 78, type: uint, name: IntegStartTimeCrs */ + 2, /* ID: 79, type: ushort, name: IntegStartTimeFine */ + 4, /* ID: 80, type: uint, name: IntegEndTimeCrs */ + 2, /* ID: 81, type: ushort, name: IntegEndTimeFine */ + 2, /* ID: 82, type: ushort, name: DataCadence */ + 1, /* ID: 83, type: char, name: ValidityStatus */ + 2, /* ID: 84, type: ushort, name: NOfTcAcc */ + 2, /* ID: 85, type: ushort, name: NOfAccFailedTc */ + 2, /* ID: 86, type: ushort, name: SeqCntLastAccTcFromObc */ + 2, /* ID: 87, type: ushort, name: SeqCntLastAccTcFromGrd */ + 2, /* ID: 88, type: ushort, name: SeqCntLastAccFailTc */ + 2, /* ID: 89, type: ushort, name: NOfStartFailedTc */ + 2, /* ID: 90, type: ushort, name: SeqCntLastStartFailTc */ + 2, /* ID: 91, type: ushort, name: NOfTcTerm */ + 2, /* ID: 92, type: ushort, name: NOfTermFailedTc */ + 2, /* ID: 93, type: ushort, name: SeqCntLastTermFailTc */ + 1, /* ID: 94, type: uchar, name: RdlSidList */ + 1, /* ID: 95, type: bool, name: isRdlFree */ + 4, /* ID: 96, type: uint, name: RdlCycCntList */ + 4, /* ID: 97, type: uint, name: RdlPeriodList */ + 1, /* ID: 98, type: bool, name: RdlEnabledList */ + 2, /* ID: 99, type: ushort, name: RdlDestList */ + 2, /* ID: 100, type: ushort, name: RdlDataItemList_0 */ + 2, /* ID: 101, type: ushort, name: RdlDataItemList_1 */ + 2, /* ID: 102, type: ushort, name: RdlDataItemList_2 */ + 2, /* ID: 103, type: ushort, name: RdlDataItemList_3 */ + 2, /* ID: 104, type: ushort, name: RdlDataItemList_4 */ + 2, /* ID: 105, type: ushort, name: RdlDataItemList_5 */ + 2, /* ID: 106, type: ushort, name: RdlDataItemList_6 */ + 2, /* ID: 107, type: ushort, name: RdlDataItemList_7 */ + 2, /* ID: 108, type: ushort, name: RdlDataItemList_8 */ + 2, /* ID: 109, type: ushort, name: RdlDataItemList_9 */ + 4, /* ID: 110, type: uint, name: DEBUG_VAR */ + 4, /* ID: 111, type: uint, name: DEBUG_VAR_ADDR */ + 1, /* ID: 112, type: uchar, name: EVTFILTERDEF */ + 1, /* ID: 113, type: uchar, name: evtEnabledList */ + 4, /* ID: 114, type: uint, name: lastPatchedAddr */ + 4, /* ID: 115, type: uint, name: lastDumpAddr */ + 2, /* ID: 116, type: enum, name: sdu2State */ + 2, /* ID: 117, type: enum, name: sdu4State */ + 4, /* ID: 118, type: uint, name: sdu2StateCnt */ + 4, /* ID: 119, type: uint, name: sdu4StateCnt */ + 2, /* ID: 120, type: ushort, name: sdu2BlockCnt */ + 2, /* ID: 121, type: ushort, name: sdu4BlockCnt */ + 4, /* ID: 122, type: uint, name: sdu2RemSize */ + 4, /* ID: 123, type: uint, name: sdu4RemSize */ + 4, /* ID: 124, type: uint, name: sdu2DownTransferSize */ + 4, /* ID: 125, type: uint, name: sdu4DownTransferSize */ + 4, /* ID: 126, type: uint, name: sdsCounter */ + 1, /* ID: 127, type: bool, name: FdGlbEnable */ + 1, /* ID: 128, type: bool, name: RpGlbEnable */ + 2, /* ID: 129, type: enum, name: FdCheckTTMState */ + 1, /* ID: 130, type: bool, name: FdCheckTTMIntEn */ + 1, /* ID: 131, type: bool, name: FdCheckTTMExtEn */ + 1, /* ID: 132, type: bool, name: RpTTMIntEn */ + 1, /* ID: 133, type: bool, name: RpTTMExtEn */ + 2, /* ID: 134, type: ushort, name: FdCheckTTMCnt */ + 2, /* ID: 135, type: ushort, name: FdCheckTTMSpCnt */ + 2, /* ID: 136, type: ushort, name: FdCheckTTMCntThr */ + 4, /* ID: 137, type: float, name: TTC_LL */ + 4, /* ID: 138, type: float, name: TTC_UL */ + 4, /* ID: 139, type: float, name: TTM_LIM */ + 2, /* ID: 140, type: enum, name: FdCheckSDSCState */ + 1, /* ID: 141, type: bool, name: FdCheckSDSCIntEn */ + 1, /* ID: 142, type: bool, name: FdCheckSDSCExtEn */ + 1, /* ID: 143, type: bool, name: RpSDSCIntEn */ + 1, /* ID: 144, type: bool, name: RpSDSCExtEn */ + 2, /* ID: 145, type: ushort, name: FdCheckSDSCCnt */ + 2, /* ID: 146, type: ushort, name: FdCheckSDSCSpCnt */ + 2, /* ID: 147, type: ushort, name: FdCheckSDSCCntThr */ + 2, /* ID: 148, type: enum, name: FdCheckComErrState */ + 1, /* ID: 149, type: bool, name: FdCheckComErrIntEn */ + 1, /* ID: 150, type: bool, name: FdCheckComErrExtEn */ + 1, /* ID: 151, type: bool, name: RpComErrIntEn */ + 1, /* ID: 152, type: bool, name: RpComErrExtEn */ + 2, /* ID: 153, type: ushort, name: FdCheckComErrCnt */ + 2, /* ID: 154, type: ushort, name: FdCheckComErrSpCnt */ + 2, /* ID: 155, type: ushort, name: FdCheckComErrCntThr */ + 2, /* ID: 156, type: enum, name: FdCheckTimeOutState */ + 1, /* ID: 157, type: bool, name: FdCheckTimeOutIntEn */ + 1, /* ID: 158, type: bool, name: FdCheckTimeOutExtEn */ + 1, /* ID: 159, type: bool, name: RpTimeOutIntEn */ + 1, /* ID: 160, type: bool, name: RpTimeOutExtEn */ + 2, /* ID: 161, type: ushort, name: FdCheckTimeOutCnt */ + 2, /* ID: 162, type: ushort, name: FdCheckTimeOutSpCnt */ + 2, /* ID: 163, type: ushort, name: FdCheckTimeOutCntThr */ + 4, /* ID: 164, type: uint, name: SEM_TO_POWERON */ + 4, /* ID: 165, type: uint, name: SEM_TO_SAFE */ + 4, /* ID: 166, type: uint, name: SEM_TO_STAB */ + 4, /* ID: 167, type: uint, name: SEM_TO_TEMP */ + 4, /* ID: 168, type: uint, name: SEM_TO_CCD */ + 4, /* ID: 169, type: uint, name: SEM_TO_DIAG */ + 4, /* ID: 170, type: uint, name: SEM_TO_STANDBY */ + 2, /* ID: 171, type: enum, name: FdCheckSafeModeState */ + 1, /* ID: 172, type: bool, name: FdCheckSafeModeIntEn */ + 1, /* ID: 173, type: bool, name: FdCheckSafeModeExtEn */ + 1, /* ID: 174, type: bool, name: RpSafeModeIntEn */ + 1, /* ID: 175, type: bool, name: RpSafeModeExtEn */ + 2, /* ID: 176, type: ushort, name: FdCheckSafeModeCnt */ + 2, /* ID: 177, type: ushort, name: FdCheckSafeModeSpCnt */ + 2, /* ID: 178, type: ushort, name: FdCheckSafeModeCntThr */ + 2, /* ID: 179, type: enum, name: FdCheckAliveState */ + 1, /* ID: 180, type: bool, name: FdCheckAliveIntEn */ + 1, /* ID: 181, type: bool, name: FdCheckAliveExtEn */ + 1, /* ID: 182, type: bool, name: RpAliveIntEn */ + 1, /* ID: 183, type: bool, name: RpAliveExtEn */ + 2, /* ID: 184, type: ushort, name: FdCheckAliveCnt */ + 2, /* ID: 185, type: ushort, name: FdCheckAliveSpCnt */ + 2, /* ID: 186, type: ushort, name: FdCheckAliveCntThr */ + 2, /* ID: 187, type: ushort, name: SEM_HK_DEF_PER */ + 2, /* ID: 188, type: ushort, name: SEMALIVE_DELAYEDSEMHK */ + 2, /* ID: 189, type: enum, name: FdCheckSemAnoEvtState */ + 1, /* ID: 190, type: bool, name: FdCheckSemAnoEvtIntEn */ + 1, /* ID: 191, type: bool, name: FdCheckSemAnoEvtExtEn */ + 1, /* ID: 192, type: bool, name: RpSemAnoEvtIntEn */ + 1, /* ID: 193, type: bool, name: RpSemAnoEvtExtEn */ + 2, /* ID: 194, type: ushort, name: FdCheckSemAnoEvtCnt */ + 2, /* ID: 195, type: ushort, name: FdCheckSemAnoEvtSpCnt */ + 2, /* ID: 196, type: ushort, name: FdCheckSemAnoEvtCntThr */ + 2, /* ID: 197, type: enum, name: semAnoEvtResp_1 */ + 2, /* ID: 198, type: enum, name: semAnoEvtResp_2 */ + 2, /* ID: 199, type: enum, name: semAnoEvtResp_3 */ + 2, /* ID: 200, type: enum, name: semAnoEvtResp_4 */ + 2, /* ID: 201, type: enum, name: semAnoEvtResp_5 */ + 2, /* ID: 202, type: enum, name: semAnoEvtResp_6 */ + 2, /* ID: 203, type: enum, name: semAnoEvtResp_7 */ + 2, /* ID: 204, type: enum, name: semAnoEvtResp_8 */ + 2, /* ID: 205, type: enum, name: semAnoEvtResp_9 */ + 2, /* ID: 206, type: enum, name: semAnoEvtResp_10 */ + 2, /* ID: 207, type: enum, name: semAnoEvtResp_11 */ + 2, /* ID: 208, type: enum, name: semAnoEvtResp_12 */ + 2, /* ID: 209, type: enum, name: semAnoEvtResp_13 */ + 2, /* ID: 210, type: enum, name: semAnoEvtResp_14 */ + 2, /* ID: 211, type: enum, name: semAnoEvtResp_15 */ + 2, /* ID: 212, type: enum, name: semAnoEvtResp_16 */ + 2, /* ID: 213, type: enum, name: semAnoEvtResp_17 */ + 2, /* ID: 214, type: enum, name: semAnoEvtResp_18 */ + 2, /* ID: 215, type: enum, name: semAnoEvtResp_19 */ + 2, /* ID: 216, type: enum, name: semAnoEvtResp_20 */ + 2, /* ID: 217, type: enum, name: semAnoEvtResp_21 */ + 2, /* ID: 218, type: enum, name: semAnoEvtResp_22 */ + 2, /* ID: 219, type: enum, name: semAnoEvtResp_23 */ + 2, /* ID: 220, type: enum, name: semAnoEvtResp_24 */ + 2, /* ID: 221, type: enum, name: semAnoEvtResp_25 */ + 2, /* ID: 222, type: enum, name: semAnoEvtResp_26 */ + 2, /* ID: 223, type: enum, name: semAnoEvtResp_27 */ + 2, /* ID: 224, type: enum, name: semAnoEvtResp_28 */ + 2, /* ID: 225, type: enum, name: semAnoEvtResp_29 */ + 2, /* ID: 226, type: enum, name: FdCheckSemLimitState */ + 1, /* ID: 227, type: bool, name: FdCheckSemLimitIntEn */ + 1, /* ID: 228, type: bool, name: FdCheckSemLimitExtEn */ + 1, /* ID: 229, type: bool, name: RpSemLimitIntEn */ + 1, /* ID: 230, type: bool, name: RpSemLimitExtEn */ + 2, /* ID: 231, type: ushort, name: FdCheckSemLimitCnt */ + 2, /* ID: 232, type: ushort, name: FdCheckSemLimitSpCnt */ + 2, /* ID: 233, type: ushort, name: FdCheckSemLimitCntThr */ + 2, /* ID: 234, type: ushort, name: SEM_LIM_DEL_T */ + 2, /* ID: 235, type: enum, name: FdCheckDpuHkState */ + 1, /* ID: 236, type: bool, name: FdCheckDpuHkIntEn */ + 1, /* ID: 237, type: bool, name: FdCheckDpuHkExtEn */ + 1, /* ID: 238, type: bool, name: RpDpuHkIntEn */ + 1, /* ID: 239, type: bool, name: RpDpuHkExtEn */ + 2, /* ID: 240, type: ushort, name: FdCheckDpuHkCnt */ + 2, /* ID: 241, type: ushort, name: FdCheckDpuHkSpCnt */ + 2, /* ID: 242, type: ushort, name: FdCheckDpuHkCntThr */ + 2, /* ID: 243, type: enum, name: FdCheckCentConsState */ + 1, /* ID: 244, type: bool, name: FdCheckCentConsIntEn */ + 1, /* ID: 245, type: bool, name: FdCheckCentConsExtEn */ + 1, /* ID: 246, type: bool, name: RpCentConsIntEn */ + 1, /* ID: 247, type: bool, name: RpCentConsExtEn */ + 2, /* ID: 248, type: ushort, name: FdCheckCentConsCnt */ + 2, /* ID: 249, type: ushort, name: FdCheckCentConsSpCnt */ + 2, /* ID: 250, type: ushort, name: FdCheckCentConsCntThr */ + 2, /* ID: 251, type: enum, name: FdCheckResState */ + 1, /* ID: 252, type: bool, name: FdCheckResIntEn */ + 1, /* ID: 253, type: bool, name: FdCheckResExtEn */ + 1, /* ID: 254, type: bool, name: RpResIntEn */ + 1, /* ID: 255, type: bool, name: RpResExtEn */ + 2, /* ID: 256, type: ushort, name: FdCheckResCnt */ + 2, /* ID: 257, type: ushort, name: FdCheckResSpCnt */ + 2, /* ID: 258, type: ushort, name: FdCheckResCntThr */ + 4, /* ID: 259, type: float, name: CPU1_USAGE_MAX */ + 4, /* ID: 260, type: float, name: MEM_USAGE_MAX */ + 2, /* ID: 261, type: enum, name: FdCheckSemCons */ + 1, /* ID: 262, type: bool, name: FdCheckSemConsIntEn */ + 1, /* ID: 263, type: bool, name: FdCheckSemConsExtEn */ + 1, /* ID: 264, type: bool, name: RpSemConsIntEn */ + 1, /* ID: 265, type: bool, name: RpSemConsExtEn */ + 2, /* ID: 266, type: ushort, name: FdCheckSemConsCnt */ + 2, /* ID: 267, type: ushort, name: FdCheckSemConsSpCnt */ + 2, /* ID: 268, type: ushort, name: FdCheckSemConsCntThr */ + 2, /* ID: 269, type: enum, name: semState */ + 2, /* ID: 270, type: enum, name: semOperState */ + 4, /* ID: 271, type: uint, name: semStateCnt */ + 4, /* ID: 272, type: uint, name: semOperStateCnt */ + 4, /* ID: 273, type: uint, name: imageCycleCnt */ + 4, /* ID: 274, type: uint, name: acqImageCnt */ + 2, /* ID: 275, type: enum, name: sciSubMode */ + 1, /* ID: 276, type: bool, name: LastSemPckt */ + 1, /* ID: 277, type: uchar, name: SEM_ON_CODE */ + 1, /* ID: 278, type: uchar, name: SEM_OFF_CODE */ + 2, /* ID: 279, type: ushort, name: SEM_INIT_T1 */ + 2, /* ID: 280, type: ushort, name: SEM_INIT_T2 */ + 2, /* ID: 281, type: ushort, name: SEM_OPER_T1 */ + 2, /* ID: 282, type: ushort, name: SEM_SHUTDOWN_T1 */ + 2, /* ID: 283, type: ushort, name: SEM_SHUTDOWN_T11 */ + 2, /* ID: 284, type: ushort, name: SEM_SHUTDOWN_T12 */ + 2, /* ID: 285, type: ushort, name: SEM_SHUTDOWN_T2 */ + 2, /* ID: 286, type: enum, name: iaswState */ + 4, /* ID: 287, type: uint, name: iaswStateCnt */ + 4, /* ID: 288, type: uint, name: iaswCycleCnt */ + 2, /* ID: 289, type: enum, name: prepScienceNode */ + 4, /* ID: 290, type: uint, name: prepScienceCnt */ + 2, /* ID: 291, type: enum, name: controlledSwitchOffNode */ + 4, /* ID: 292, type: uint, name: controlledSwitchOffCnt */ + 2, /* ID: 293, type: ushort, name: CTRLD_SWITCH_OFF_T1 */ + 2, /* ID: 294, type: enum, name: algoCent0State */ + 4, /* ID: 295, type: uint, name: algoCent0Cnt */ + 1, /* ID: 296, type: bool, name: algoCent0Enabled */ + 2, /* ID: 297, type: enum, name: algoCent1State */ + 4, /* ID: 298, type: uint, name: algoCent1Cnt */ + 1, /* ID: 299, type: bool, name: algoCent1Enabled */ + 4, /* ID: 300, type: uint, name: CENT_EXEC_PHASE */ + 2, /* ID: 301, type: enum, name: algoAcq1State */ + 4, /* ID: 302, type: uint, name: algoAcq1Cnt */ + 1, /* ID: 303, type: bool, name: algoAcq1Enabled */ + 2, /* ID: 304, type: ushort, name: ACQ_PH */ + 2, /* ID: 305, type: enum, name: algoCcState */ + 4, /* ID: 306, type: uint, name: algoCcCnt */ + 1, /* ID: 307, type: bool, name: algoCcEnabled */ + 2, /* ID: 308, type: ushort, name: STCK_ORDER */ + 2, /* ID: 309, type: enum, name: algoTTC1State */ + 4, /* ID: 310, type: uint, name: algoTTC1Cnt */ + 1, /* ID: 311, type: bool, name: algoTTC1Enabled */ + 4, /* ID: 312, type: uint, name: TTC1_EXEC_PHASE */ + 4, /* ID: 313, type: int, name: TTC1_EXEC_PER */ + 4, /* ID: 314, type: float, name: TTC1_LL_FRT */ + 4, /* ID: 315, type: float, name: TTC1_LL_AFT */ + 4, /* ID: 316, type: float, name: TTC1_UL_FRT */ + 4, /* ID: 317, type: float, name: TTC1_UL_AFT */ + 4, /* ID: 318, type: float, name: ttc1AvTempAft */ + 4, /* ID: 319, type: float, name: ttc1AvTempFrt */ + 2, /* ID: 320, type: enum, name: algoTTC2State */ + 4, /* ID: 321, type: uint, name: algoTTC2Cnt */ + 1, /* ID: 322, type: bool, name: algoTTC2Enabled */ + 4, /* ID: 323, type: int, name: TTC2_EXEC_PER */ + 4, /* ID: 324, type: float, name: TTC2_REF_TEMP */ + 4, /* ID: 325, type: float, name: TTC2_OFFSETA */ + 4, /* ID: 326, type: float, name: TTC2_OFFSETF */ + 4, /* ID: 327, type: float, name: intTimeAft */ + 4, /* ID: 328, type: float, name: onTimeAft */ + 4, /* ID: 329, type: float, name: intTimeFront */ + 4, /* ID: 330, type: float, name: onTimeFront */ + 4, /* ID: 331, type: float, name: TTC2_PA */ + 4, /* ID: 332, type: float, name: TTC2_DA */ + 4, /* ID: 333, type: float, name: TTC2_IA */ + 4, /* ID: 334, type: float, name: TTC2_PF */ + 4, /* ID: 335, type: float, name: TTC2_DF */ + 4, /* ID: 336, type: float, name: TTC2_IF */ + 2, /* ID: 337, type: enum, name: algoSaaEvalState */ + 4, /* ID: 338, type: uint, name: algoSaaEvalCnt */ + 1, /* ID: 339, type: bool, name: algoSaaEvalEnabled */ + 4, /* ID: 340, type: uint, name: SAA_EXEC_PHASE */ + 4, /* ID: 341, type: int, name: SAA_EXEC_PER */ + 1, /* ID: 342, type: bool, name: isSaaActive */ + 4, /* ID: 343, type: uint, name: saaCounter */ + 4, /* ID: 344, type: uint, name: pInitSaaCounter */ + 2, /* ID: 345, type: enum, name: algoSdsEvalState */ + 4, /* ID: 346, type: uint, name: algoSdsEvalCnt */ + 1, /* ID: 347, type: bool, name: algoSdsEvalEnabled */ + 4, /* ID: 348, type: uint, name: SDS_EXEC_PHASE */ + 4, /* ID: 349, type: int, name: SDS_EXEC_PER */ + 1, /* ID: 350, type: bool, name: isSdsActive */ + 1, /* ID: 351, type: bool, name: SDS_FORCED */ + 1, /* ID: 352, type: bool, name: SDS_INHIBITED */ + 1, /* ID: 353, type: bool, name: EARTH_OCCULT_ACTIVE */ + 2, /* ID: 354, type: ushort, name: HEARTBEAT_D1 */ + 2, /* ID: 355, type: ushort, name: HEARTBEAT_D2 */ + 1, /* ID: 356, type: bool, name: HbSem */ + 1, /* ID: 357, type: uchar, name: starMap */ + 4, /* ID: 358, type: uint, name: observationId */ + 1, /* ID: 359, type: char, name: centValProcOutput */ + 4, /* ID: 360, type: float, name: CENT_OFFSET_LIM */ + 4, /* ID: 361, type: float, name: CENT_FROZEN_LIM */ + 1, /* ID: 362, type: bool, name: SEM_SERV1_1_FORWARD */ + 1, /* ID: 363, type: bool, name: SEM_SERV1_2_FORWARD */ + 1, /* ID: 364, type: bool, name: SEM_SERV1_7_FORWARD */ + 1, /* ID: 365, type: bool, name: SEM_SERV1_8_FORWARD */ + 1, /* ID: 366, type: bool, name: SEM_SERV3_1_FORWARD */ + 1, /* ID: 367, type: bool, name: SEM_SERV3_2_FORWARD */ + 4, /* ID: 368, type: uint, name: SEM_HK_TS_DEF_CRS */ + 2, /* ID: 369, type: ushort, name: SEM_HK_TS_DEF_FINE */ + 4, /* ID: 370, type: uint, name: SEM_HK_TS_EXT_CRS */ + 2, /* ID: 371, type: ushort, name: SEM_HK_TS_EXT_FINE */ + 2, /* ID: 372, type: enum, name: STAT_MODE */ + 2, /* ID: 373, type: ushort, name: STAT_FLAGS */ + 2, /* ID: 374, type: enum, name: STAT_LAST_SPW_ERR */ + 2, /* ID: 375, type: ushort, name: STAT_LAST_ERR_ID */ + 2, /* ID: 376, type: ushort, name: STAT_LAST_ERR_FREQ */ + 2, /* ID: 377, type: ushort, name: STAT_NUM_CMD_RECEIVED */ + 2, /* ID: 378, type: ushort, name: STAT_NUM_CMD_EXECUTED */ + 2, /* ID: 379, type: ushort, name: STAT_NUM_DATA_SENT */ + 2, /* ID: 380, type: ushort, name: STAT_SCU_PROC_DUTY_CL */ + 2, /* ID: 381, type: ushort, name: STAT_SCU_NUM_AHB_ERR */ + 2, /* ID: 382, type: ushort, name: STAT_SCU_NUM_AHB_CERR */ + 2, /* ID: 383, type: ushort, name: STAT_SCU_NUM_LUP_ERR */ + 4, /* ID: 384, type: float, name: TEMP_SEM_SCU */ + 4, /* ID: 385, type: float, name: TEMP_SEM_PCU */ + 4, /* ID: 386, type: float, name: VOLT_SCU_P3_4 */ + 4, /* ID: 387, type: float, name: VOLT_SCU_P5 */ + 4, /* ID: 388, type: float, name: TEMP_FEE_CCD */ + 4, /* ID: 389, type: float, name: TEMP_FEE_STRAP */ + 4, /* ID: 390, type: float, name: TEMP_FEE_ADC */ + 4, /* ID: 391, type: float, name: TEMP_FEE_BIAS */ + 4, /* ID: 392, type: float, name: TEMP_FEE_DEB */ + 4, /* ID: 393, type: float, name: VOLT_FEE_VOD */ + 4, /* ID: 394, type: float, name: VOLT_FEE_VRD */ + 4, /* ID: 395, type: float, name: VOLT_FEE_VOG */ + 4, /* ID: 396, type: float, name: VOLT_FEE_VSS */ + 4, /* ID: 397, type: float, name: VOLT_FEE_CCD */ + 4, /* ID: 398, type: float, name: VOLT_FEE_CLK */ + 4, /* ID: 399, type: float, name: VOLT_FEE_ANA_P5 */ + 4, /* ID: 400, type: float, name: VOLT_FEE_ANA_N5 */ + 4, /* ID: 401, type: float, name: VOLT_FEE_ANA_P3_3 */ + 4, /* ID: 402, type: float, name: CURR_FEE_CLK_BUF */ + 4, /* ID: 403, type: float, name: VOLT_SCU_FPGA_P1_5 */ + 4, /* ID: 404, type: float, name: CURR_SCU_P3_4 */ + 1, /* ID: 405, type: uchar, name: STAT_NUM_SPW_ERR_CRE */ + 1, /* ID: 406, type: uchar, name: STAT_NUM_SPW_ERR_ESC */ + 1, /* ID: 407, type: uchar, name: STAT_NUM_SPW_ERR_DISC */ + 1, /* ID: 408, type: uchar, name: STAT_NUM_SPW_ERR_PAR */ + 1, /* ID: 409, type: uchar, name: STAT_NUM_SPW_ERR_WRSY */ + 1, /* ID: 410, type: uchar, name: STAT_NUM_SPW_ERR_INVA */ + 1, /* ID: 411, type: uchar, name: STAT_NUM_SPW_ERR_EOP */ + 1, /* ID: 412, type: uchar, name: STAT_NUM_SPW_ERR_RXAH */ + 1, /* ID: 413, type: uchar, name: STAT_NUM_SPW_ERR_TXAH */ + 1, /* ID: 414, type: uchar, name: STAT_NUM_SPW_ERR_TXBL */ + 1, /* ID: 415, type: uchar, name: STAT_NUM_SPW_ERR_TXLE */ + 1, /* ID: 416, type: uchar, name: STAT_NUM_SP_ERR_RX */ + 1, /* ID: 417, type: uchar, name: STAT_NUM_SP_ERR_TX */ + 1, /* ID: 418, type: uchar, name: STAT_HEAT_PWM_FPA_CCD */ + 1, /* ID: 419, type: uchar, name: STAT_HEAT_PWM_FEE_STR */ + 1, /* ID: 420, type: uchar, name: STAT_HEAT_PWM_FEE_ANA */ + 1, /* ID: 421, type: uchar, name: STAT_HEAT_PWM_SPARE */ + 1, /* ID: 422, type: uchar, name: STAT_HEAT_PWM_FLAGS */ + 2, /* ID: 423, type: ushort, name: STAT_OBTIME_SYNC_DELTA */ + 4, /* ID: 424, type: float, name: TEMP_SEM_SCU_LW */ + 4, /* ID: 425, type: float, name: TEMP_SEM_PCU_LW */ + 4, /* ID: 426, type: float, name: VOLT_SCU_P3_4_LW */ + 4, /* ID: 427, type: float, name: VOLT_SCU_P5_LW */ + 4, /* ID: 428, type: float, name: TEMP_FEE_CCD_LW */ + 4, /* ID: 429, type: float, name: TEMP_FEE_STRAP_LW */ + 4, /* ID: 430, type: float, name: TEMP_FEE_ADC_LW */ + 4, /* ID: 431, type: float, name: TEMP_FEE_BIAS_LW */ + 4, /* ID: 432, type: float, name: TEMP_FEE_DEB_LW */ + 4, /* ID: 433, type: float, name: VOLT_FEE_VOD_LW */ + 4, /* ID: 434, type: float, name: VOLT_FEE_VRD_LW */ + 4, /* ID: 435, type: float, name: VOLT_FEE_VOG_LW */ + 4, /* ID: 436, type: float, name: VOLT_FEE_VSS_LW */ + 4, /* ID: 437, type: float, name: VOLT_FEE_CCD_LW */ + 4, /* ID: 438, type: float, name: VOLT_FEE_CLK_LW */ + 4, /* ID: 439, type: float, name: VOLT_FEE_ANA_P5_LW */ + 4, /* ID: 440, type: float, name: VOLT_FEE_ANA_N5_LW */ + 4, /* ID: 441, type: float, name: VOLT_FEE_ANA_P3_3_LW */ + 4, /* ID: 442, type: float, name: CURR_FEE_CLK_BUF_LW */ + 4, /* ID: 443, type: float, name: VOLT_SCU_FPGA_P1_5_LW */ + 4, /* ID: 444, type: float, name: CURR_SCU_P3_4_LW */ + 4, /* ID: 445, type: float, name: TEMP_SEM_SCU_UW */ + 4, /* ID: 446, type: float, name: TEMP_SEM_PCU_UW */ + 4, /* ID: 447, type: float, name: VOLT_SCU_P3_4_UW */ + 4, /* ID: 448, type: float, name: VOLT_SCU_P5_UW */ + 4, /* ID: 449, type: float, name: TEMP_FEE_CCD_UW */ + 4, /* ID: 450, type: float, name: TEMP_FEE_STRAP_UW */ + 4, /* ID: 451, type: float, name: TEMP_FEE_ADC_UW */ + 4, /* ID: 452, type: float, name: TEMP_FEE_BIAS_UW */ + 4, /* ID: 453, type: float, name: TEMP_FEE_DEB_UW */ + 4, /* ID: 454, type: float, name: VOLT_FEE_VOD_UW */ + 4, /* ID: 455, type: float, name: VOLT_FEE_VRD_UW */ + 4, /* ID: 456, type: float, name: VOLT_FEE_VOG_UW */ + 4, /* ID: 457, type: float, name: VOLT_FEE_VSS_UW */ + 4, /* ID: 458, type: float, name: VOLT_FEE_CCD_UW */ + 4, /* ID: 459, type: float, name: VOLT_FEE_CLK_UW */ + 4, /* ID: 460, type: float, name: VOLT_FEE_ANA_P5_UW */ + 4, /* ID: 461, type: float, name: VOLT_FEE_ANA_N5_UW */ + 4, /* ID: 462, type: float, name: VOLT_FEE_ANA_P3_3_UW */ + 4, /* ID: 463, type: float, name: CURR_FEE_CLK_BUF_UW */ + 4, /* ID: 464, type: float, name: VOLT_SCU_FPGA_P1_5_UW */ + 4, /* ID: 465, type: float, name: CURR_SCU_P3_4_UW */ + 4, /* ID: 466, type: float, name: TEMP_SEM_SCU_LA */ + 4, /* ID: 467, type: float, name: TEMP_SEM_PCU_LA */ + 4, /* ID: 468, type: float, name: VOLT_SCU_P3_4_LA */ + 4, /* ID: 469, type: float, name: VOLT_SCU_P5_LA */ + 4, /* ID: 470, type: float, name: TEMP_FEE_CCD_LA */ + 4, /* ID: 471, type: float, name: TEMP_FEE_STRAP_LA */ + 4, /* ID: 472, type: float, name: TEMP_FEE_ADC_LA */ + 4, /* ID: 473, type: float, name: TEMP_FEE_BIAS_LA */ + 4, /* ID: 474, type: float, name: TEMP_FEE_DEB_LA */ + 4, /* ID: 475, type: float, name: VOLT_FEE_VOD_LA */ + 4, /* ID: 476, type: float, name: VOLT_FEE_VRD_LA */ + 4, /* ID: 477, type: float, name: VOLT_FEE_VOG_LA */ + 4, /* ID: 478, type: float, name: VOLT_FEE_VSS_LA */ + 4, /* ID: 479, type: float, name: VOLT_FEE_CCD_LA */ + 4, /* ID: 480, type: float, name: VOLT_FEE_CLK_LA */ + 4, /* ID: 481, type: float, name: VOLT_FEE_ANA_P5_LA */ + 4, /* ID: 482, type: float, name: VOLT_FEE_ANA_N5_LA */ + 4, /* ID: 483, type: float, name: VOLT_FEE_ANA_P3_3_LA */ + 4, /* ID: 484, type: float, name: CURR_FEE_CLK_BUF_LA */ + 4, /* ID: 485, type: float, name: VOLT_SCU_FPGA_P1_5_LA */ + 4, /* ID: 486, type: float, name: CURR_SCU_P3_4_LA */ + 4, /* ID: 487, type: float, name: TEMP_SEM_SCU_UA */ + 4, /* ID: 488, type: float, name: TEMP_SEM_PCU_UA */ + 4, /* ID: 489, type: float, name: VOLT_SCU_P3_4_UA */ + 4, /* ID: 490, type: float, name: VOLT_SCU_P5_UA */ + 4, /* ID: 491, type: float, name: TEMP_FEE_CCD_UA */ + 4, /* ID: 492, type: float, name: TEMP_FEE_STRAP_UA */ + 4, /* ID: 493, type: float, name: TEMP_FEE_ADC_UA */ + 4, /* ID: 494, type: float, name: TEMP_FEE_BIAS_UA */ + 4, /* ID: 495, type: float, name: TEMP_FEE_DEB_UA */ + 4, /* ID: 496, type: float, name: VOLT_FEE_VOD_UA */ + 4, /* ID: 497, type: float, name: VOLT_FEE_VRD_UA */ + 4, /* ID: 498, type: float, name: VOLT_FEE_VOG_UA */ + 4, /* ID: 499, type: float, name: VOLT_FEE_VSS_UA */ + 4, /* ID: 500, type: float, name: VOLT_FEE_CCD_UA */ + 4, /* ID: 501, type: float, name: VOLT_FEE_CLK_UA */ + 4, /* ID: 502, type: float, name: VOLT_FEE_ANA_P5_UA */ + 4, /* ID: 503, type: float, name: VOLT_FEE_ANA_N5_UA */ + 4, /* ID: 504, type: float, name: VOLT_FEE_ANA_P3_3_UA */ + 4, /* ID: 505, type: float, name: CURR_FEE_CLK_BUF_UA */ + 4, /* ID: 506, type: float, name: VOLT_SCU_FPGA_P1_5_UA */ + 4, /* ID: 507, type: float, name: CURR_SCU_P3_4_UA */ + 4, /* ID: 508, type: uint, name: semEvtCounter */ + 1, /* ID: 509, type: bool, name: SEM_SERV5_1_FORWARD */ + 1, /* ID: 510, type: bool, name: SEM_SERV5_2_FORWARD */ + 1, /* ID: 511, type: bool, name: SEM_SERV5_3_FORWARD */ + 1, /* ID: 512, type: bool, name: SEM_SERV5_4_FORWARD */ + 4, /* ID: 513, type: uint, name: pExpTime */ + 4, /* ID: 514, type: uint, name: pImageRep */ + 4, /* ID: 515, type: uint, name: pAcqNum */ + 2, /* ID: 516, type: enum, name: pDataOs */ + 2, /* ID: 517, type: enum, name: pCcdRdMode */ + 2, /* ID: 518, type: ushort, name: pWinPosX */ + 2, /* ID: 519, type: ushort, name: pWinPosY */ + 2, /* ID: 520, type: ushort, name: pWinSizeX */ + 2, /* ID: 521, type: ushort, name: pWinSizeY */ + 2, /* ID: 522, type: enum, name: pDtAcqSrc */ + 2, /* ID: 523, type: enum, name: pTempCtrlTarget */ + 4, /* ID: 524, type: float, name: pVoltFeeVod */ + 4, /* ID: 525, type: float, name: pVoltFeeVrd */ + 4, /* ID: 526, type: float, name: pVoltFeeVss */ + 4, /* ID: 527, type: float, name: pHeatTempFpaCCd */ + 4, /* ID: 528, type: float, name: pHeatTempFeeStrap */ + 4, /* ID: 529, type: float, name: pHeatTempFeeAnach */ + 4, /* ID: 530, type: float, name: pHeatTempSpare */ + 2, /* ID: 531, type: enum, name: pStepEnDiagCcd */ + 2, /* ID: 532, type: enum, name: pStepEnDiagFee */ + 2, /* ID: 533, type: enum, name: pStepEnDiagTemp */ + 2, /* ID: 534, type: enum, name: pStepEnDiagAna */ + 2, /* ID: 535, type: enum, name: pStepEnDiagExpos */ + 2, /* ID: 536, type: enum, name: pStepDebDiagCcd */ + 2, /* ID: 537, type: enum, name: pStepDebDiagFee */ + 2, /* ID: 538, type: enum, name: pStepDebDiagTemp */ + 2, /* ID: 539, type: enum, name: pStepDebDiagAna */ + 2, /* ID: 540, type: enum, name: pStepDebDiagExpos */ + 1, /* ID: 541, type: bool, name: SEM_SERV220_6_FORWARD */ + 1, /* ID: 542, type: bool, name: SEM_SERV220_12_FORWARD */ + 1, /* ID: 543, type: bool, name: SEM_SERV222_6_FORWARD */ + 2, /* ID: 544, type: enum, name: saveImagesNode */ + 4, /* ID: 545, type: uint, name: saveImagesCnt */ + 2, /* ID: 546, type: enum, name: SaveImages_pSaveTarget */ + 1, /* ID: 547, type: uchar, name: SaveImages_pFbfInit */ + 1, /* ID: 548, type: uchar, name: SaveImages_pFbfEnd */ + 2, /* ID: 549, type: enum, name: acqFullDropNode */ + 4, /* ID: 550, type: uint, name: acqFullDropCnt */ + 4, /* ID: 551, type: uint, name: AcqFullDrop_pExpTime */ + 4, /* ID: 552, type: uint, name: AcqFullDrop_pImageRep */ + 4, /* ID: 553, type: uint, name: acqFullDropT1 */ + 4, /* ID: 554, type: uint, name: acqFullDropT2 */ + 2, /* ID: 555, type: enum, name: calFullSnapNode */ + 4, /* ID: 556, type: uint, name: calFullSnapCnt */ + 4, /* ID: 557, type: uint, name: CalFullSnap_pExpTime */ + 4, /* ID: 558, type: uint, name: CalFullSnap_pImageRep */ + 4, /* ID: 559, type: uint, name: CalFullSnap_pNmbImages */ + 2, /* ID: 560, type: enum, name: CalFullSnap_pCentSel */ + 4, /* ID: 561, type: uint, name: calFullSnapT1 */ + 4, /* ID: 562, type: uint, name: calFullSnapT2 */ + 2, /* ID: 563, type: enum, name: SciWinNode */ + 4, /* ID: 564, type: uint, name: SciWinCnt */ + 4, /* ID: 565, type: uint, name: SciWin_pNmbImages */ + 2, /* ID: 566, type: enum, name: SciWin_pCcdRdMode */ + 4, /* ID: 567, type: uint, name: SciWin_pExpTime */ + 4, /* ID: 568, type: uint, name: SciWin_pImageRep */ + 2, /* ID: 569, type: ushort, name: SciWin_pWinPosX */ + 2, /* ID: 570, type: ushort, name: SciWin_pWinPosY */ + 2, /* ID: 571, type: ushort, name: SciWin_pWinSizeX */ + 2, /* ID: 572, type: ushort, name: SciWin_pWinSizeY */ + 2, /* ID: 573, type: enum, name: SciWin_pCentSel */ + 4, /* ID: 574, type: uint, name: sciWinT1 */ + 4, /* ID: 575, type: uint, name: sciWinT2 */ + 2, /* ID: 576, type: enum, name: fbfLoadNode */ + 4, /* ID: 577, type: uint, name: fbfLoadCnt */ + 2, /* ID: 578, type: enum, name: fbfSaveNode */ + 4, /* ID: 579, type: uint, name: fbfSaveCnt */ + 1, /* ID: 580, type: uchar, name: FbfLoad_pFbfId */ + 1, /* ID: 581, type: uchar, name: FbfLoad_pFbfNBlocks */ + 2, /* ID: 582, type: ushort, name: FbfLoad_pFbfRamAreaId */ + 4, /* ID: 583, type: uint, name: FbfLoad_pFbfRamAddr */ + 1, /* ID: 584, type: uchar, name: FbfSave_pFbfId */ + 1, /* ID: 585, type: uchar, name: FbfSave_pFbfNBlocks */ + 2, /* ID: 586, type: ushort, name: FbfSave_pFbfRamAreaId */ + 4, /* ID: 587, type: uint, name: FbfSave_pFbfRamAddr */ + 1, /* ID: 588, type: uchar, name: fbfLoadBlockCounter */ + 1, /* ID: 589, type: uchar, name: fbfSaveBlockCounter */ + 2, /* ID: 590, type: enum, name: transFbfToGrndNode */ + 4, /* ID: 591, type: uint, name: transFbfToGrndCnt */ + 1, /* ID: 592, type: uchar, name: TransFbfToGrnd_pNmbFbf */ + 1, /* ID: 593, type: uchar, name: TransFbfToGrnd_pFbfInit */ + 1, /* ID: 594, type: uchar, name: TransFbfToGrnd_pFbfSize */ + 2, /* ID: 595, type: enum, name: nomSciNode */ + 4, /* ID: 596, type: uint, name: nomSciCnt */ + 1, /* ID: 597, type: bool, name: NomSci_pAcqFlag */ + 1, /* ID: 598, type: bool, name: NomSci_pCal1Flag */ + 1, /* ID: 599, type: bool, name: NomSci_pSciFlag */ + 1, /* ID: 600, type: bool, name: NomSci_pCal2Flag */ + 1, /* ID: 601, type: uchar, name: NomSci_pCibNFull */ + 2, /* ID: 602, type: ushort, name: NomSci_pCibSizeFull */ + 1, /* ID: 603, type: uchar, name: NomSci_pSibNFull */ + 2, /* ID: 604, type: ushort, name: NomSci_pSibSizeFull */ + 1, /* ID: 605, type: uchar, name: NomSci_pGibNFull */ + 2, /* ID: 606, type: ushort, name: NomSci_pGibSizeFull */ + 1, /* ID: 607, type: uchar, name: NomSci_pSibNWin */ + 2, /* ID: 608, type: ushort, name: NomSci_pSibSizeWin */ + 1, /* ID: 609, type: uchar, name: NomSci_pCibNWin */ + 2, /* ID: 610, type: ushort, name: NomSci_pCibSizeWin */ + 1, /* ID: 611, type: uchar, name: NomSci_pGibNWin */ + 2, /* ID: 612, type: ushort, name: NomSci_pGibSizeWin */ + 4, /* ID: 613, type: uint, name: NomSci_pExpTimeAcq */ + 4, /* ID: 614, type: uint, name: NomSci_pImageRepAcq */ + 4, /* ID: 615, type: uint, name: NomSci_pExpTimeCal1 */ + 4, /* ID: 616, type: uint, name: NomSci_pImageRepCal1 */ + 4, /* ID: 617, type: uint, name: NomSci_pNmbImagesCal1 */ + 2, /* ID: 618, type: enum, name: NomSci_pCentSelCal1 */ + 4, /* ID: 619, type: uint, name: NomSci_pNmbImagesSci */ + 2, /* ID: 620, type: enum, name: NomSci_pCcdRdModeSci */ + 4, /* ID: 621, type: uint, name: NomSci_pExpTimeSci */ + 4, /* ID: 622, type: uint, name: NomSci_pImageRepSci */ + 2, /* ID: 623, type: ushort, name: NomSci_pWinPosXSci */ + 2, /* ID: 624, type: ushort, name: NomSci_pWinPosYSci */ + 2, /* ID: 625, type: ushort, name: NomSci_pWinSizeXSci */ + 2, /* ID: 626, type: ushort, name: NomSci_pWinSizeYSci */ + 2, /* ID: 627, type: enum, name: NomSci_pCentSelSci */ + 4, /* ID: 628, type: uint, name: NomSci_pExpTimeCal2 */ + 4, /* ID: 629, type: uint, name: NomSci_pImageRepCal2 */ + 4, /* ID: 630, type: uint, name: NomSci_pNmbImagesCal2 */ + 2, /* ID: 631, type: enum, name: NomSci_pCentSelCal2 */ + 2, /* ID: 632, type: enum, name: NomSci_pSaveTarget */ + 1, /* ID: 633, type: uchar, name: NomSci_pFbfInit */ + 1, /* ID: 634, type: uchar, name: NomSci_pFbfEnd */ + 2, /* ID: 635, type: ushort, name: NomSci_pStckOrderCal1 */ + 2, /* ID: 636, type: ushort, name: NomSci_pStckOrderSci */ + 2, /* ID: 637, type: ushort, name: NomSci_pStckOrderCal2 */ + 2, /* ID: 638, type: enum, name: ConfigSdb_pSdbCmd */ + 1, /* ID: 639, type: uchar, name: ConfigSdb_pCibNFull */ + 2, /* ID: 640, type: ushort, name: ConfigSdb_pCibSizeFull */ + 1, /* ID: 641, type: uchar, name: ConfigSdb_pSibNFull */ + 2, /* ID: 642, type: ushort, name: ConfigSdb_pSibSizeFull */ + 1, /* ID: 643, type: uchar, name: ConfigSdb_pGibNFull */ + 2, /* ID: 644, type: ushort, name: ConfigSdb_pGibSizeFull */ + 1, /* ID: 645, type: uchar, name: ConfigSdb_pSibNWin */ + 2, /* ID: 646, type: ushort, name: ConfigSdb_pSibSizeWin */ + 1, /* ID: 647, type: uchar, name: ConfigSdb_pCibNWin */ + 2, /* ID: 648, type: ushort, name: ConfigSdb_pCibSizeWin */ + 1, /* ID: 649, type: uchar, name: ConfigSdb_pGibNWin */ + 2, /* ID: 650, type: ushort, name: ConfigSdb_pGibSizeWin */ + 4, /* ID: 651, type: float, name: ADC_P3V3 */ + 4, /* ID: 652, type: float, name: ADC_P5V */ + 4, /* ID: 653, type: float, name: ADC_P1V8 */ + 4, /* ID: 654, type: float, name: ADC_P2V5 */ + 4, /* ID: 655, type: float, name: ADC_N5V */ + 4, /* ID: 656, type: float, name: ADC_PGND */ + 4, /* ID: 657, type: float, name: ADC_TEMPOH1A */ + 4, /* ID: 658, type: float, name: ADC_TEMP1 */ + 4, /* ID: 659, type: float, name: ADC_TEMPOH2A */ + 4, /* ID: 660, type: float, name: ADC_TEMPOH1B */ + 4, /* ID: 661, type: float, name: ADC_TEMPOH3A */ + 4, /* ID: 662, type: float, name: ADC_TEMPOH2B */ + 4, /* ID: 663, type: float, name: ADC_TEMPOH4A */ + 4, /* ID: 664, type: float, name: ADC_TEMPOH3B */ + 4, /* ID: 665, type: float, name: ADC_TEMPOH4B */ + 4, /* ID: 666, type: float, name: SEM_P15V */ + 4, /* ID: 667, type: float, name: SEM_P30V */ + 4, /* ID: 668, type: float, name: SEM_P5V0 */ + 4, /* ID: 669, type: float, name: SEM_P7V0 */ + 4, /* ID: 670, type: float, name: SEM_N5V0 */ + 2, /* ID: 671, type: short, name: ADC_P3V3_RAW */ + 2, /* ID: 672, type: short, name: ADC_P5V_RAW */ + 2, /* ID: 673, type: short, name: ADC_P1V8_RAW */ + 2, /* ID: 674, type: short, name: ADC_P2V5_RAW */ + 2, /* ID: 675, type: short, name: ADC_N5V_RAW */ + 2, /* ID: 676, type: short, name: ADC_PGND_RAW */ + 2, /* ID: 677, type: short, name: ADC_TEMPOH1A_RAW */ + 2, /* ID: 678, type: short, name: ADC_TEMP1_RAW */ + 2, /* ID: 679, type: short, name: ADC_TEMPOH2A_RAW */ + 2, /* ID: 680, type: short, name: ADC_TEMPOH1B_RAW */ + 2, /* ID: 681, type: short, name: ADC_TEMPOH3A_RAW */ + 2, /* ID: 682, type: short, name: ADC_TEMPOH2B_RAW */ + 2, /* ID: 683, type: short, name: ADC_TEMPOH4A_RAW */ + 2, /* ID: 684, type: short, name: ADC_TEMPOH3B_RAW */ + 2, /* ID: 685, type: short, name: ADC_TEMPOH4B_RAW */ + 2, /* ID: 686, type: short, name: SEM_P15V_RAW */ + 2, /* ID: 687, type: short, name: SEM_P30V_RAW */ + 2, /* ID: 688, type: short, name: SEM_P5V0_RAW */ + 2, /* ID: 689, type: short, name: SEM_P7V0_RAW */ + 2, /* ID: 690, type: short, name: SEM_N5V0_RAW */ + 4, /* ID: 691, type: float, name: ADC_P3V3_U */ + 4, /* ID: 692, type: float, name: ADC_P5V_U */ + 4, /* ID: 693, type: float, name: ADC_P1V8_U */ + 4, /* ID: 694, type: float, name: ADC_P2V5_U */ + 4, /* ID: 695, type: float, name: ADC_N5V_L */ + 4, /* ID: 696, type: float, name: ADC_PGND_U */ + 4, /* ID: 697, type: float, name: ADC_PGND_L */ + 4, /* ID: 698, type: float, name: ADC_TEMPOH1A_U */ + 4, /* ID: 699, type: float, name: ADC_TEMP1_U */ + 4, /* ID: 700, type: float, name: ADC_TEMPOH2A_U */ + 4, /* ID: 701, type: float, name: ADC_TEMPOH1B_U */ + 4, /* ID: 702, type: float, name: ADC_TEMPOH3A_U */ + 4, /* ID: 703, type: float, name: ADC_TEMPOH2B_U */ + 4, /* ID: 704, type: float, name: ADC_TEMPOH4A_U */ + 4, /* ID: 705, type: float, name: ADC_TEMPOH3B_U */ + 4, /* ID: 706, type: float, name: ADC_TEMPOH4B_U */ + 4, /* ID: 707, type: float, name: SEM_P15V_U */ + 4, /* ID: 708, type: float, name: SEM_P30V_U */ + 4, /* ID: 709, type: float, name: SEM_P5V0_U */ + 4, /* ID: 710, type: float, name: SEM_P7V0_U */ + 4, /* ID: 711, type: float, name: SEM_N5V0_L */ + 2, /* ID: 712, type: ushort, name: HbSemPassword */ + 4, /* ID: 713, type: uint, name: HbSemCounter */ + 1, /* ID: 714, type: bool, name: isWatchdogEnabled */ + 1, /* ID: 715, type: bool, name: isSynchronized */ + 4, /* ID: 716, type: int, name: missedMsgCnt */ + 4, /* ID: 717, type: int, name: missedPulseCnt */ + 4, /* ID: 718, type: uint, name: milFrameDelay */ + 2, /* ID: 719, type: enum, name: EL1_CHIP */ + 2, /* ID: 720, type: enum, name: EL2_CHIP */ + 4, /* ID: 721, type: uint, name: EL1_ADDR */ + 4, /* ID: 722, type: uint, name: EL2_ADDR */ + 1, /* ID: 723, type: bool, name: ERR_LOG_ENB */ + 1, /* ID: 724, type: bool, name: isErrLogValid */ + 2, /* ID: 725, type: ushort, name: nOfErrLogEntries */ + 4, /* ID: 726, type: uint, name: MAX_SEM_PCKT_CYC */ + 4, /* ID: 727, type: uint, name: FBF_BLCK_WR_DUR */ + 4, /* ID: 728, type: uint, name: FBF_BLCK_RD_DUR */ + 1, /* ID: 729, type: bool, name: isFbfOpen */ + 1, /* ID: 730, type: bool, name: isFbfValid */ + 1, /* ID: 731, type: bool, name: FBF_ENB */ + 2, /* ID: 732, type: enum, name: FBF_CHIP */ + 4, /* ID: 733, type: uint, name: FBF_ADDR */ + 2, /* ID: 734, type: ushort, name: fbfNBlocks */ + 4, /* ID: 735, type: float, name: THR_MA_A_1 */ + 4, /* ID: 736, type: float, name: THR_MA_A_2 */ + 4, /* ID: 737, type: float, name: THR_MA_A_3 */ + 4, /* ID: 738, type: float, name: THR_MA_A_4 */ + 4, /* ID: 739, type: float, name: THR_MA_A_5 */ + 4, /* ID: 740, type: float, name: wcet_1 */ + 4, /* ID: 741, type: float, name: wcet_2 */ + 4, /* ID: 742, type: float, name: wcet_3 */ + 4, /* ID: 743, type: float, name: wcet_4 */ + 4, /* ID: 744, type: float, name: wcet_5 */ + 4, /* ID: 745, type: float, name: wcetAver_1 */ + 4, /* ID: 746, type: float, name: wcetAver_2 */ + 4, /* ID: 747, type: float, name: wcetAver_3 */ + 4, /* ID: 748, type: float, name: wcetAver_4 */ + 4, /* ID: 749, type: float, name: wcetAver_5 */ + 4, /* ID: 750, type: float, name: wcetMax_1 */ + 4, /* ID: 751, type: float, name: wcetMax_2 */ + 4, /* ID: 752, type: float, name: wcetMax_3 */ + 4, /* ID: 753, type: float, name: wcetMax_4 */ + 4, /* ID: 754, type: float, name: wcetMax_5 */ + 4, /* ID: 755, type: uint, name: nOfNotif_1 */ + 4, /* ID: 756, type: uint, name: nOfNotif_2 */ + 4, /* ID: 757, type: uint, name: nOfNotif_3 */ + 4, /* ID: 758, type: uint, name: nOfNotif_4 */ + 4, /* ID: 759, type: uint, name: nOfNotif_5 */ + 4, /* ID: 760, type: uint, name: nofFuncExec_1 */ + 4, /* ID: 761, type: uint, name: nofFuncExec_2 */ + 4, /* ID: 762, type: uint, name: nofFuncExec_3 */ + 4, /* ID: 763, type: uint, name: nofFuncExec_4 */ + 4, /* ID: 764, type: uint, name: nofFuncExec_5 */ + 2, /* ID: 765, type: ushort, name: wcetTimeStampFine_1 */ + 2, /* ID: 766, type: ushort, name: wcetTimeStampFine_2 */ + 2, /* ID: 767, type: ushort, name: wcetTimeStampFine_3 */ + 2, /* ID: 768, type: ushort, name: wcetTimeStampFine_4 */ + 2, /* ID: 769, type: ushort, name: wcetTimeStampFine_5 */ + 4, /* ID: 770, type: uint, name: wcetTimeStampCoarse_1 */ + 4, /* ID: 771, type: uint, name: wcetTimeStampCoarse_2 */ + 4, /* ID: 772, type: uint, name: wcetTimeStampCoarse_3 */ + 4, /* ID: 773, type: uint, name: wcetTimeStampCoarse_4 */ + 4, /* ID: 774, type: uint, name: wcetTimeStampCoarse_5 */ + 4, /* ID: 775, type: uint, name: flashContStepCnt */ + 4, /* ID: 776, type: float, name: OTA_TM1A_NOM */ + 4, /* ID: 777, type: float, name: OTA_TM1A_RED */ + 4, /* ID: 778, type: float, name: OTA_TM1B_NOM */ + 4, /* ID: 779, type: float, name: OTA_TM1B_RED */ + 4, /* ID: 780, type: float, name: OTA_TM2A_NOM */ + 4, /* ID: 781, type: float, name: OTA_TM2A_RED */ + 4, /* ID: 782, type: float, name: OTA_TM2B_NOM */ + 4, /* ID: 783, type: float, name: OTA_TM2B_RED */ + 4, /* ID: 784, type: float, name: OTA_TM3A_NOM */ + 4, /* ID: 785, type: float, name: OTA_TM3A_RED */ + 4, /* ID: 786, type: float, name: OTA_TM3B_NOM */ + 4, /* ID: 787, type: float, name: OTA_TM3B_RED */ + 4, /* ID: 788, type: float, name: OTA_TM4A_NOM */ + 4, /* ID: 789, type: float, name: OTA_TM4A_RED */ + 4, /* ID: 790, type: float, name: OTA_TM4B_NOM */ + 4, /* ID: 791, type: float, name: OTA_TM4B_RED */ + 1, /* ID: 792, type: uchar, name: Core0Load */ + 1, /* ID: 793, type: uchar, name: Core1Load */ + 4, /* ID: 794, type: uint, name: InterruptRate */ + 1, /* ID: 795, type: uchar, name: CyclicalActivitiesCtr */ + 4, /* ID: 796, type: uint, name: Uptime */ + 1, /* ID: 797, type: uchar, name: SemTick */ + 4, /* ID: 798, type: uint, name: SemPwrOnTimestamp */ + 4, /* ID: 799, type: uint, name: SemPwrOffTimestamp */ + 2, /* ID: 800, type: ushort, name: IASW_EVT_CTR */ + 4, /* ID: 801, type: uint, name: BAD_COPY_ID */ + 4, /* ID: 802, type: uint, name: BAD_PASTE_ID */ + 4, /* ID: 803, type: uint, name: ObcInputBufferPackets */ + 4, /* ID: 804, type: uint, name: GrndInputBufferPackets */ + 4, /* ID: 805, type: uint, name: MilBusBytesIn */ + 4, /* ID: 806, type: uint, name: MilBusBytesOut */ + 2, /* ID: 807, type: ushort, name: MilBusDroppedBytes */ + 2, /* ID: 808, type: ushort, name: IRL1 */ + 1, /* ID: 809, type: uchar, name: IRL1_AHBSTAT */ + 1, /* ID: 810, type: uchar, name: IRL1_GRGPIO_6 */ + 1, /* ID: 811, type: uchar, name: IRL1_GRTIMER */ + 1, /* ID: 812, type: uchar, name: IRL1_GPTIMER_0 */ + 1, /* ID: 813, type: uchar, name: IRL1_GPTIMER_1 */ + 1, /* ID: 814, type: uchar, name: IRL1_GPTIMER_2 */ + 1, /* ID: 815, type: uchar, name: IRL1_GPTIMER_3 */ + 1, /* ID: 816, type: uchar, name: IRL1_IRQMP */ + 1, /* ID: 817, type: uchar, name: IRL1_B1553BRM */ + 2, /* ID: 818, type: ushort, name: IRL2 */ + 1, /* ID: 819, type: uchar, name: IRL2_GRSPW2_0 */ + 1, /* ID: 820, type: uchar, name: IRL2_GRSPW2_1 */ + 2, /* ID: 821, type: enum, name: SemRoute */ + 4, /* ID: 822, type: uint, name: SpW0BytesIn */ + 4, /* ID: 823, type: uint, name: SpW0BytesOut */ + 4, /* ID: 824, type: uint, name: SpW1BytesIn */ + 4, /* ID: 825, type: uint, name: SpW1BytesOut */ + 1, /* ID: 826, type: uchar, name: Spw0TxDescAvail */ + 1, /* ID: 827, type: uchar, name: Spw0RxPcktAvail */ + 1, /* ID: 828, type: uchar, name: Spw1TxDescAvail */ + 1, /* ID: 829, type: uchar, name: Spw1RxPcktAvail */ + 4, /* ID: 830, type: uint, name: MilCucCoarseTime */ + 2, /* ID: 831, type: ushort, name: MilCucFineTime */ + 4, /* ID: 832, type: uint, name: CucCoarseTime */ + 2, /* ID: 833, type: ushort, name: CucFineTime */ + 4, /* ID: 834, type: uint, name: Sram1ScrCurrAddr */ + 4, /* ID: 835, type: uint, name: Sram2ScrCurrAddr */ + 2, /* ID: 836, type: ushort, name: Sram1ScrLength */ + 2, /* ID: 837, type: ushort, name: Sram2ScrLength */ + 1, /* ID: 838, type: uchar, name: EdacSingleRepaired */ + 2, /* ID: 839, type: ushort, name: EdacSingleFaults */ + 4, /* ID: 840, type: uint, name: EdacLastSingleFail */ + 1, /* ID: 841, type: uchar, name: EdacDoubleFaults */ + 4, /* ID: 842, type: uint, name: EdacDoubleFAddr */ + 2, /* ID: 843, type: enum, name: Cpu2ProcStatus */ + 1, /* ID: 844, type: uchar, name: HEARTBEAT_ENABLED */ + 4, /* ID: 845, type: uint, name: S1AllocDbs */ + 4, /* ID: 846, type: uint, name: S1AllocSw */ + 4, /* ID: 847, type: uint, name: S1AllocHeap */ + 4, /* ID: 848, type: uint, name: S1AllocFlash */ + 4, /* ID: 849, type: uint, name: S1AllocAux */ + 4, /* ID: 850, type: uint, name: S1AllocRes */ + 4, /* ID: 851, type: uint, name: S1AllocSwap */ + 4, /* ID: 852, type: uint, name: S2AllocSciHeap */ + 2, /* ID: 853, type: enum, name: TaAlgoId */ + 2, /* ID: 854, type: ushort, name: TAACQALGOID */ + 4, /* ID: 855, type: uint, name: TASPARE32 */ + 2, /* ID: 856, type: ushort, name: TaTimingPar1 */ + 2, /* ID: 857, type: ushort, name: TaTimingPar2 */ + 2, /* ID: 858, type: ushort, name: TaDistanceThrd */ + 2, /* ID: 859, type: ushort, name: TaIterations */ + 2, /* ID: 860, type: ushort, name: TaRebinningFact */ + 2, /* ID: 861, type: ushort, name: TaDetectionThrd */ + 2, /* ID: 862, type: ushort, name: TaSeReducedExtr */ + 2, /* ID: 863, type: ushort, name: TaSeReducedRadius */ + 2, /* ID: 864, type: ushort, name: TaSeTolerance */ + 2, /* ID: 865, type: ushort, name: TaMvaTolerance */ + 2, /* ID: 866, type: ushort, name: TaAmaTolerance */ + 2, /* ID: 867, type: ushort, name: TAPOINTUNCERT */ + 4, /* ID: 868, type: uint, name: TATARGETSIG */ + 2, /* ID: 869, type: ushort, name: TANROFSTARS */ + 4, /* ID: 870, type: float, name: TaMaxSigFract */ + 4, /* ID: 871, type: float, name: TaBias */ + 4, /* ID: 872, type: float, name: TaDark */ + 4, /* ID: 873, type: float, name: TaSkyBg */ + 1, /* ID: 874, type: uchar, name: COGBITS */ + 4, /* ID: 875, type: float, name: CENT_MULT_X */ + 4, /* ID: 876, type: float, name: CENT_MULT_Y */ + 4, /* ID: 877, type: float, name: CENT_OFFSET_X */ + 4, /* ID: 878, type: float, name: CENT_OFFSET_Y */ + 1, /* ID: 879, type: uchar, name: CENT_MEDIANFILTER */ + 2, /* ID: 880, type: ushort, name: CENT_DIM_X */ + 2, /* ID: 881, type: ushort, name: CENT_DIM_Y */ + 1, /* ID: 882, type: bool, name: CENT_CHECKS */ + 4, /* ID: 883, type: uint, name: CEN_SIGMALIMIT */ + 4, /* ID: 884, type: uint, name: CEN_SIGNALLIMIT */ + 4, /* ID: 885, type: uint, name: CEN_MEDIAN_THRD */ + 4, /* ID: 886, type: float, name: OPT_AXIS_X */ + 4, /* ID: 887, type: float, name: OPT_AXIS_Y */ + 1, /* ID: 888, type: bool, name: DIST_CORR */ + 1, /* ID: 889, type: uchar, name: pStckOrderSci */ + 2, /* ID: 890, type: ushort, name: pWinSizeXSci */ + 2, /* ID: 891, type: ushort, name: pWinSizeYSci */ + 2, /* ID: 892, type: enum, name: SdpImageAptShape */ + 2, /* ID: 893, type: ushort, name: SdpImageAptX */ + 2, /* ID: 894, type: ushort, name: SdpImageAptY */ + 2, /* ID: 895, type: enum, name: SdpImgttAptShape */ + 2, /* ID: 896, type: ushort, name: SdpImgttAptX */ + 2, /* ID: 897, type: ushort, name: SdpImgttAptY */ + 1, /* ID: 898, type: uchar, name: SdpImgttStckOrder */ + 1, /* ID: 899, type: uchar, name: SdpLosStckOrder */ + 1, /* ID: 900, type: uchar, name: SdpLblkStckOrder */ + 1, /* ID: 901, type: uchar, name: SdpLdkStckOrder */ + 1, /* ID: 902, type: uchar, name: SdpRdkStckOrder */ + 1, /* ID: 903, type: uchar, name: SdpRblkStckOrder */ + 1, /* ID: 904, type: uchar, name: SdpTosStckOrder */ + 1, /* ID: 905, type: uchar, name: SdpTdkStckOrder */ + 2, /* ID: 906, type: enum, name: SdpImgttStrat */ + 4, /* ID: 907, type: float, name: Sdp3StatAmpl */ + 2, /* ID: 908, type: enum, name: SdpPhotStrat */ + 1, /* ID: 909, type: uchar, name: SdpPhotRcent */ + 1, /* ID: 910, type: uchar, name: SdpPhotRann1 */ + 1, /* ID: 911, type: uchar, name: SdpPhotRann2 */ + 1, /* ID: 912, type: uchar, name: SdpCrc */ + 2, /* ID: 913, type: ushort, name: CCPRODUCT */ + 2, /* ID: 914, type: ushort, name: CCSTEP */ + 2, /* ID: 915, type: ushort, name: XIB_FAILURES */ + 1, /* ID: 916, type: uchar, name: FEE_SIDE_A */ + 1, /* ID: 917, type: uchar, name: FEE_SIDE_B */ + 4, /* ID: 918, type: uint, name: NLCBORDERS */ + 4, /* ID: 919, type: float, name: NLCCOEFF_A */ + 4, /* ID: 920, type: float, name: NLCCOEFF_B */ + 4, /* ID: 921, type: float, name: NLCCOEFF_C */ + 4, /* ID: 922, type: float, name: NLCCOEFF_D */ + 2, /* ID: 923, type: ushort, name: SdpGlobalBias */ + 2, /* ID: 924, type: enum, name: BiasOrigin */ + 4, /* ID: 925, type: float, name: SdpGlobalGain */ + 4, /* ID: 926, type: uint, name: SdpWinImageCeKey */ + 4, /* ID: 927, type: uint, name: SdpWinImgttCeKey */ + 4, /* ID: 928, type: uint, name: SdpWinHdrCeKey */ + 4, /* ID: 929, type: uint, name: SdpWinMLOSCeKey */ + 4, /* ID: 930, type: uint, name: SdpWinMLBLKCeKey */ + 4, /* ID: 931, type: uint, name: SdpWinMLDKCeKey */ + 4, /* ID: 932, type: uint, name: SdpWinMRDKCeKey */ + 4, /* ID: 933, type: uint, name: SdpWinMRBLKCeKey */ + 4, /* ID: 934, type: uint, name: SdpWinMTOSCeKey */ + 4, /* ID: 935, type: uint, name: SdpWinMTDKCeKey */ + 4, /* ID: 936, type: uint, name: SdpFullImgCeKey */ + 4, /* ID: 937, type: uint, name: SdpFullHdrCeKey */ + 4, /* ID: 938, type: uint, name: CE_Timetag_crs */ + 2, /* ID: 939, type: ushort, name: CE_Timetag_fine */ + 2, /* ID: 940, type: ushort, name: CE_Counter */ + 2, /* ID: 941, type: ushort, name: CE_Version */ + 1, /* ID: 942, type: uchar, name: CE_Integrity */ + 2, /* ID: 943, type: ushort, name: CE_SemWindowPosX */ + 2, /* ID: 944, type: ushort, name: CE_SemWindowPosY */ + 2, /* ID: 945, type: ushort, name: CE_SemWindowSizeX */ + 2, /* ID: 946, type: ushort, name: CE_SemWindowSizeY */ + 4, /* ID: 947, type: uint, name: SPILL_CTR */ + 1, /* ID: 948, type: uchar, name: RZIP_ITER1 */ + 1, /* ID: 949, type: uchar, name: RZIP_ITER2 */ + 1, /* ID: 950, type: uchar, name: RZIP_ITER3 */ + 1, /* ID: 951, type: uchar, name: RZIP_ITER4 */ + 2, /* ID: 952, type: ushort, name: SdpLdkColMask */ + 2, /* ID: 953, type: ushort, name: SdpRdkColMask */ + 2, /* ID: 954, type: ushort, name: FPGA_Version */ + 2, /* ID: 955, type: ushort, name: FPGA_DPU_Status */ + 2, /* ID: 956, type: ushort, name: FPGA_DPU_Address */ + 2, /* ID: 957, type: ushort, name: FPGA_RESET_Status */ + 2, /* ID: 958, type: ushort, name: FPGA_SEM_Status */ + 2, /* ID: 959, type: ushort, name: FPGA_Oper_Heater_Status */ + 2, /* ID: 960, type: ushort, name: GIBTOTRANSFER */ + 2, /* ID: 961, type: ushort, name: TRANSFERMODE */ + 4, /* ID: 962, type: uint, name: S2TOTRANSFERSIZE */ + 4, /* ID: 963, type: uint, name: S4TOTRANSFERSIZE */ + 1, /* ID: 964, type: uchar, name: TransferComplete */ + 4, /* ID: 965, type: uint, name: NLCBORDERS_2 */ + 4, /* ID: 966, type: float, name: NLCCOEFF_A_2 */ + 4, /* ID: 967, type: float, name: NLCCOEFF_B_2 */ + 4, /* ID: 968, type: float, name: NLCCOEFF_C_2 */ + 1, /* ID: 969, type: uchar, name: RF100 */ + 1, /* ID: 970, type: uchar, name: RF230 */ + 4, /* ID: 971, type: float, name: distc1 */ + 4, /* ID: 972, type: float, name: distc2 */ + 4, /* ID: 973, type: float, name: distc3 */ + 4, /* ID: 974, type: uint, name: SPARE_UI_0 */ + 4, /* ID: 975, type: uint, name: SPARE_UI_1 */ + 4, /* ID: 976, type: uint, name: SPARE_UI_2 */ + 4, /* ID: 977, type: uint, name: SPARE_UI_3 */ + 4, /* ID: 978, type: uint, name: SPARE_UI_4 */ + 4, /* ID: 979, type: uint, name: SPARE_UI_5 */ + 4, /* ID: 980, type: uint, name: SPARE_UI_6 */ + 4, /* ID: 981, type: uint, name: SPARE_UI_7 */ + 4, /* ID: 982, type: uint, name: SPARE_UI_8 */ + 4, /* ID: 983, type: uint, name: SPARE_UI_9 */ + 4, /* ID: 984, type: uint, name: SPARE_UI_10 */ + 4, /* ID: 985, type: uint, name: SPARE_UI_11 */ + 4, /* ID: 986, type: uint, name: SPARE_UI_12 */ + 4, /* ID: 987, type: uint, name: SPARE_UI_13 */ + 4, /* ID: 988, type: uint, name: SPARE_UI_14 */ + 4, /* ID: 989, type: uint, name: SPARE_UI_15 */ + 4, /* ID: 990, type: float, name: SPARE_F_0 */ + 4, /* ID: 991, type: float, name: SPARE_F_1 */ + 4, /* ID: 992, type: float, name: SPARE_F_2 */ + 4, /* ID: 993, type: float, name: SPARE_F_3 */ + 4, /* ID: 994, type: float, name: SPARE_F_4 */ + 4, /* ID: 995, type: float, name: SPARE_F_5 */ + 4, /* ID: 996, type: float, name: SPARE_F_6 */ + 4, /* ID: 997, type: float, name: SPARE_F_7 */ + 4, /* ID: 998, type: float, name: SPARE_F_8 */ + 4, /* ID: 999, type: float, name: SPARE_F_9 */ + 4, /* ID: 1000, type: float, name: SPARE_F_10 */ + 4, /* ID: 1001, type: float, name: SPARE_F_11 */ + 4, /* ID: 1002, type: float, name: SPARE_F_12 */ + 4, /* ID: 1003, type: float, name: SPARE_F_13 */ + 4, /* ID: 1004, type: float, name: SPARE_F_14 */ + 4, /* ID: 1005, type: float, name: SPARE_F_15 */ +}; + +/** + * Initialization of the array holding the addresses of data pool items. + */ +static void * dataPoolAddr[1006] = { + 0, /* ID: 0, unused */ + (void *)&dpIasw.buildNumber, /* ID: 1 */ + (void *)&dpCordet.AppErrCode, /* ID: 2 */ + (void *)&dpCordet.NofAllocatedInRep, /* ID: 3 */ + (void *)&dpCordet.MaxNOfInRep, /* ID: 4 */ + (void *)&dpCordet.NofAllocatedInCmd, /* ID: 5 */ + (void *)&dpCordet.MaxNOfInCmd, /* ID: 6 */ + (void *)&dpCordet.Sem_NOfPendingInCmp, /* ID: 7 */ + (void *)&dpCordet.Sem_PCRLSize, /* ID: 8 */ + (void *)&dpCordet.Sem_NOfLoadedInCmp, /* ID: 9 */ + (void *)&dpCordet.GrdObc_NOfPendingInCmp, /* ID: 10 */ + (void *)&dpCordet.GrdObc_PCRLSize, /* ID: 11 */ + (void *)&dpCordet.NOfAllocatedOutCmp, /* ID: 12 */ + (void *)&dpCordet.MaxNOfOutCmp, /* ID: 13 */ + (void *)&dpCordet.NOfInstanceId, /* ID: 14 */ + (void *)&dpCordet.OutMg1_NOfPendingOutCmp, /* ID: 15 */ + (void *)&dpCordet.OutMg1_POCLSize, /* ID: 16 */ + (void *)&dpCordet.OutMg1_NOfLoadedOutCmp, /* ID: 17 */ + (void *)&dpCordet.OutMg2_NOfPendingOutCmp, /* ID: 18 */ + (void *)&dpCordet.OutMg2_POCLSize, /* ID: 19 */ + (void *)&dpCordet.OutMg2_NOfLoadedOutCmp, /* ID: 20 */ + (void *)&dpCordet.OutMg3_NOfPendingOutCmp, /* ID: 21 */ + (void *)&dpCordet.OutMg3_POCLSize, /* ID: 22 */ + (void *)&dpCordet.OutMg3_NOfLoadedOutCmp, /* ID: 23 */ + (void *)&dpCordet.InSem_SeqCnt, /* ID: 24 */ + (void *)&dpCordet.InSem_NOfPendingPckts, /* ID: 25 */ + (void *)&dpCordet.InSem_NOfGroups, /* ID: 26 */ + (void *)&dpCordet.InSem_PcktQueueSize, /* ID: 27 */ + (void *)&dpCordet.InSem_Src, /* ID: 28 */ + (void *)&dpCordet.InObc_NOfPendingPckts, /* ID: 29 */ + (void *)&dpCordet.InObc_NOfGroups, /* ID: 30 */ + (void *)&dpCordet.InObc_PcktQueueSize, /* ID: 31 */ + (void *)&dpCordet.InObc_Src, /* ID: 32 */ + (void *)&dpCordet.InGrd_NOfPendingPckts, /* ID: 33 */ + (void *)&dpCordet.InGrd_NOfGroups, /* ID: 34 */ + (void *)&dpCordet.InGrd_PcktQueueSize, /* ID: 35 */ + (void *)&dpCordet.InGrd_Src, /* ID: 36 */ + (void *)&dpCordet.OutSem_Dest, /* ID: 37 */ + (void *)&dpCordet.OutSem_SeqCnt, /* ID: 38 */ + (void *)&dpCordet.OutSem_NOfPendingPckts, /* ID: 39 */ + (void *)&dpCordet.OutSem_NOfGroups, /* ID: 40 */ + (void *)&dpCordet.OutSem_PcktQueueSize, /* ID: 41 */ + (void *)&dpCordet.OutObc_Dest, /* ID: 42 */ + (void *)&dpCordet.OutObc_SeqCnt_Group0, /* ID: 43 */ + (void *)&dpCordet.OutObc_SeqCnt_Group1, /* ID: 44 */ + (void *)&dpCordet.OutObc_NOfPendingPckts, /* ID: 45 */ + (void *)&dpCordet.OutObc_NOfGroups, /* ID: 46 */ + (void *)&dpCordet.OutObc_PcktQueueSize, /* ID: 47 */ + (void *)&dpCordet.OutGrd_Dest, /* ID: 48 */ + (void *)&dpCordet.OutGrd_SeqCnt_Group0, /* ID: 49 */ + (void *)&dpCordet.OutGrd_SeqCnt_Group1, /* ID: 50 */ + (void *)&dpCordet.OutGrd_SeqCnt_Group2, /* ID: 51 */ + (void *)&dpCordet.OutGrd_NOfPendingPckts, /* ID: 52 */ + (void *)&dpCordet.OutGrd_NOfGroups, /* ID: 53 */ + (void *)&dpCordet.OutGrd_PcktQueueSize, /* ID: 54 */ + (void *)&dpIasw.sibNFull, /* ID: 55 */ + (void *)&dpIasw.cibNFull, /* ID: 56 */ + (void *)&dpIasw.gibNFull, /* ID: 57 */ + (void *)&dpIasw.sibNWin, /* ID: 58 */ + (void *)&dpIasw.cibNWin, /* ID: 59 */ + (void *)&dpIasw.gibNWin, /* ID: 60 */ + (void *)&dpIasw.sibSizeFull, /* ID: 61 */ + (void *)&dpIasw.cibSizeFull, /* ID: 62 */ + (void *)&dpIasw.gibSizeFull, /* ID: 63 */ + (void *)&dpIasw.sibSizeWin, /* ID: 64 */ + (void *)&dpIasw.cibSizeWin, /* ID: 65 */ + (void *)&dpIasw.gibSizeWin, /* ID: 66 */ + (void *)&dpIasw.sibIn, /* ID: 67 */ + (void *)&dpIasw.sibOut, /* ID: 68 */ + (void *)&dpIasw.cibIn, /* ID: 69 */ + (void *)&dpIasw.gibIn, /* ID: 70 */ + (void *)&dpIasw.gibOut, /* ID: 71 */ + (void *)&dpIasw.sdbState, /* ID: 72 */ + (void *)&dpIasw.sdbStateCnt, /* ID: 73 */ + (void *)&dpIasw.OffsetX, /* ID: 74 */ + (void *)&dpIasw.OffsetY, /* ID: 75 */ + (void *)&dpIasw.TargetLocationX, /* ID: 76 */ + (void *)&dpIasw.TargetLocationY, /* ID: 77 */ + (void *)&dpIasw.IntegStartTimeCrs, /* ID: 78 */ + (void *)&dpIasw.IntegStartTimeFine, /* ID: 79 */ + (void *)&dpIasw.IntegEndTimeCrs, /* ID: 80 */ + (void *)&dpIasw.IntegEndTimeFine, /* ID: 81 */ + (void *)&dpIasw.DataCadence, /* ID: 82 */ + (void *)&dpIasw.ValidityStatus, /* ID: 83 */ + (void *)&dpIasw.NOfTcAcc, /* ID: 84 */ + (void *)&dpIasw.NOfAccFailedTc, /* ID: 85 */ + (void *)&dpIasw.SeqCntLastAccTcFromObc, /* ID: 86 */ + (void *)&dpIasw.SeqCntLastAccTcFromGrd, /* ID: 87 */ + (void *)&dpIasw.SeqCntLastAccFailTc, /* ID: 88 */ + (void *)&dpIasw.NOfStartFailedTc, /* ID: 89 */ + (void *)&dpIasw.SeqCntLastStartFailTc, /* ID: 90 */ + (void *)&dpIasw.NOfTcTerm, /* ID: 91 */ + (void *)&dpIasw.NOfTermFailedTc, /* ID: 92 */ + (void *)&dpIasw.SeqCntLastTermFailTc, /* ID: 93 */ + (void *)&dpIasw.RdlSidList, /* ID: 94 */ + (void *)&dpIasw.isRdlFree, /* ID: 95 */ + (void *)&dpIasw.RdlCycCntList, /* ID: 96 */ + (void *)&dpIasw.RdlPeriodList, /* ID: 97 */ + (void *)&dpIasw.RdlEnabledList, /* ID: 98 */ + (void *)&dpIasw.RdlDestList, /* ID: 99 */ + (void *)&dpIasw.RdlDataItemList_0, /* ID: 100 */ + (void *)&dpIasw.RdlDataItemList_1, /* ID: 101 */ + (void *)&dpIasw.RdlDataItemList_2, /* ID: 102 */ + (void *)&dpIasw.RdlDataItemList_3, /* ID: 103 */ + (void *)&dpIasw.RdlDataItemList_4, /* ID: 104 */ + (void *)&dpIasw.RdlDataItemList_5, /* ID: 105 */ + (void *)&dpIasw.RdlDataItemList_6, /* ID: 106 */ + (void *)&dpIasw.RdlDataItemList_7, /* ID: 107 */ + (void *)&dpIasw.RdlDataItemList_8, /* ID: 108 */ + (void *)&dpIasw.RdlDataItemList_9, /* ID: 109 */ + (void *)&dpIasw.DEBUG_VAR, /* ID: 110 */ + (void *)&dpIasw.DEBUG_VAR_ADDR, /* ID: 111 */ + (void *)&dpIasw.EVTFILTERDEF, /* ID: 112 */ + (void *)&dpIasw.evtEnabledList, /* ID: 113 */ + (void *)&dpIasw.lastPatchedAddr, /* ID: 114 */ + (void *)&dpIasw.lastDumpAddr, /* ID: 115 */ + (void *)&dpIasw.sdu2State, /* ID: 116 */ + (void *)&dpIasw.sdu4State, /* ID: 117 */ + (void *)&dpIasw.sdu2StateCnt, /* ID: 118 */ + (void *)&dpIasw.sdu4StateCnt, /* ID: 119 */ + (void *)&dpIasw.sdu2BlockCnt, /* ID: 120 */ + (void *)&dpIasw.sdu4BlockCnt, /* ID: 121 */ + (void *)&dpIasw.sdu2RemSize, /* ID: 122 */ + (void *)&dpIasw.sdu4RemSize, /* ID: 123 */ + (void *)&dpIasw.sdu2DownTransferSize, /* ID: 124 */ + (void *)&dpIasw.sdu4DownTransferSize, /* ID: 125 */ + (void *)&dpIasw.sdsCounter, /* ID: 126 */ + (void *)&dpIasw.FdGlbEnable, /* ID: 127 */ + (void *)&dpIasw.RpGlbEnable, /* ID: 128 */ + (void *)&dpIasw.FdCheckTTMState, /* ID: 129 */ + (void *)&dpIasw.FdCheckTTMIntEn, /* ID: 130 */ + (void *)&dpIasw.FdCheckTTMExtEn, /* ID: 131 */ + (void *)&dpIasw.RpTTMIntEn, /* ID: 132 */ + (void *)&dpIasw.RpTTMExtEn, /* ID: 133 */ + (void *)&dpIasw.FdCheckTTMCnt, /* ID: 134 */ + (void *)&dpIasw.FdCheckTTMSpCnt, /* ID: 135 */ + (void *)&dpIasw.FdCheckTTMCntThr, /* ID: 136 */ + (void *)&dpIasw.TTC_LL, /* ID: 137 */ + (void *)&dpIasw.TTC_UL, /* ID: 138 */ + (void *)&dpIasw.TTM_LIM, /* ID: 139 */ + (void *)&dpIasw.FdCheckSDSCState, /* ID: 140 */ + (void *)&dpIasw.FdCheckSDSCIntEn, /* ID: 141 */ + (void *)&dpIasw.FdCheckSDSCExtEn, /* ID: 142 */ + (void *)&dpIasw.RpSDSCIntEn, /* ID: 143 */ + (void *)&dpIasw.RpSDSCExtEn, /* ID: 144 */ + (void *)&dpIasw.FdCheckSDSCCnt, /* ID: 145 */ + (void *)&dpIasw.FdCheckSDSCSpCnt, /* ID: 146 */ + (void *)&dpIasw.FdCheckSDSCCntThr, /* ID: 147 */ + (void *)&dpIasw.FdCheckComErrState, /* ID: 148 */ + (void *)&dpIasw.FdCheckComErrIntEn, /* ID: 149 */ + (void *)&dpIasw.FdCheckComErrExtEn, /* ID: 150 */ + (void *)&dpIasw.RpComErrIntEn, /* ID: 151 */ + (void *)&dpIasw.RpComErrExtEn, /* ID: 152 */ + (void *)&dpIasw.FdCheckComErrCnt, /* ID: 153 */ + (void *)&dpIasw.FdCheckComErrSpCnt, /* ID: 154 */ + (void *)&dpIasw.FdCheckComErrCntThr, /* ID: 155 */ + (void *)&dpIasw.FdCheckTimeOutState, /* ID: 156 */ + (void *)&dpIasw.FdCheckTimeOutIntEn, /* ID: 157 */ + (void *)&dpIasw.FdCheckTimeOutExtEn, /* ID: 158 */ + (void *)&dpIasw.RpTimeOutIntEn, /* ID: 159 */ + (void *)&dpIasw.RpTimeOutExtEn, /* ID: 160 */ + (void *)&dpIasw.FdCheckTimeOutCnt, /* ID: 161 */ + (void *)&dpIasw.FdCheckTimeOutSpCnt, /* ID: 162 */ + (void *)&dpIasw.FdCheckTimeOutCntThr, /* ID: 163 */ + (void *)&dpIasw.SEM_TO_POWERON, /* ID: 164 */ + (void *)&dpIasw.SEM_TO_SAFE, /* ID: 165 */ + (void *)&dpIasw.SEM_TO_STAB, /* ID: 166 */ + (void *)&dpIasw.SEM_TO_TEMP, /* ID: 167 */ + (void *)&dpIasw.SEM_TO_CCD, /* ID: 168 */ + (void *)&dpIasw.SEM_TO_DIAG, /* ID: 169 */ + (void *)&dpIasw.SEM_TO_STANDBY, /* ID: 170 */ + (void *)&dpIasw.FdCheckSafeModeState, /* ID: 171 */ + (void *)&dpIasw.FdCheckSafeModeIntEn, /* ID: 172 */ + (void *)&dpIasw.FdCheckSafeModeExtEn, /* ID: 173 */ + (void *)&dpIasw.RpSafeModeIntEn, /* ID: 174 */ + (void *)&dpIasw.RpSafeModeExtEn, /* ID: 175 */ + (void *)&dpIasw.FdCheckSafeModeCnt, /* ID: 176 */ + (void *)&dpIasw.FdCheckSafeModeSpCnt, /* ID: 177 */ + (void *)&dpIasw.FdCheckSafeModeCntThr, /* ID: 178 */ + (void *)&dpIasw.FdCheckAliveState, /* ID: 179 */ + (void *)&dpIasw.FdCheckAliveIntEn, /* ID: 180 */ + (void *)&dpIasw.FdCheckAliveExtEn, /* ID: 181 */ + (void *)&dpIasw.RpAliveIntEn, /* ID: 182 */ + (void *)&dpIasw.RpAliveExtEn, /* ID: 183 */ + (void *)&dpIasw.FdCheckAliveCnt, /* ID: 184 */ + (void *)&dpIasw.FdCheckAliveSpCnt, /* ID: 185 */ + (void *)&dpIasw.FdCheckAliveCntThr, /* ID: 186 */ + (void *)&dpIasw.SEM_HK_DEF_PER, /* ID: 187 */ + (void *)&dpIasw.SEMALIVE_DELAYEDSEMHK, /* ID: 188 */ + (void *)&dpIasw.FdCheckSemAnoEvtState, /* ID: 189 */ + (void *)&dpIasw.FdCheckSemAnoEvtIntEn, /* ID: 190 */ + (void *)&dpIasw.FdCheckSemAnoEvtExtEn, /* ID: 191 */ + (void *)&dpIasw.RpSemAnoEvtIntEn, /* ID: 192 */ + (void *)&dpIasw.RpSemAnoEvtExtEn, /* ID: 193 */ + (void *)&dpIasw.FdCheckSemAnoEvtCnt, /* ID: 194 */ + (void *)&dpIasw.FdCheckSemAnoEvtSpCnt, /* ID: 195 */ + (void *)&dpIasw.FdCheckSemAnoEvtCntThr, /* ID: 196 */ + (void *)&dpIasw.semAnoEvtResp_1, /* ID: 197 */ + (void *)&dpIasw.semAnoEvtResp_2, /* ID: 198 */ + (void *)&dpIasw.semAnoEvtResp_3, /* ID: 199 */ + (void *)&dpIasw.semAnoEvtResp_4, /* ID: 200 */ + (void *)&dpIasw.semAnoEvtResp_5, /* ID: 201 */ + (void *)&dpIasw.semAnoEvtResp_6, /* ID: 202 */ + (void *)&dpIasw.semAnoEvtResp_7, /* ID: 203 */ + (void *)&dpIasw.semAnoEvtResp_8, /* ID: 204 */ + (void *)&dpIasw.semAnoEvtResp_9, /* ID: 205 */ + (void *)&dpIasw.semAnoEvtResp_10, /* ID: 206 */ + (void *)&dpIasw.semAnoEvtResp_11, /* ID: 207 */ + (void *)&dpIasw.semAnoEvtResp_12, /* ID: 208 */ + (void *)&dpIasw.semAnoEvtResp_13, /* ID: 209 */ + (void *)&dpIasw.semAnoEvtResp_14, /* ID: 210 */ + (void *)&dpIasw.semAnoEvtResp_15, /* ID: 211 */ + (void *)&dpIasw.semAnoEvtResp_16, /* ID: 212 */ + (void *)&dpIasw.semAnoEvtResp_17, /* ID: 213 */ + (void *)&dpIasw.semAnoEvtResp_18, /* ID: 214 */ + (void *)&dpIasw.semAnoEvtResp_19, /* ID: 215 */ + (void *)&dpIasw.semAnoEvtResp_20, /* ID: 216 */ + (void *)&dpIasw.semAnoEvtResp_21, /* ID: 217 */ + (void *)&dpIasw.semAnoEvtResp_22, /* ID: 218 */ + (void *)&dpIasw.semAnoEvtResp_23, /* ID: 219 */ + (void *)&dpIasw.semAnoEvtResp_24, /* ID: 220 */ + (void *)&dpIasw.semAnoEvtResp_25, /* ID: 221 */ + (void *)&dpIasw.semAnoEvtResp_26, /* ID: 222 */ + (void *)&dpIasw.semAnoEvtResp_27, /* ID: 223 */ + (void *)&dpIasw.semAnoEvtResp_28, /* ID: 224 */ + (void *)&dpIasw.semAnoEvtResp_29, /* ID: 225 */ + (void *)&dpIasw.FdCheckSemLimitState, /* ID: 226 */ + (void *)&dpIasw.FdCheckSemLimitIntEn, /* ID: 227 */ + (void *)&dpIasw.FdCheckSemLimitExtEn, /* ID: 228 */ + (void *)&dpIasw.RpSemLimitIntEn, /* ID: 229 */ + (void *)&dpIasw.RpSemLimitExtEn, /* ID: 230 */ + (void *)&dpIasw.FdCheckSemLimitCnt, /* ID: 231 */ + (void *)&dpIasw.FdCheckSemLimitSpCnt, /* ID: 232 */ + (void *)&dpIasw.FdCheckSemLimitCntThr, /* ID: 233 */ + (void *)&dpIasw.SEM_LIM_DEL_T, /* ID: 234 */ + (void *)&dpIasw.FdCheckDpuHkState, /* ID: 235 */ + (void *)&dpIasw.FdCheckDpuHkIntEn, /* ID: 236 */ + (void *)&dpIasw.FdCheckDpuHkExtEn, /* ID: 237 */ + (void *)&dpIasw.RpDpuHkIntEn, /* ID: 238 */ + (void *)&dpIasw.RpDpuHkExtEn, /* ID: 239 */ + (void *)&dpIasw.FdCheckDpuHkCnt, /* ID: 240 */ + (void *)&dpIasw.FdCheckDpuHkSpCnt, /* ID: 241 */ + (void *)&dpIasw.FdCheckDpuHkCntThr, /* ID: 242 */ + (void *)&dpIasw.FdCheckCentConsState, /* ID: 243 */ + (void *)&dpIasw.FdCheckCentConsIntEn, /* ID: 244 */ + (void *)&dpIasw.FdCheckCentConsExtEn, /* ID: 245 */ + (void *)&dpIasw.RpCentConsIntEn, /* ID: 246 */ + (void *)&dpIasw.RpCentConsExtEn, /* ID: 247 */ + (void *)&dpIasw.FdCheckCentConsCnt, /* ID: 248 */ + (void *)&dpIasw.FdCheckCentConsSpCnt, /* ID: 249 */ + (void *)&dpIasw.FdCheckCentConsCntThr, /* ID: 250 */ + (void *)&dpIasw.FdCheckResState, /* ID: 251 */ + (void *)&dpIasw.FdCheckResIntEn, /* ID: 252 */ + (void *)&dpIasw.FdCheckResExtEn, /* ID: 253 */ + (void *)&dpIasw.RpResIntEn, /* ID: 254 */ + (void *)&dpIasw.RpResExtEn, /* ID: 255 */ + (void *)&dpIasw.FdCheckResCnt, /* ID: 256 */ + (void *)&dpIasw.FdCheckResSpCnt, /* ID: 257 */ + (void *)&dpIasw.FdCheckResCntThr, /* ID: 258 */ + (void *)&dpIasw.CPU1_USAGE_MAX, /* ID: 259 */ + (void *)&dpIasw.MEM_USAGE_MAX, /* ID: 260 */ + (void *)&dpIasw.FdCheckSemCons, /* ID: 261 */ + (void *)&dpIasw.FdCheckSemConsIntEn, /* ID: 262 */ + (void *)&dpIasw.FdCheckSemConsExtEn, /* ID: 263 */ + (void *)&dpIasw.RpSemConsIntEn, /* ID: 264 */ + (void *)&dpIasw.RpSemConsExtEn, /* ID: 265 */ + (void *)&dpIasw.FdCheckSemConsCnt, /* ID: 266 */ + (void *)&dpIasw.FdCheckSemConsSpCnt, /* ID: 267 */ + (void *)&dpIasw.FdCheckSemConsCntThr, /* ID: 268 */ + (void *)&dpIasw.semState, /* ID: 269 */ + (void *)&dpIasw.semOperState, /* ID: 270 */ + (void *)&dpIasw.semStateCnt, /* ID: 271 */ + (void *)&dpIasw.semOperStateCnt, /* ID: 272 */ + (void *)&dpIasw.imageCycleCnt, /* ID: 273 */ + (void *)&dpIasw.acqImageCnt, /* ID: 274 */ + (void *)&dpIasw.sciSubMode, /* ID: 275 */ + (void *)&dpIasw.LastSemPckt, /* ID: 276 */ + (void *)&dpIasw.SEM_ON_CODE, /* ID: 277 */ + (void *)&dpIasw.SEM_OFF_CODE, /* ID: 278 */ + (void *)&dpIasw.SEM_INIT_T1, /* ID: 279 */ + (void *)&dpIasw.SEM_INIT_T2, /* ID: 280 */ + (void *)&dpIasw.SEM_OPER_T1, /* ID: 281 */ + (void *)&dpIasw.SEM_SHUTDOWN_T1, /* ID: 282 */ + (void *)&dpIasw.SEM_SHUTDOWN_T11, /* ID: 283 */ + (void *)&dpIasw.SEM_SHUTDOWN_T12, /* ID: 284 */ + (void *)&dpIasw.SEM_SHUTDOWN_T2, /* ID: 285 */ + (void *)&dpIasw.iaswState, /* ID: 286 */ + (void *)&dpIasw.iaswStateCnt, /* ID: 287 */ + (void *)&dpIasw.iaswCycleCnt, /* ID: 288 */ + (void *)&dpIasw.prepScienceNode, /* ID: 289 */ + (void *)&dpIasw.prepScienceCnt, /* ID: 290 */ + (void *)&dpIasw.controlledSwitchOffNode, /* ID: 291 */ + (void *)&dpIasw.controlledSwitchOffCnt, /* ID: 292 */ + (void *)&dpIasw.CTRLD_SWITCH_OFF_T1, /* ID: 293 */ + (void *)&dpIasw.algoCent0State, /* ID: 294 */ + (void *)&dpIasw.algoCent0Cnt, /* ID: 295 */ + (void *)&dpIasw.algoCent0Enabled, /* ID: 296 */ + (void *)&dpIasw.algoCent1State, /* ID: 297 */ + (void *)&dpIasw.algoCent1Cnt, /* ID: 298 */ + (void *)&dpIasw.algoCent1Enabled, /* ID: 299 */ + (void *)&dpIasw.CENT_EXEC_PHASE, /* ID: 300 */ + (void *)&dpIasw.algoAcq1State, /* ID: 301 */ + (void *)&dpIasw.algoAcq1Cnt, /* ID: 302 */ + (void *)&dpIasw.algoAcq1Enabled, /* ID: 303 */ + (void *)&dpIasw.ACQ_PH, /* ID: 304 */ + (void *)&dpIasw.algoCcState, /* ID: 305 */ + (void *)&dpIasw.algoCcCnt, /* ID: 306 */ + (void *)&dpIasw.algoCcEnabled, /* ID: 307 */ + (void *)&dpIasw.STCK_ORDER, /* ID: 308 */ + (void *)&dpIasw.algoTTC1State, /* ID: 309 */ + (void *)&dpIasw.algoTTC1Cnt, /* ID: 310 */ + (void *)&dpIasw.algoTTC1Enabled, /* ID: 311 */ + (void *)&dpIasw.TTC1_EXEC_PHASE, /* ID: 312 */ + (void *)&dpIasw.TTC1_EXEC_PER, /* ID: 313 */ + (void *)&dpIasw.TTC1_LL_FRT, /* ID: 314 */ + (void *)&dpIasw.TTC1_LL_AFT, /* ID: 315 */ + (void *)&dpIasw.TTC1_UL_FRT, /* ID: 316 */ + (void *)&dpIasw.TTC1_UL_AFT, /* ID: 317 */ + (void *)&dpIasw.ttc1AvTempAft, /* ID: 318 */ + (void *)&dpIasw.ttc1AvTempFrt, /* ID: 319 */ + (void *)&dpIasw.algoTTC2State, /* ID: 320 */ + (void *)&dpIasw.algoTTC2Cnt, /* ID: 321 */ + (void *)&dpIasw.algoTTC2Enabled, /* ID: 322 */ + (void *)&dpIasw.TTC2_EXEC_PER, /* ID: 323 */ + (void *)&dpIasw.TTC2_REF_TEMP, /* ID: 324 */ + (void *)&dpIasw.TTC2_OFFSETA, /* ID: 325 */ + (void *)&dpIasw.TTC2_OFFSETF, /* ID: 326 */ + (void *)&dpIasw.intTimeAft, /* ID: 327 */ + (void *)&dpIasw.onTimeAft, /* ID: 328 */ + (void *)&dpIasw.intTimeFront, /* ID: 329 */ + (void *)&dpIasw.onTimeFront, /* ID: 330 */ + (void *)&dpIasw.TTC2_PA, /* ID: 331 */ + (void *)&dpIasw.TTC2_DA, /* ID: 332 */ + (void *)&dpIasw.TTC2_IA, /* ID: 333 */ + (void *)&dpIasw.TTC2_PF, /* ID: 334 */ + (void *)&dpIasw.TTC2_DF, /* ID: 335 */ + (void *)&dpIasw.TTC2_IF, /* ID: 336 */ + (void *)&dpIasw.algoSaaEvalState, /* ID: 337 */ + (void *)&dpIasw.algoSaaEvalCnt, /* ID: 338 */ + (void *)&dpIasw.algoSaaEvalEnabled, /* ID: 339 */ + (void *)&dpIasw.SAA_EXEC_PHASE, /* ID: 340 */ + (void *)&dpIasw.SAA_EXEC_PER, /* ID: 341 */ + (void *)&dpIasw.isSaaActive, /* ID: 342 */ + (void *)&dpIasw.saaCounter, /* ID: 343 */ + (void *)&dpIasw.pInitSaaCounter, /* ID: 344 */ + (void *)&dpIasw.algoSdsEvalState, /* ID: 345 */ + (void *)&dpIasw.algoSdsEvalCnt, /* ID: 346 */ + (void *)&dpIasw.algoSdsEvalEnabled, /* ID: 347 */ + (void *)&dpIasw.SDS_EXEC_PHASE, /* ID: 348 */ + (void *)&dpIasw.SDS_EXEC_PER, /* ID: 349 */ + (void *)&dpIasw.isSdsActive, /* ID: 350 */ + (void *)&dpIasw.SDS_FORCED, /* ID: 351 */ + (void *)&dpIasw.SDS_INHIBITED, /* ID: 352 */ + (void *)&dpIasw.EARTH_OCCULT_ACTIVE, /* ID: 353 */ + (void *)&dpIasw.HEARTBEAT_D1, /* ID: 354 */ + (void *)&dpIasw.HEARTBEAT_D2, /* ID: 355 */ + (void *)&dpIasw.HbSem, /* ID: 356 */ + (void *)&dpIasw.starMap, /* ID: 357 */ + (void *)&dpIasw.observationId, /* ID: 358 */ + (void *)&dpIasw.centValProcOutput, /* ID: 359 */ + (void *)&dpIasw.CENT_OFFSET_LIM, /* ID: 360 */ + (void *)&dpIasw.CENT_FROZEN_LIM, /* ID: 361 */ + (void *)&dpIasw.SEM_SERV1_1_FORWARD, /* ID: 362 */ + (void *)&dpIasw.SEM_SERV1_2_FORWARD, /* ID: 363 */ + (void *)&dpIasw.SEM_SERV1_7_FORWARD, /* ID: 364 */ + (void *)&dpIasw.SEM_SERV1_8_FORWARD, /* ID: 365 */ + (void *)&dpIasw.SEM_SERV3_1_FORWARD, /* ID: 366 */ + (void *)&dpIasw.SEM_SERV3_2_FORWARD, /* ID: 367 */ + (void *)&dpIasw.SEM_HK_TS_DEF_CRS, /* ID: 368 */ + (void *)&dpIasw.SEM_HK_TS_DEF_FINE, /* ID: 369 */ + (void *)&dpIasw.SEM_HK_TS_EXT_CRS, /* ID: 370 */ + (void *)&dpIasw.SEM_HK_TS_EXT_FINE, /* ID: 371 */ + (void *)&dpIasw.STAT_MODE, /* ID: 372 */ + (void *)&dpIasw.STAT_FLAGS, /* ID: 373 */ + (void *)&dpIasw.STAT_LAST_SPW_ERR, /* ID: 374 */ + (void *)&dpIasw.STAT_LAST_ERR_ID, /* ID: 375 */ + (void *)&dpIasw.STAT_LAST_ERR_FREQ, /* ID: 376 */ + (void *)&dpIasw.STAT_NUM_CMD_RECEIVED, /* ID: 377 */ + (void *)&dpIasw.STAT_NUM_CMD_EXECUTED, /* ID: 378 */ + (void *)&dpIasw.STAT_NUM_DATA_SENT, /* ID: 379 */ + (void *)&dpIasw.STAT_SCU_PROC_DUTY_CL, /* ID: 380 */ + (void *)&dpIasw.STAT_SCU_NUM_AHB_ERR, /* ID: 381 */ + (void *)&dpIasw.STAT_SCU_NUM_AHB_CERR, /* ID: 382 */ + (void *)&dpIasw.STAT_SCU_NUM_LUP_ERR, /* ID: 383 */ + (void *)&dpIasw.TEMP_SEM_SCU, /* ID: 384 */ + (void *)&dpIasw.TEMP_SEM_PCU, /* ID: 385 */ + (void *)&dpIasw.VOLT_SCU_P3_4, /* ID: 386 */ + (void *)&dpIasw.VOLT_SCU_P5, /* ID: 387 */ + (void *)&dpIasw.TEMP_FEE_CCD, /* ID: 388 */ + (void *)&dpIasw.TEMP_FEE_STRAP, /* ID: 389 */ + (void *)&dpIasw.TEMP_FEE_ADC, /* ID: 390 */ + (void *)&dpIasw.TEMP_FEE_BIAS, /* ID: 391 */ + (void *)&dpIasw.TEMP_FEE_DEB, /* ID: 392 */ + (void *)&dpIasw.VOLT_FEE_VOD, /* ID: 393 */ + (void *)&dpIasw.VOLT_FEE_VRD, /* ID: 394 */ + (void *)&dpIasw.VOLT_FEE_VOG, /* ID: 395 */ + (void *)&dpIasw.VOLT_FEE_VSS, /* ID: 396 */ + (void *)&dpIasw.VOLT_FEE_CCD, /* ID: 397 */ + (void *)&dpIasw.VOLT_FEE_CLK, /* ID: 398 */ + (void *)&dpIasw.VOLT_FEE_ANA_P5, /* ID: 399 */ + (void *)&dpIasw.VOLT_FEE_ANA_N5, /* ID: 400 */ + (void *)&dpIasw.VOLT_FEE_ANA_P3_3, /* ID: 401 */ + (void *)&dpIasw.CURR_FEE_CLK_BUF, /* ID: 402 */ + (void *)&dpIasw.VOLT_SCU_FPGA_P1_5, /* ID: 403 */ + (void *)&dpIasw.CURR_SCU_P3_4, /* ID: 404 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_CRE, /* ID: 405 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_ESC, /* ID: 406 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_DISC, /* ID: 407 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_PAR, /* ID: 408 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_WRSY, /* ID: 409 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_INVA, /* ID: 410 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_EOP, /* ID: 411 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_RXAH, /* ID: 412 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_TXAH, /* ID: 413 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_TXBL, /* ID: 414 */ + (void *)&dpIasw.STAT_NUM_SPW_ERR_TXLE, /* ID: 415 */ + (void *)&dpIasw.STAT_NUM_SP_ERR_RX, /* ID: 416 */ + (void *)&dpIasw.STAT_NUM_SP_ERR_TX, /* ID: 417 */ + (void *)&dpIasw.STAT_HEAT_PWM_FPA_CCD, /* ID: 418 */ + (void *)&dpIasw.STAT_HEAT_PWM_FEE_STR, /* ID: 419 */ + (void *)&dpIasw.STAT_HEAT_PWM_FEE_ANA, /* ID: 420 */ + (void *)&dpIasw.STAT_HEAT_PWM_SPARE, /* ID: 421 */ + (void *)&dpIasw.STAT_HEAT_PWM_FLAGS, /* ID: 422 */ + (void *)&dpIasw.STAT_OBTIME_SYNC_DELTA, /* ID: 423 */ + (void *)&dpIasw.TEMP_SEM_SCU_LW, /* ID: 424 */ + (void *)&dpIasw.TEMP_SEM_PCU_LW, /* ID: 425 */ + (void *)&dpIasw.VOLT_SCU_P3_4_LW, /* ID: 426 */ + (void *)&dpIasw.VOLT_SCU_P5_LW, /* ID: 427 */ + (void *)&dpIasw.TEMP_FEE_CCD_LW, /* ID: 428 */ + (void *)&dpIasw.TEMP_FEE_STRAP_LW, /* ID: 429 */ + (void *)&dpIasw.TEMP_FEE_ADC_LW, /* ID: 430 */ + (void *)&dpIasw.TEMP_FEE_BIAS_LW, /* ID: 431 */ + (void *)&dpIasw.TEMP_FEE_DEB_LW, /* ID: 432 */ + (void *)&dpIasw.VOLT_FEE_VOD_LW, /* ID: 433 */ + (void *)&dpIasw.VOLT_FEE_VRD_LW, /* ID: 434 */ + (void *)&dpIasw.VOLT_FEE_VOG_LW, /* ID: 435 */ + (void *)&dpIasw.VOLT_FEE_VSS_LW, /* ID: 436 */ + (void *)&dpIasw.VOLT_FEE_CCD_LW, /* ID: 437 */ + (void *)&dpIasw.VOLT_FEE_CLK_LW, /* ID: 438 */ + (void *)&dpIasw.VOLT_FEE_ANA_P5_LW, /* ID: 439 */ + (void *)&dpIasw.VOLT_FEE_ANA_N5_LW, /* ID: 440 */ + (void *)&dpIasw.VOLT_FEE_ANA_P3_3_LW, /* ID: 441 */ + (void *)&dpIasw.CURR_FEE_CLK_BUF_LW, /* ID: 442 */ + (void *)&dpIasw.VOLT_SCU_FPGA_P1_5_LW, /* ID: 443 */ + (void *)&dpIasw.CURR_SCU_P3_4_LW, /* ID: 444 */ + (void *)&dpIasw.TEMP_SEM_SCU_UW, /* ID: 445 */ + (void *)&dpIasw.TEMP_SEM_PCU_UW, /* ID: 446 */ + (void *)&dpIasw.VOLT_SCU_P3_4_UW, /* ID: 447 */ + (void *)&dpIasw.VOLT_SCU_P5_UW, /* ID: 448 */ + (void *)&dpIasw.TEMP_FEE_CCD_UW, /* ID: 449 */ + (void *)&dpIasw.TEMP_FEE_STRAP_UW, /* ID: 450 */ + (void *)&dpIasw.TEMP_FEE_ADC_UW, /* ID: 451 */ + (void *)&dpIasw.TEMP_FEE_BIAS_UW, /* ID: 452 */ + (void *)&dpIasw.TEMP_FEE_DEB_UW, /* ID: 453 */ + (void *)&dpIasw.VOLT_FEE_VOD_UW, /* ID: 454 */ + (void *)&dpIasw.VOLT_FEE_VRD_UW, /* ID: 455 */ + (void *)&dpIasw.VOLT_FEE_VOG_UW, /* ID: 456 */ + (void *)&dpIasw.VOLT_FEE_VSS_UW, /* ID: 457 */ + (void *)&dpIasw.VOLT_FEE_CCD_UW, /* ID: 458 */ + (void *)&dpIasw.VOLT_FEE_CLK_UW, /* ID: 459 */ + (void *)&dpIasw.VOLT_FEE_ANA_P5_UW, /* ID: 460 */ + (void *)&dpIasw.VOLT_FEE_ANA_N5_UW, /* ID: 461 */ + (void *)&dpIasw.VOLT_FEE_ANA_P3_3_UW, /* ID: 462 */ + (void *)&dpIasw.CURR_FEE_CLK_BUF_UW, /* ID: 463 */ + (void *)&dpIasw.VOLT_SCU_FPGA_P1_5_UW, /* ID: 464 */ + (void *)&dpIasw.CURR_SCU_P3_4_UW, /* ID: 465 */ + (void *)&dpIasw.TEMP_SEM_SCU_LA, /* ID: 466 */ + (void *)&dpIasw.TEMP_SEM_PCU_LA, /* ID: 467 */ + (void *)&dpIasw.VOLT_SCU_P3_4_LA, /* ID: 468 */ + (void *)&dpIasw.VOLT_SCU_P5_LA, /* ID: 469 */ + (void *)&dpIasw.TEMP_FEE_CCD_LA, /* ID: 470 */ + (void *)&dpIasw.TEMP_FEE_STRAP_LA, /* ID: 471 */ + (void *)&dpIasw.TEMP_FEE_ADC_LA, /* ID: 472 */ + (void *)&dpIasw.TEMP_FEE_BIAS_LA, /* ID: 473 */ + (void *)&dpIasw.TEMP_FEE_DEB_LA, /* ID: 474 */ + (void *)&dpIasw.VOLT_FEE_VOD_LA, /* ID: 475 */ + (void *)&dpIasw.VOLT_FEE_VRD_LA, /* ID: 476 */ + (void *)&dpIasw.VOLT_FEE_VOG_LA, /* ID: 477 */ + (void *)&dpIasw.VOLT_FEE_VSS_LA, /* ID: 478 */ + (void *)&dpIasw.VOLT_FEE_CCD_LA, /* ID: 479 */ + (void *)&dpIasw.VOLT_FEE_CLK_LA, /* ID: 480 */ + (void *)&dpIasw.VOLT_FEE_ANA_P5_LA, /* ID: 481 */ + (void *)&dpIasw.VOLT_FEE_ANA_N5_LA, /* ID: 482 */ + (void *)&dpIasw.VOLT_FEE_ANA_P3_3_LA, /* ID: 483 */ + (void *)&dpIasw.CURR_FEE_CLK_BUF_LA, /* ID: 484 */ + (void *)&dpIasw.VOLT_SCU_FPGA_P1_5_LA, /* ID: 485 */ + (void *)&dpIasw.CURR_SCU_P3_4_LA, /* ID: 486 */ + (void *)&dpIasw.TEMP_SEM_SCU_UA, /* ID: 487 */ + (void *)&dpIasw.TEMP_SEM_PCU_UA, /* ID: 488 */ + (void *)&dpIasw.VOLT_SCU_P3_4_UA, /* ID: 489 */ + (void *)&dpIasw.VOLT_SCU_P5_UA, /* ID: 490 */ + (void *)&dpIasw.TEMP_FEE_CCD_UA, /* ID: 491 */ + (void *)&dpIasw.TEMP_FEE_STRAP_UA, /* ID: 492 */ + (void *)&dpIasw.TEMP_FEE_ADC_UA, /* ID: 493 */ + (void *)&dpIasw.TEMP_FEE_BIAS_UA, /* ID: 494 */ + (void *)&dpIasw.TEMP_FEE_DEB_UA, /* ID: 495 */ + (void *)&dpIasw.VOLT_FEE_VOD_UA, /* ID: 496 */ + (void *)&dpIasw.VOLT_FEE_VRD_UA, /* ID: 497 */ + (void *)&dpIasw.VOLT_FEE_VOG_UA, /* ID: 498 */ + (void *)&dpIasw.VOLT_FEE_VSS_UA, /* ID: 499 */ + (void *)&dpIasw.VOLT_FEE_CCD_UA, /* ID: 500 */ + (void *)&dpIasw.VOLT_FEE_CLK_UA, /* ID: 501 */ + (void *)&dpIasw.VOLT_FEE_ANA_P5_UA, /* ID: 502 */ + (void *)&dpIasw.VOLT_FEE_ANA_N5_UA, /* ID: 503 */ + (void *)&dpIasw.VOLT_FEE_ANA_P3_3_UA, /* ID: 504 */ + (void *)&dpIasw.CURR_FEE_CLK_BUF_UA, /* ID: 505 */ + (void *)&dpIasw.VOLT_SCU_FPGA_P1_5_UA, /* ID: 506 */ + (void *)&dpIasw.CURR_SCU_P3_4_UA, /* ID: 507 */ + (void *)&dpIasw.semEvtCounter, /* ID: 508 */ + (void *)&dpIasw.SEM_SERV5_1_FORWARD, /* ID: 509 */ + (void *)&dpIasw.SEM_SERV5_2_FORWARD, /* ID: 510 */ + (void *)&dpIasw.SEM_SERV5_3_FORWARD, /* ID: 511 */ + (void *)&dpIasw.SEM_SERV5_4_FORWARD, /* ID: 512 */ + (void *)&dpIasw.pExpTime, /* ID: 513 */ + (void *)&dpIasw.pImageRep, /* ID: 514 */ + (void *)&dpIasw.pAcqNum, /* ID: 515 */ + (void *)&dpIasw.pDataOs, /* ID: 516 */ + (void *)&dpIasw.pCcdRdMode, /* ID: 517 */ + (void *)&dpIasw.pWinPosX, /* ID: 518 */ + (void *)&dpIasw.pWinPosY, /* ID: 519 */ + (void *)&dpIasw.pWinSizeX, /* ID: 520 */ + (void *)&dpIasw.pWinSizeY, /* ID: 521 */ + (void *)&dpIasw.pDtAcqSrc, /* ID: 522 */ + (void *)&dpIasw.pTempCtrlTarget, /* ID: 523 */ + (void *)&dpIasw.pVoltFeeVod, /* ID: 524 */ + (void *)&dpIasw.pVoltFeeVrd, /* ID: 525 */ + (void *)&dpIasw.pVoltFeeVss, /* ID: 526 */ + (void *)&dpIasw.pHeatTempFpaCCd, /* ID: 527 */ + (void *)&dpIasw.pHeatTempFeeStrap, /* ID: 528 */ + (void *)&dpIasw.pHeatTempFeeAnach, /* ID: 529 */ + (void *)&dpIasw.pHeatTempSpare, /* ID: 530 */ + (void *)&dpIasw.pStepEnDiagCcd, /* ID: 531 */ + (void *)&dpIasw.pStepEnDiagFee, /* ID: 532 */ + (void *)&dpIasw.pStepEnDiagTemp, /* ID: 533 */ + (void *)&dpIasw.pStepEnDiagAna, /* ID: 534 */ + (void *)&dpIasw.pStepEnDiagExpos, /* ID: 535 */ + (void *)&dpIasw.pStepDebDiagCcd, /* ID: 536 */ + (void *)&dpIasw.pStepDebDiagFee, /* ID: 537 */ + (void *)&dpIasw.pStepDebDiagTemp, /* ID: 538 */ + (void *)&dpIasw.pStepDebDiagAna, /* ID: 539 */ + (void *)&dpIasw.pStepDebDiagExpos, /* ID: 540 */ + (void *)&dpIasw.SEM_SERV220_6_FORWARD, /* ID: 541 */ + (void *)&dpIasw.SEM_SERV220_12_FORWARD, /* ID: 542 */ + (void *)&dpIasw.SEM_SERV222_6_FORWARD, /* ID: 543 */ + (void *)&dpIasw.saveImagesNode, /* ID: 544 */ + (void *)&dpIasw.saveImagesCnt, /* ID: 545 */ + (void *)&dpIasw.SaveImages_pSaveTarget, /* ID: 546 */ + (void *)&dpIasw.SaveImages_pFbfInit, /* ID: 547 */ + (void *)&dpIasw.SaveImages_pFbfEnd, /* ID: 548 */ + (void *)&dpIasw.acqFullDropNode, /* ID: 549 */ + (void *)&dpIasw.acqFullDropCnt, /* ID: 550 */ + (void *)&dpIasw.AcqFullDrop_pExpTime, /* ID: 551 */ + (void *)&dpIasw.AcqFullDrop_pImageRep, /* ID: 552 */ + (void *)&dpIasw.acqFullDropT1, /* ID: 553 */ + (void *)&dpIasw.acqFullDropT2, /* ID: 554 */ + (void *)&dpIasw.calFullSnapNode, /* ID: 555 */ + (void *)&dpIasw.calFullSnapCnt, /* ID: 556 */ + (void *)&dpIasw.CalFullSnap_pExpTime, /* ID: 557 */ + (void *)&dpIasw.CalFullSnap_pImageRep, /* ID: 558 */ + (void *)&dpIasw.CalFullSnap_pNmbImages, /* ID: 559 */ + (void *)&dpIasw.CalFullSnap_pCentSel, /* ID: 560 */ + (void *)&dpIasw.calFullSnapT1, /* ID: 561 */ + (void *)&dpIasw.calFullSnapT2, /* ID: 562 */ + (void *)&dpIasw.SciWinNode, /* ID: 563 */ + (void *)&dpIasw.SciWinCnt, /* ID: 564 */ + (void *)&dpIasw.SciWin_pNmbImages, /* ID: 565 */ + (void *)&dpIasw.SciWin_pCcdRdMode, /* ID: 566 */ + (void *)&dpIasw.SciWin_pExpTime, /* ID: 567 */ + (void *)&dpIasw.SciWin_pImageRep, /* ID: 568 */ + (void *)&dpIasw.SciWin_pWinPosX, /* ID: 569 */ + (void *)&dpIasw.SciWin_pWinPosY, /* ID: 570 */ + (void *)&dpIasw.SciWin_pWinSizeX, /* ID: 571 */ + (void *)&dpIasw.SciWin_pWinSizeY, /* ID: 572 */ + (void *)&dpIasw.SciWin_pCentSel, /* ID: 573 */ + (void *)&dpIasw.sciWinT1, /* ID: 574 */ + (void *)&dpIasw.sciWinT2, /* ID: 575 */ + (void *)&dpIasw.fbfLoadNode, /* ID: 576 */ + (void *)&dpIasw.fbfLoadCnt, /* ID: 577 */ + (void *)&dpIasw.fbfSaveNode, /* ID: 578 */ + (void *)&dpIasw.fbfSaveCnt, /* ID: 579 */ + (void *)&dpIasw.FbfLoad_pFbfId, /* ID: 580 */ + (void *)&dpIasw.FbfLoad_pFbfNBlocks, /* ID: 581 */ + (void *)&dpIasw.FbfLoad_pFbfRamAreaId, /* ID: 582 */ + (void *)&dpIasw.FbfLoad_pFbfRamAddr, /* ID: 583 */ + (void *)&dpIasw.FbfSave_pFbfId, /* ID: 584 */ + (void *)&dpIasw.FbfSave_pFbfNBlocks, /* ID: 585 */ + (void *)&dpIasw.FbfSave_pFbfRamAreaId, /* ID: 586 */ + (void *)&dpIasw.FbfSave_pFbfRamAddr, /* ID: 587 */ + (void *)&dpIasw.fbfLoadBlockCounter, /* ID: 588 */ + (void *)&dpIasw.fbfSaveBlockCounter, /* ID: 589 */ + (void *)&dpIasw.transFbfToGrndNode, /* ID: 590 */ + (void *)&dpIasw.transFbfToGrndCnt, /* ID: 591 */ + (void *)&dpIasw.TransFbfToGrnd_pNmbFbf, /* ID: 592 */ + (void *)&dpIasw.TransFbfToGrnd_pFbfInit, /* ID: 593 */ + (void *)&dpIasw.TransFbfToGrnd_pFbfSize, /* ID: 594 */ + (void *)&dpIasw.nomSciNode, /* ID: 595 */ + (void *)&dpIasw.nomSciCnt, /* ID: 596 */ + (void *)&dpIasw.NomSci_pAcqFlag, /* ID: 597 */ + (void *)&dpIasw.NomSci_pCal1Flag, /* ID: 598 */ + (void *)&dpIasw.NomSci_pSciFlag, /* ID: 599 */ + (void *)&dpIasw.NomSci_pCal2Flag, /* ID: 600 */ + (void *)&dpIasw.NomSci_pCibNFull, /* ID: 601 */ + (void *)&dpIasw.NomSci_pCibSizeFull, /* ID: 602 */ + (void *)&dpIasw.NomSci_pSibNFull, /* ID: 603 */ + (void *)&dpIasw.NomSci_pSibSizeFull, /* ID: 604 */ + (void *)&dpIasw.NomSci_pGibNFull, /* ID: 605 */ + (void *)&dpIasw.NomSci_pGibSizeFull, /* ID: 606 */ + (void *)&dpIasw.NomSci_pSibNWin, /* ID: 607 */ + (void *)&dpIasw.NomSci_pSibSizeWin, /* ID: 608 */ + (void *)&dpIasw.NomSci_pCibNWin, /* ID: 609 */ + (void *)&dpIasw.NomSci_pCibSizeWin, /* ID: 610 */ + (void *)&dpIasw.NomSci_pGibNWin, /* ID: 611 */ + (void *)&dpIasw.NomSci_pGibSizeWin, /* ID: 612 */ + (void *)&dpIasw.NomSci_pExpTimeAcq, /* ID: 613 */ + (void *)&dpIasw.NomSci_pImageRepAcq, /* ID: 614 */ + (void *)&dpIasw.NomSci_pExpTimeCal1, /* ID: 615 */ + (void *)&dpIasw.NomSci_pImageRepCal1, /* ID: 616 */ + (void *)&dpIasw.NomSci_pNmbImagesCal1, /* ID: 617 */ + (void *)&dpIasw.NomSci_pCentSelCal1, /* ID: 618 */ + (void *)&dpIasw.NomSci_pNmbImagesSci, /* ID: 619 */ + (void *)&dpIasw.NomSci_pCcdRdModeSci, /* ID: 620 */ + (void *)&dpIasw.NomSci_pExpTimeSci, /* ID: 621 */ + (void *)&dpIasw.NomSci_pImageRepSci, /* ID: 622 */ + (void *)&dpIasw.NomSci_pWinPosXSci, /* ID: 623 */ + (void *)&dpIasw.NomSci_pWinPosYSci, /* ID: 624 */ + (void *)&dpIasw.NomSci_pWinSizeXSci, /* ID: 625 */ + (void *)&dpIasw.NomSci_pWinSizeYSci, /* ID: 626 */ + (void *)&dpIasw.NomSci_pCentSelSci, /* ID: 627 */ + (void *)&dpIasw.NomSci_pExpTimeCal2, /* ID: 628 */ + (void *)&dpIasw.NomSci_pImageRepCal2, /* ID: 629 */ + (void *)&dpIasw.NomSci_pNmbImagesCal2, /* ID: 630 */ + (void *)&dpIasw.NomSci_pCentSelCal2, /* ID: 631 */ + (void *)&dpIasw.NomSci_pSaveTarget, /* ID: 632 */ + (void *)&dpIasw.NomSci_pFbfInit, /* ID: 633 */ + (void *)&dpIasw.NomSci_pFbfEnd, /* ID: 634 */ + (void *)&dpIasw.NomSci_pStckOrderCal1, /* ID: 635 */ + (void *)&dpIasw.NomSci_pStckOrderSci, /* ID: 636 */ + (void *)&dpIasw.NomSci_pStckOrderCal2, /* ID: 637 */ + (void *)&dpIasw.ConfigSdb_pSdbCmd, /* ID: 638 */ + (void *)&dpIasw.ConfigSdb_pCibNFull, /* ID: 639 */ + (void *)&dpIasw.ConfigSdb_pCibSizeFull, /* ID: 640 */ + (void *)&dpIasw.ConfigSdb_pSibNFull, /* ID: 641 */ + (void *)&dpIasw.ConfigSdb_pSibSizeFull, /* ID: 642 */ + (void *)&dpIasw.ConfigSdb_pGibNFull, /* ID: 643 */ + (void *)&dpIasw.ConfigSdb_pGibSizeFull, /* ID: 644 */ + (void *)&dpIasw.ConfigSdb_pSibNWin, /* ID: 645 */ + (void *)&dpIasw.ConfigSdb_pSibSizeWin, /* ID: 646 */ + (void *)&dpIasw.ConfigSdb_pCibNWin, /* ID: 647 */ + (void *)&dpIasw.ConfigSdb_pCibSizeWin, /* ID: 648 */ + (void *)&dpIasw.ConfigSdb_pGibNWin, /* ID: 649 */ + (void *)&dpIasw.ConfigSdb_pGibSizeWin, /* ID: 650 */ + (void *)&dpIasw.ADC_P3V3, /* ID: 651 */ + (void *)&dpIasw.ADC_P5V, /* ID: 652 */ + (void *)&dpIasw.ADC_P1V8, /* ID: 653 */ + (void *)&dpIasw.ADC_P2V5, /* ID: 654 */ + (void *)&dpIasw.ADC_N5V, /* ID: 655 */ + (void *)&dpIasw.ADC_PGND, /* ID: 656 */ + (void *)&dpIasw.ADC_TEMPOH1A, /* ID: 657 */ + (void *)&dpIasw.ADC_TEMP1, /* ID: 658 */ + (void *)&dpIasw.ADC_TEMPOH2A, /* ID: 659 */ + (void *)&dpIasw.ADC_TEMPOH1B, /* ID: 660 */ + (void *)&dpIasw.ADC_TEMPOH3A, /* ID: 661 */ + (void *)&dpIasw.ADC_TEMPOH2B, /* ID: 662 */ + (void *)&dpIasw.ADC_TEMPOH4A, /* ID: 663 */ + (void *)&dpIasw.ADC_TEMPOH3B, /* ID: 664 */ + (void *)&dpIasw.ADC_TEMPOH4B, /* ID: 665 */ + (void *)&dpIasw.SEM_P15V, /* ID: 666 */ + (void *)&dpIasw.SEM_P30V, /* ID: 667 */ + (void *)&dpIasw.SEM_P5V0, /* ID: 668 */ + (void *)&dpIasw.SEM_P7V0, /* ID: 669 */ + (void *)&dpIasw.SEM_N5V0, /* ID: 670 */ + (void *)&dpIasw.ADC_P3V3_RAW, /* ID: 671 */ + (void *)&dpIasw.ADC_P5V_RAW, /* ID: 672 */ + (void *)&dpIasw.ADC_P1V8_RAW, /* ID: 673 */ + (void *)&dpIasw.ADC_P2V5_RAW, /* ID: 674 */ + (void *)&dpIasw.ADC_N5V_RAW, /* ID: 675 */ + (void *)&dpIasw.ADC_PGND_RAW, /* ID: 676 */ + (void *)&dpIasw.ADC_TEMPOH1A_RAW, /* ID: 677 */ + (void *)&dpIasw.ADC_TEMP1_RAW, /* ID: 678 */ + (void *)&dpIasw.ADC_TEMPOH2A_RAW, /* ID: 679 */ + (void *)&dpIasw.ADC_TEMPOH1B_RAW, /* ID: 680 */ + (void *)&dpIasw.ADC_TEMPOH3A_RAW, /* ID: 681 */ + (void *)&dpIasw.ADC_TEMPOH2B_RAW, /* ID: 682 */ + (void *)&dpIasw.ADC_TEMPOH4A_RAW, /* ID: 683 */ + (void *)&dpIasw.ADC_TEMPOH3B_RAW, /* ID: 684 */ + (void *)&dpIasw.ADC_TEMPOH4B_RAW, /* ID: 685 */ + (void *)&dpIasw.SEM_P15V_RAW, /* ID: 686 */ + (void *)&dpIasw.SEM_P30V_RAW, /* ID: 687 */ + (void *)&dpIasw.SEM_P5V0_RAW, /* ID: 688 */ + (void *)&dpIasw.SEM_P7V0_RAW, /* ID: 689 */ + (void *)&dpIasw.SEM_N5V0_RAW, /* ID: 690 */ + (void *)&dpIasw.ADC_P3V3_U, /* ID: 691 */ + (void *)&dpIasw.ADC_P5V_U, /* ID: 692 */ + (void *)&dpIasw.ADC_P1V8_U, /* ID: 693 */ + (void *)&dpIasw.ADC_P2V5_U, /* ID: 694 */ + (void *)&dpIasw.ADC_N5V_L, /* ID: 695 */ + (void *)&dpIasw.ADC_PGND_U, /* ID: 696 */ + (void *)&dpIasw.ADC_PGND_L, /* ID: 697 */ + (void *)&dpIasw.ADC_TEMPOH1A_U, /* ID: 698 */ + (void *)&dpIasw.ADC_TEMP1_U, /* ID: 699 */ + (void *)&dpIasw.ADC_TEMPOH2A_U, /* ID: 700 */ + (void *)&dpIasw.ADC_TEMPOH1B_U, /* ID: 701 */ + (void *)&dpIasw.ADC_TEMPOH3A_U, /* ID: 702 */ + (void *)&dpIasw.ADC_TEMPOH2B_U, /* ID: 703 */ + (void *)&dpIasw.ADC_TEMPOH4A_U, /* ID: 704 */ + (void *)&dpIasw.ADC_TEMPOH3B_U, /* ID: 705 */ + (void *)&dpIasw.ADC_TEMPOH4B_U, /* ID: 706 */ + (void *)&dpIasw.SEM_P15V_U, /* ID: 707 */ + (void *)&dpIasw.SEM_P30V_U, /* ID: 708 */ + (void *)&dpIasw.SEM_P5V0_U, /* ID: 709 */ + (void *)&dpIasw.SEM_P7V0_U, /* ID: 710 */ + (void *)&dpIasw.SEM_N5V0_L, /* ID: 711 */ + (void *)&dpIasw.HbSemPassword, /* ID: 712 */ + (void *)&dpIasw.HbSemCounter, /* ID: 713 */ + (void *)&dpIbsw.isWatchdogEnabled, /* ID: 714 */ + (void *)&dpIbsw.isSynchronized, /* ID: 715 */ + (void *)&dpIbsw.missedMsgCnt, /* ID: 716 */ + (void *)&dpIbsw.missedPulseCnt, /* ID: 717 */ + (void *)&dpIbsw.milFrameDelay, /* ID: 718 */ + (void *)&dpIbsw.EL1_CHIP, /* ID: 719 */ + (void *)&dpIbsw.EL2_CHIP, /* ID: 720 */ + (void *)&dpIbsw.EL1_ADDR, /* ID: 721 */ + (void *)&dpIbsw.EL2_ADDR, /* ID: 722 */ + (void *)&dpIbsw.ERR_LOG_ENB, /* ID: 723 */ + (void *)&dpIbsw.isErrLogValid, /* ID: 724 */ + (void *)&dpIbsw.nOfErrLogEntries, /* ID: 725 */ + (void *)&dpIasw.MAX_SEM_PCKT_CYC, /* ID: 726 */ + (void *)&dpIbsw.FBF_BLCK_WR_DUR, /* ID: 727 */ + (void *)&dpIbsw.FBF_BLCK_RD_DUR, /* ID: 728 */ + (void *)&dpIbsw.isFbfOpen, /* ID: 729 */ + (void *)&dpIbsw.isFbfValid, /* ID: 730 */ + (void *)&dpIbsw.FBF_ENB, /* ID: 731 */ + (void *)&dpIbsw.FBF_CHIP, /* ID: 732 */ + (void *)&dpIbsw.FBF_ADDR, /* ID: 733 */ + (void *)&dpIbsw.fbfNBlocks, /* ID: 734 */ + (void *)&dpIbsw.THR_MA_A_1, /* ID: 735 */ + (void *)&dpIbsw.THR_MA_A_2, /* ID: 736 */ + (void *)&dpIbsw.THR_MA_A_3, /* ID: 737 */ + (void *)&dpIbsw.THR_MA_A_4, /* ID: 738 */ + (void *)&dpIbsw.THR_MA_A_5, /* ID: 739 */ + (void *)&dpIbsw.wcet_1, /* ID: 740 */ + (void *)&dpIbsw.wcet_2, /* ID: 741 */ + (void *)&dpIbsw.wcet_3, /* ID: 742 */ + (void *)&dpIbsw.wcet_4, /* ID: 743 */ + (void *)&dpIbsw.wcet_5, /* ID: 744 */ + (void *)&dpIbsw.wcetAver_1, /* ID: 745 */ + (void *)&dpIbsw.wcetAver_2, /* ID: 746 */ + (void *)&dpIbsw.wcetAver_3, /* ID: 747 */ + (void *)&dpIbsw.wcetAver_4, /* ID: 748 */ + (void *)&dpIbsw.wcetAver_5, /* ID: 749 */ + (void *)&dpIbsw.wcetMax_1, /* ID: 750 */ + (void *)&dpIbsw.wcetMax_2, /* ID: 751 */ + (void *)&dpIbsw.wcetMax_3, /* ID: 752 */ + (void *)&dpIbsw.wcetMax_4, /* ID: 753 */ + (void *)&dpIbsw.wcetMax_5, /* ID: 754 */ + (void *)&dpIbsw.nOfNotif_1, /* ID: 755 */ + (void *)&dpIbsw.nOfNotif_2, /* ID: 756 */ + (void *)&dpIbsw.nOfNotif_3, /* ID: 757 */ + (void *)&dpIbsw.nOfNotif_4, /* ID: 758 */ + (void *)&dpIbsw.nOfNotif_5, /* ID: 759 */ + (void *)&dpIbsw.nofFuncExec_1, /* ID: 760 */ + (void *)&dpIbsw.nofFuncExec_2, /* ID: 761 */ + (void *)&dpIbsw.nofFuncExec_3, /* ID: 762 */ + (void *)&dpIbsw.nofFuncExec_4, /* ID: 763 */ + (void *)&dpIbsw.nofFuncExec_5, /* ID: 764 */ + (void *)&dpIbsw.wcetTimeStampFine_1, /* ID: 765 */ + (void *)&dpIbsw.wcetTimeStampFine_2, /* ID: 766 */ + (void *)&dpIbsw.wcetTimeStampFine_3, /* ID: 767 */ + (void *)&dpIbsw.wcetTimeStampFine_4, /* ID: 768 */ + (void *)&dpIbsw.wcetTimeStampFine_5, /* ID: 769 */ + (void *)&dpIbsw.wcetTimeStampCoarse_1, /* ID: 770 */ + (void *)&dpIbsw.wcetTimeStampCoarse_2, /* ID: 771 */ + (void *)&dpIbsw.wcetTimeStampCoarse_3, /* ID: 772 */ + (void *)&dpIbsw.wcetTimeStampCoarse_4, /* ID: 773 */ + (void *)&dpIbsw.wcetTimeStampCoarse_5, /* ID: 774 */ + (void *)&dpIbsw.flashContStepCnt, /* ID: 775 */ + (void *)&dpIbsw.OTA_TM1A_NOM, /* ID: 776 */ + (void *)&dpIbsw.OTA_TM1A_RED, /* ID: 777 */ + (void *)&dpIbsw.OTA_TM1B_NOM, /* ID: 778 */ + (void *)&dpIbsw.OTA_TM1B_RED, /* ID: 779 */ + (void *)&dpIbsw.OTA_TM2A_NOM, /* ID: 780 */ + (void *)&dpIbsw.OTA_TM2A_RED, /* ID: 781 */ + (void *)&dpIbsw.OTA_TM2B_NOM, /* ID: 782 */ + (void *)&dpIbsw.OTA_TM2B_RED, /* ID: 783 */ + (void *)&dpIbsw.OTA_TM3A_NOM, /* ID: 784 */ + (void *)&dpIbsw.OTA_TM3A_RED, /* ID: 785 */ + (void *)&dpIbsw.OTA_TM3B_NOM, /* ID: 786 */ + (void *)&dpIbsw.OTA_TM3B_RED, /* ID: 787 */ + (void *)&dpIbsw.OTA_TM4A_NOM, /* ID: 788 */ + (void *)&dpIbsw.OTA_TM4A_RED, /* ID: 789 */ + (void *)&dpIbsw.OTA_TM4B_NOM, /* ID: 790 */ + (void *)&dpIbsw.OTA_TM4B_RED, /* ID: 791 */ + (void *)&dpIbsw.Core0Load, /* ID: 792 */ + (void *)&dpIbsw.Core1Load, /* ID: 793 */ + (void *)&dpIbsw.InterruptRate, /* ID: 794 */ + (void *)&dpIbsw.CyclicalActivitiesCtr, /* ID: 795 */ + (void *)&dpIbsw.Uptime, /* ID: 796 */ + (void *)&dpIbsw.SemTick, /* ID: 797 */ + (void *)&dpIasw.SemPwrOnTimestamp, /* ID: 798 */ + (void *)&dpIasw.SemPwrOffTimestamp, /* ID: 799 */ + (void *)&dpIasw.IASW_EVT_CTR, /* ID: 800 */ + (void *)&dpIbsw.BAD_COPY_ID, /* ID: 801 */ + (void *)&dpIbsw.BAD_PASTE_ID, /* ID: 802 */ + (void *)&dpIbsw.ObcInputBufferPackets, /* ID: 803 */ + (void *)&dpIbsw.GrndInputBufferPackets, /* ID: 804 */ + (void *)&dpIbsw.MilBusBytesIn, /* ID: 805 */ + (void *)&dpIbsw.MilBusBytesOut, /* ID: 806 */ + (void *)&dpIbsw.MilBusDroppedBytes, /* ID: 807 */ + (void *)&dpIbsw.IRL1, /* ID: 808 */ + (void *)&dpIbsw.IRL1_AHBSTAT, /* ID: 809 */ + (void *)&dpIbsw.IRL1_GRGPIO_6, /* ID: 810 */ + (void *)&dpIbsw.IRL1_GRTIMER, /* ID: 811 */ + (void *)&dpIbsw.IRL1_GPTIMER_0, /* ID: 812 */ + (void *)&dpIbsw.IRL1_GPTIMER_1, /* ID: 813 */ + (void *)&dpIbsw.IRL1_GPTIMER_2, /* ID: 814 */ + (void *)&dpIbsw.IRL1_GPTIMER_3, /* ID: 815 */ + (void *)&dpIbsw.IRL1_IRQMP, /* ID: 816 */ + (void *)&dpIbsw.IRL1_B1553BRM, /* ID: 817 */ + (void *)&dpIbsw.IRL2, /* ID: 818 */ + (void *)&dpIbsw.IRL2_GRSPW2_0, /* ID: 819 */ + (void *)&dpIbsw.IRL2_GRSPW2_1, /* ID: 820 */ + (void *)&dpIbsw.SemRoute, /* ID: 821 */ + (void *)&dpIbsw.SpW0BytesIn, /* ID: 822 */ + (void *)&dpIbsw.SpW0BytesOut, /* ID: 823 */ + (void *)&dpIbsw.SpW1BytesIn, /* ID: 824 */ + (void *)&dpIbsw.SpW1BytesOut, /* ID: 825 */ + (void *)&dpIbsw.Spw0TxDescAvail, /* ID: 826 */ + (void *)&dpIbsw.Spw0RxPcktAvail, /* ID: 827 */ + (void *)&dpIbsw.Spw1TxDescAvail, /* ID: 828 */ + (void *)&dpIbsw.Spw1RxPcktAvail, /* ID: 829 */ + (void *)&dpIbsw.MilCucCoarseTime, /* ID: 830 */ + (void *)&dpIbsw.MilCucFineTime, /* ID: 831 */ + (void *)&dpIbsw.CucCoarseTime, /* ID: 832 */ + (void *)&dpIbsw.CucFineTime, /* ID: 833 */ + (void *)&dpIasw.Sram1ScrCurrAddr, /* ID: 834 */ + (void *)&dpIasw.Sram2ScrCurrAddr, /* ID: 835 */ + (void *)&dpIasw.Sram1ScrLength, /* ID: 836 */ + (void *)&dpIasw.Sram2ScrLength, /* ID: 837 */ + (void *)&dpIasw.EdacSingleRepaired, /* ID: 838 */ + (void *)&dpIasw.EdacSingleFaults, /* ID: 839 */ + (void *)&dpIasw.EdacLastSingleFail, /* ID: 840 */ + (void *)&dpIbsw.EdacDoubleFaults, /* ID: 841 */ + (void *)&dpIbsw.EdacDoubleFAddr, /* ID: 842 */ + (void *)&dpIasw.Cpu2ProcStatus, /* ID: 843 */ + (void *)&dpIbsw.HEARTBEAT_ENABLED, /* ID: 844 */ + (void *)&dpIbsw.S1AllocDbs, /* ID: 845 */ + (void *)&dpIbsw.S1AllocSw, /* ID: 846 */ + (void *)&dpIbsw.S1AllocHeap, /* ID: 847 */ + (void *)&dpIbsw.S1AllocFlash, /* ID: 848 */ + (void *)&dpIbsw.S1AllocAux, /* ID: 849 */ + (void *)&dpIbsw.S1AllocRes, /* ID: 850 */ + (void *)&dpIbsw.S1AllocSwap, /* ID: 851 */ + (void *)&dpIbsw.S2AllocSciHeap, /* ID: 852 */ + (void *)&dpIasw.TaAlgoId, /* ID: 853 */ + (void *)&dpIasw.TAACQALGOID, /* ID: 854 */ + (void *)&dpIasw.TASPARE32, /* ID: 855 */ + (void *)&dpIasw.TaTimingPar1, /* ID: 856 */ + (void *)&dpIasw.TaTimingPar2, /* ID: 857 */ + (void *)&dpIasw.TaDistanceThrd, /* ID: 858 */ + (void *)&dpIasw.TaIterations, /* ID: 859 */ + (void *)&dpIasw.TaRebinningFact, /* ID: 860 */ + (void *)&dpIasw.TaDetectionThrd, /* ID: 861 */ + (void *)&dpIasw.TaSeReducedExtr, /* ID: 862 */ + (void *)&dpIasw.TaSeReducedRadius, /* ID: 863 */ + (void *)&dpIasw.TaSeTolerance, /* ID: 864 */ + (void *)&dpIasw.TaMvaTolerance, /* ID: 865 */ + (void *)&dpIasw.TaAmaTolerance, /* ID: 866 */ + (void *)&dpIasw.TAPOINTUNCERT, /* ID: 867 */ + (void *)&dpIasw.TATARGETSIG, /* ID: 868 */ + (void *)&dpIasw.TANROFSTARS, /* ID: 869 */ + (void *)&dpIasw.TaMaxSigFract, /* ID: 870 */ + (void *)&dpIasw.TaBias, /* ID: 871 */ + (void *)&dpIasw.TaDark, /* ID: 872 */ + (void *)&dpIasw.TaSkyBg, /* ID: 873 */ + (void *)&dpIasw.COGBITS, /* ID: 874 */ + (void *)&dpIasw.CENT_MULT_X, /* ID: 875 */ + (void *)&dpIasw.CENT_MULT_Y, /* ID: 876 */ + (void *)&dpIasw.CENT_OFFSET_X, /* ID: 877 */ + (void *)&dpIasw.CENT_OFFSET_Y, /* ID: 878 */ + (void *)&dpIasw.CENT_MEDIANFILTER, /* ID: 879 */ + (void *)&dpIasw.CENT_DIM_X, /* ID: 880 */ + (void *)&dpIasw.CENT_DIM_Y, /* ID: 881 */ + (void *)&dpIasw.CENT_CHECKS, /* ID: 882 */ + (void *)&dpIasw.CEN_SIGMALIMIT, /* ID: 883 */ + (void *)&dpIasw.CEN_SIGNALLIMIT, /* ID: 884 */ + (void *)&dpIasw.CEN_MEDIAN_THRD, /* ID: 885 */ + (void *)&dpIasw.OPT_AXIS_X, /* ID: 886 */ + (void *)&dpIasw.OPT_AXIS_Y, /* ID: 887 */ + (void *)&dpIasw.DIST_CORR, /* ID: 888 */ + (void *)&dpIasw.pStckOrderSci, /* ID: 889 */ + (void *)&dpIasw.pWinSizeXSci, /* ID: 890 */ + (void *)&dpIasw.pWinSizeYSci, /* ID: 891 */ + (void *)&dpIasw.SdpImageAptShape, /* ID: 892 */ + (void *)&dpIasw.SdpImageAptX, /* ID: 893 */ + (void *)&dpIasw.SdpImageAptY, /* ID: 894 */ + (void *)&dpIasw.SdpImgttAptShape, /* ID: 895 */ + (void *)&dpIasw.SdpImgttAptX, /* ID: 896 */ + (void *)&dpIasw.SdpImgttAptY, /* ID: 897 */ + (void *)&dpIasw.SdpImgttStckOrder, /* ID: 898 */ + (void *)&dpIasw.SdpLosStckOrder, /* ID: 899 */ + (void *)&dpIasw.SdpLblkStckOrder, /* ID: 900 */ + (void *)&dpIasw.SdpLdkStckOrder, /* ID: 901 */ + (void *)&dpIasw.SdpRdkStckOrder, /* ID: 902 */ + (void *)&dpIasw.SdpRblkStckOrder, /* ID: 903 */ + (void *)&dpIasw.SdpTosStckOrder, /* ID: 904 */ + (void *)&dpIasw.SdpTdkStckOrder, /* ID: 905 */ + (void *)&dpIasw.SdpImgttStrat, /* ID: 906 */ + (void *)&dpIasw.Sdp3StatAmpl, /* ID: 907 */ + (void *)&dpIasw.SdpPhotStrat, /* ID: 908 */ + (void *)&dpIasw.SdpPhotRcent, /* ID: 909 */ + (void *)&dpIasw.SdpPhotRann1, /* ID: 910 */ + (void *)&dpIasw.SdpPhotRann2, /* ID: 911 */ + (void *)&dpIasw.SdpCrc, /* ID: 912 */ + (void *)&dpIasw.CCPRODUCT, /* ID: 913 */ + (void *)&dpIasw.CCSTEP, /* ID: 914 */ + (void *)&dpIasw.XIB_FAILURES, /* ID: 915 */ + (void *)&dpIasw.FEE_SIDE_A, /* ID: 916 */ + (void *)&dpIasw.FEE_SIDE_B, /* ID: 917 */ + (void *)&dpIasw.NLCBORDERS, /* ID: 918 */ + (void *)&dpIasw.NLCCOEFF_A, /* ID: 919 */ + (void *)&dpIasw.NLCCOEFF_B, /* ID: 920 */ + (void *)&dpIasw.NLCCOEFF_C, /* ID: 921 */ + (void *)&dpIasw.NLCCOEFF_D, /* ID: 922 */ + (void *)&dpIasw.SdpGlobalBias, /* ID: 923 */ + (void *)&dpIasw.BiasOrigin, /* ID: 924 */ + (void *)&dpIasw.SdpGlobalGain, /* ID: 925 */ + (void *)&dpIasw.SdpWinImageCeKey, /* ID: 926 */ + (void *)&dpIasw.SdpWinImgttCeKey, /* ID: 927 */ + (void *)&dpIasw.SdpWinHdrCeKey, /* ID: 928 */ + (void *)&dpIasw.SdpWinMLOSCeKey, /* ID: 929 */ + (void *)&dpIasw.SdpWinMLBLKCeKey, /* ID: 930 */ + (void *)&dpIasw.SdpWinMLDKCeKey, /* ID: 931 */ + (void *)&dpIasw.SdpWinMRDKCeKey, /* ID: 932 */ + (void *)&dpIasw.SdpWinMRBLKCeKey, /* ID: 933 */ + (void *)&dpIasw.SdpWinMTOSCeKey, /* ID: 934 */ + (void *)&dpIasw.SdpWinMTDKCeKey, /* ID: 935 */ + (void *)&dpIasw.SdpFullImgCeKey, /* ID: 936 */ + (void *)&dpIasw.SdpFullHdrCeKey, /* ID: 937 */ + (void *)&dpIasw.CE_Timetag_crs, /* ID: 938 */ + (void *)&dpIasw.CE_Timetag_fine, /* ID: 939 */ + (void *)&dpIasw.CE_Counter, /* ID: 940 */ + (void *)&dpIasw.CE_Version, /* ID: 941 */ + (void *)&dpIasw.CE_Integrity, /* ID: 942 */ + (void *)&dpIasw.CE_SemWindowPosX, /* ID: 943 */ + (void *)&dpIasw.CE_SemWindowPosY, /* ID: 944 */ + (void *)&dpIasw.CE_SemWindowSizeX, /* ID: 945 */ + (void *)&dpIasw.CE_SemWindowSizeY, /* ID: 946 */ + (void *)&dpIasw.SPILL_CTR, /* ID: 947 */ + (void *)&dpIasw.RZIP_ITER1, /* ID: 948 */ + (void *)&dpIasw.RZIP_ITER2, /* ID: 949 */ + (void *)&dpIasw.RZIP_ITER3, /* ID: 950 */ + (void *)&dpIasw.RZIP_ITER4, /* ID: 951 */ + (void *)&dpIasw.SdpLdkColMask, /* ID: 952 */ + (void *)&dpIasw.SdpRdkColMask, /* ID: 953 */ + (void *)&dpIbsw.FPGA_Version, /* ID: 954 */ + (void *)&dpIbsw.FPGA_DPU_Status, /* ID: 955 */ + (void *)&dpIbsw.FPGA_DPU_Address, /* ID: 956 */ + (void *)&dpIbsw.FPGA_RESET_Status, /* ID: 957 */ + (void *)&dpIbsw.FPGA_SEM_Status, /* ID: 958 */ + (void *)&dpIbsw.FPGA_Oper_Heater_Status, /* ID: 959 */ + (void *)&dpIasw.GIBTOTRANSFER, /* ID: 960 */ + (void *)&dpIasw.TRANSFERMODE, /* ID: 961 */ + (void *)&dpIasw.S2TOTRANSFERSIZE, /* ID: 962 */ + (void *)&dpIasw.S4TOTRANSFERSIZE, /* ID: 963 */ + (void *)&dpIasw.TransferComplete, /* ID: 964 */ + (void *)&dpIasw.NLCBORDERS_2, /* ID: 965 */ + (void *)&dpIasw.NLCCOEFF_A_2, /* ID: 966 */ + (void *)&dpIasw.NLCCOEFF_B_2, /* ID: 967 */ + (void *)&dpIasw.NLCCOEFF_C_2, /* ID: 968 */ + (void *)&dpIasw.RF100, /* ID: 969 */ + (void *)&dpIasw.RF230, /* ID: 970 */ + (void *)&dpIasw.distc1, /* ID: 971 */ + (void *)&dpIasw.distc2, /* ID: 972 */ + (void *)&dpIasw.distc3, /* ID: 973 */ + (void *)&dpIasw.SPARE_UI_0, /* ID: 974 */ + (void *)&dpIasw.SPARE_UI_1, /* ID: 975 */ + (void *)&dpIasw.SPARE_UI_2, /* ID: 976 */ + (void *)&dpIasw.SPARE_UI_3, /* ID: 977 */ + (void *)&dpIasw.SPARE_UI_4, /* ID: 978 */ + (void *)&dpIasw.SPARE_UI_5, /* ID: 979 */ + (void *)&dpIasw.SPARE_UI_6, /* ID: 980 */ + (void *)&dpIasw.SPARE_UI_7, /* ID: 981 */ + (void *)&dpIasw.SPARE_UI_8, /* ID: 982 */ + (void *)&dpIasw.SPARE_UI_9, /* ID: 983 */ + (void *)&dpIasw.SPARE_UI_10, /* ID: 984 */ + (void *)&dpIasw.SPARE_UI_11, /* ID: 985 */ + (void *)&dpIasw.SPARE_UI_12, /* ID: 986 */ + (void *)&dpIasw.SPARE_UI_13, /* ID: 987 */ + (void *)&dpIasw.SPARE_UI_14, /* ID: 988 */ + (void *)&dpIasw.SPARE_UI_15, /* ID: 989 */ + (void *)&dpIasw.SPARE_F_0, /* ID: 990 */ + (void *)&dpIasw.SPARE_F_1, /* ID: 991 */ + (void *)&dpIasw.SPARE_F_2, /* ID: 992 */ + (void *)&dpIasw.SPARE_F_3, /* ID: 993 */ + (void *)&dpIasw.SPARE_F_4, /* ID: 994 */ + (void *)&dpIasw.SPARE_F_5, /* ID: 995 */ + (void *)&dpIasw.SPARE_F_6, /* ID: 996 */ + (void *)&dpIasw.SPARE_F_7, /* ID: 997 */ + (void *)&dpIasw.SPARE_F_8, /* ID: 998 */ + (void *)&dpIasw.SPARE_F_9, /* ID: 999 */ + (void *)&dpIasw.SPARE_F_10, /* ID: 1000 */ + (void *)&dpIasw.SPARE_F_11, /* ID: 1001 */ + (void *)&dpIasw.SPARE_F_12, /* ID: 1002 */ + (void *)&dpIasw.SPARE_F_13, /* ID: 1003 */ + (void *)&dpIasw.SPARE_F_14, /* ID: 1004 */ + (void *)&dpIasw.SPARE_F_15, /* ID: 1005 */ +}; + +/** + * Multiplicity of data items. + */ +static unsigned int dataPoolMult[1006] = { + 0, /* ID: 0, unused */ + 1, /* ID: 1, type: uint, name: buildNumber */ + 1, /* ID: 2, type: uchar, name: AppErrCode */ + 1, /* ID: 3, type: uchar, name: NofAllocatedInRep */ + 1, /* ID: 4, type: uchar, name: MaxNOfInRep */ + 1, /* ID: 5, type: uchar, name: NofAllocatedInCmd */ + 1, /* ID: 6, type: uchar, name: MaxNOfInCmd */ + 1, /* ID: 7, type: uchar, name: Sem_NOfPendingInCmp */ + 1, /* ID: 8, type: uchar, name: Sem_PCRLSize */ + 1, /* ID: 9, type: uchar, name: Sem_NOfLoadedInCmp */ + 1, /* ID: 10, type: uchar, name: GrdObc_NOfPendingInCmp */ + 1, /* ID: 11, type: uchar, name: GrdObc_PCRLSize */ + 1, /* ID: 12, type: uchar, name: NOfAllocatedOutCmp */ + 1, /* ID: 13, type: uchar, name: MaxNOfOutCmp */ + 1, /* ID: 14, type: ushort, name: NOfInstanceId */ + 1, /* ID: 15, type: uchar, name: OutMg1_NOfPendingOutCmp */ + 1, /* ID: 16, type: uchar, name: OutMg1_POCLSize */ + 1, /* ID: 17, type: ushort, name: OutMg1_NOfLoadedOutCmp */ + 1, /* ID: 18, type: uchar, name: OutMg2_NOfPendingOutCmp */ + 1, /* ID: 19, type: uchar, name: OutMg2_POCLSize */ + 1, /* ID: 20, type: ushort, name: OutMg2_NOfLoadedOutCmp */ + 1, /* ID: 21, type: uchar, name: OutMg3_NOfPendingOutCmp */ + 1, /* ID: 22, type: uchar, name: OutMg3_POCLSize */ + 1, /* ID: 23, type: ushort, name: OutMg3_NOfLoadedOutCmp */ + 1, /* ID: 24, type: uint, name: InSem_SeqCnt */ + 1, /* ID: 25, type: ushort, name: InSem_NOfPendingPckts */ + 1, /* ID: 26, type: uchar, name: InSem_NOfGroups */ + 1, /* ID: 27, type: uchar, name: InSem_PcktQueueSize */ + 1, /* ID: 28, type: uchar, name: InSem_Src */ + 1, /* ID: 29, type: uchar, name: InObc_NOfPendingPckts */ + 1, /* ID: 30, type: uchar, name: InObc_NOfGroups */ + 1, /* ID: 31, type: uchar, name: InObc_PcktQueueSize */ + 1, /* ID: 32, type: uchar, name: InObc_Src */ + 1, /* ID: 33, type: uchar, name: InGrd_NOfPendingPckts */ + 1, /* ID: 34, type: uchar, name: InGrd_NOfGroups */ + 1, /* ID: 35, type: uchar, name: InGrd_PcktQueueSize */ + 1, /* ID: 36, type: uchar, name: InGrd_Src */ + 1, /* ID: 37, type: uchar, name: OutSem_Dest */ + 1, /* ID: 38, type: uint, name: OutSem_SeqCnt */ + 1, /* ID: 39, type: uchar, name: OutSem_NOfPendingPckts */ + 1, /* ID: 40, type: uchar, name: OutSem_NOfGroups */ + 1, /* ID: 41, type: uchar, name: OutSem_PcktQueueSize */ + 1, /* ID: 42, type: uchar, name: OutObc_Dest */ + 1, /* ID: 43, type: uint, name: OutObc_SeqCnt_Group0 */ + 1, /* ID: 44, type: uint, name: OutObc_SeqCnt_Group1 */ + 1, /* ID: 45, type: uchar, name: OutObc_NOfPendingPckts */ + 1, /* ID: 46, type: uchar, name: OutObc_NOfGroups */ + 1, /* ID: 47, type: uchar, name: OutObc_PcktQueueSize */ + 1, /* ID: 48, type: uchar, name: OutGrd_Dest */ + 1, /* ID: 49, type: uint, name: OutGrd_SeqCnt_Group0 */ + 1, /* ID: 50, type: uint, name: OutGrd_SeqCnt_Group1 */ + 1, /* ID: 51, type: uint, name: OutGrd_SeqCnt_Group2 */ + 1, /* ID: 52, type: uchar, name: OutGrd_NOfPendingPckts */ + 1, /* ID: 53, type: uchar, name: OutGrd_NOfGroups */ + 1, /* ID: 54, type: uchar, name: OutGrd_PcktQueueSize */ + 1, /* ID: 55, type: ushort, name: sibNFull */ + 1, /* ID: 56, type: ushort, name: cibNFull */ + 1, /* ID: 57, type: ushort, name: gibNFull */ + 1, /* ID: 58, type: ushort, name: sibNWin */ + 1, /* ID: 59, type: ushort, name: cibNWin */ + 1, /* ID: 60, type: ushort, name: gibNWin */ + 1, /* ID: 61, type: ushort, name: sibSizeFull */ + 1, /* ID: 62, type: ushort, name: cibSizeFull */ + 1, /* ID: 63, type: ushort, name: gibSizeFull */ + 1, /* ID: 64, type: ushort, name: sibSizeWin */ + 1, /* ID: 65, type: ushort, name: cibSizeWin */ + 1, /* ID: 66, type: ushort, name: gibSizeWin */ + 1, /* ID: 67, type: ushort, name: sibIn */ + 1, /* ID: 68, type: ushort, name: sibOut */ + 1, /* ID: 69, type: ushort, name: cibIn */ + 1, /* ID: 70, type: ushort, name: gibIn */ + 1, /* ID: 71, type: ushort, name: gibOut */ + 1, /* ID: 72, type: enum, name: sdbState */ + 1, /* ID: 73, type: uint, name: sdbStateCnt */ + 1, /* ID: 74, type: int, name: OffsetX */ + 1, /* ID: 75, type: int, name: OffsetY */ + 1, /* ID: 76, type: int, name: TargetLocationX */ + 1, /* ID: 77, type: int, name: TargetLocationY */ + 1, /* ID: 78, type: uint, name: IntegStartTimeCrs */ + 1, /* ID: 79, type: ushort, name: IntegStartTimeFine */ + 1, /* ID: 80, type: uint, name: IntegEndTimeCrs */ + 1, /* ID: 81, type: ushort, name: IntegEndTimeFine */ + 1, /* ID: 82, type: ushort, name: DataCadence */ + 1, /* ID: 83, type: char, name: ValidityStatus */ + 1, /* ID: 84, type: ushort, name: NOfTcAcc */ + 1, /* ID: 85, type: ushort, name: NOfAccFailedTc */ + 1, /* ID: 86, type: ushort, name: SeqCntLastAccTcFromObc */ + 1, /* ID: 87, type: ushort, name: SeqCntLastAccTcFromGrd */ + 1, /* ID: 88, type: ushort, name: SeqCntLastAccFailTc */ + 1, /* ID: 89, type: ushort, name: NOfStartFailedTc */ + 1, /* ID: 90, type: ushort, name: SeqCntLastStartFailTc */ + 1, /* ID: 91, type: ushort, name: NOfTcTerm */ + 1, /* ID: 92, type: ushort, name: NOfTermFailedTc */ + 1, /* ID: 93, type: ushort, name: SeqCntLastTermFailTc */ + 10, /* ID: 94, type: uchar, name: RdlSidList */ + 10, /* ID: 95, type: bool, name: isRdlFree */ + 10, /* ID: 96, type: uint, name: RdlCycCntList */ + 10, /* ID: 97, type: uint, name: RdlPeriodList */ + 10, /* ID: 98, type: bool, name: RdlEnabledList */ + 10, /* ID: 99, type: ushort, name: RdlDestList */ + 250, /* ID: 100, type: ushort, name: RdlDataItemList_0 */ + 250, /* ID: 101, type: ushort, name: RdlDataItemList_1 */ + 250, /* ID: 102, type: ushort, name: RdlDataItemList_2 */ + 250, /* ID: 103, type: ushort, name: RdlDataItemList_3 */ + 250, /* ID: 104, type: ushort, name: RdlDataItemList_4 */ + 250, /* ID: 105, type: ushort, name: RdlDataItemList_5 */ + 250, /* ID: 106, type: ushort, name: RdlDataItemList_6 */ + 250, /* ID: 107, type: ushort, name: RdlDataItemList_7 */ + 250, /* ID: 108, type: ushort, name: RdlDataItemList_8 */ + 250, /* ID: 109, type: ushort, name: RdlDataItemList_9 */ + 20, /* ID: 110, type: uint, name: DEBUG_VAR */ + 20, /* ID: 111, type: uint, name: DEBUG_VAR_ADDR */ + 1, /* ID: 112, type: uchar, name: EVTFILTERDEF */ + 60, /* ID: 113, type: uchar, name: evtEnabledList */ + 1, /* ID: 114, type: uint, name: lastPatchedAddr */ + 1, /* ID: 115, type: uint, name: lastDumpAddr */ + 1, /* ID: 116, type: enum, name: sdu2State */ + 1, /* ID: 117, type: enum, name: sdu4State */ + 1, /* ID: 118, type: uint, name: sdu2StateCnt */ + 1, /* ID: 119, type: uint, name: sdu4StateCnt */ + 1, /* ID: 120, type: ushort, name: sdu2BlockCnt */ + 1, /* ID: 121, type: ushort, name: sdu4BlockCnt */ + 1, /* ID: 122, type: uint, name: sdu2RemSize */ + 1, /* ID: 123, type: uint, name: sdu4RemSize */ + 1, /* ID: 124, type: uint, name: sdu2DownTransferSize */ + 1, /* ID: 125, type: uint, name: sdu4DownTransferSize */ + 1, /* ID: 126, type: uint, name: sdsCounter */ + 1, /* ID: 127, type: bool, name: FdGlbEnable */ + 1, /* ID: 128, type: bool, name: RpGlbEnable */ + 1, /* ID: 129, type: enum, name: FdCheckTTMState */ + 1, /* ID: 130, type: bool, name: FdCheckTTMIntEn */ + 1, /* ID: 131, type: bool, name: FdCheckTTMExtEn */ + 1, /* ID: 132, type: bool, name: RpTTMIntEn */ + 1, /* ID: 133, type: bool, name: RpTTMExtEn */ + 1, /* ID: 134, type: ushort, name: FdCheckTTMCnt */ + 1, /* ID: 135, type: ushort, name: FdCheckTTMSpCnt */ + 1, /* ID: 136, type: ushort, name: FdCheckTTMCntThr */ + 1, /* ID: 137, type: float, name: TTC_LL */ + 1, /* ID: 138, type: float, name: TTC_UL */ + 1, /* ID: 139, type: float, name: TTM_LIM */ + 1, /* ID: 140, type: enum, name: FdCheckSDSCState */ + 1, /* ID: 141, type: bool, name: FdCheckSDSCIntEn */ + 1, /* ID: 142, type: bool, name: FdCheckSDSCExtEn */ + 1, /* ID: 143, type: bool, name: RpSDSCIntEn */ + 1, /* ID: 144, type: bool, name: RpSDSCExtEn */ + 1, /* ID: 145, type: ushort, name: FdCheckSDSCCnt */ + 1, /* ID: 146, type: ushort, name: FdCheckSDSCSpCnt */ + 1, /* ID: 147, type: ushort, name: FdCheckSDSCCntThr */ + 1, /* ID: 148, type: enum, name: FdCheckComErrState */ + 1, /* ID: 149, type: bool, name: FdCheckComErrIntEn */ + 1, /* ID: 150, type: bool, name: FdCheckComErrExtEn */ + 1, /* ID: 151, type: bool, name: RpComErrIntEn */ + 1, /* ID: 152, type: bool, name: RpComErrExtEn */ + 1, /* ID: 153, type: ushort, name: FdCheckComErrCnt */ + 1, /* ID: 154, type: ushort, name: FdCheckComErrSpCnt */ + 1, /* ID: 155, type: ushort, name: FdCheckComErrCntThr */ + 1, /* ID: 156, type: enum, name: FdCheckTimeOutState */ + 1, /* ID: 157, type: bool, name: FdCheckTimeOutIntEn */ + 1, /* ID: 158, type: bool, name: FdCheckTimeOutExtEn */ + 1, /* ID: 159, type: bool, name: RpTimeOutIntEn */ + 1, /* ID: 160, type: bool, name: RpTimeOutExtEn */ + 1, /* ID: 161, type: ushort, name: FdCheckTimeOutCnt */ + 1, /* ID: 162, type: ushort, name: FdCheckTimeOutSpCnt */ + 1, /* ID: 163, type: ushort, name: FdCheckTimeOutCntThr */ + 1, /* ID: 164, type: uint, name: SEM_TO_POWERON */ + 1, /* ID: 165, type: uint, name: SEM_TO_SAFE */ + 1, /* ID: 166, type: uint, name: SEM_TO_STAB */ + 1, /* ID: 167, type: uint, name: SEM_TO_TEMP */ + 1, /* ID: 168, type: uint, name: SEM_TO_CCD */ + 1, /* ID: 169, type: uint, name: SEM_TO_DIAG */ + 1, /* ID: 170, type: uint, name: SEM_TO_STANDBY */ + 1, /* ID: 171, type: enum, name: FdCheckSafeModeState */ + 1, /* ID: 172, type: bool, name: FdCheckSafeModeIntEn */ + 1, /* ID: 173, type: bool, name: FdCheckSafeModeExtEn */ + 1, /* ID: 174, type: bool, name: RpSafeModeIntEn */ + 1, /* ID: 175, type: bool, name: RpSafeModeExtEn */ + 1, /* ID: 176, type: ushort, name: FdCheckSafeModeCnt */ + 1, /* ID: 177, type: ushort, name: FdCheckSafeModeSpCnt */ + 1, /* ID: 178, type: ushort, name: FdCheckSafeModeCntThr */ + 1, /* ID: 179, type: enum, name: FdCheckAliveState */ + 1, /* ID: 180, type: bool, name: FdCheckAliveIntEn */ + 1, /* ID: 181, type: bool, name: FdCheckAliveExtEn */ + 1, /* ID: 182, type: bool, name: RpAliveIntEn */ + 1, /* ID: 183, type: bool, name: RpAliveExtEn */ + 1, /* ID: 184, type: ushort, name: FdCheckAliveCnt */ + 1, /* ID: 185, type: ushort, name: FdCheckAliveSpCnt */ + 1, /* ID: 186, type: ushort, name: FdCheckAliveCntThr */ + 1, /* ID: 187, type: ushort, name: SEM_HK_DEF_PER */ + 1, /* ID: 188, type: ushort, name: SEMALIVE_DELAYEDSEMHK */ + 1, /* ID: 189, type: enum, name: FdCheckSemAnoEvtState */ + 1, /* ID: 190, type: bool, name: FdCheckSemAnoEvtIntEn */ + 1, /* ID: 191, type: bool, name: FdCheckSemAnoEvtExtEn */ + 1, /* ID: 192, type: bool, name: RpSemAnoEvtIntEn */ + 1, /* ID: 193, type: bool, name: RpSemAnoEvtExtEn */ + 1, /* ID: 194, type: ushort, name: FdCheckSemAnoEvtCnt */ + 1, /* ID: 195, type: ushort, name: FdCheckSemAnoEvtSpCnt */ + 1, /* ID: 196, type: ushort, name: FdCheckSemAnoEvtCntThr */ + 1, /* ID: 197, type: enum, name: semAnoEvtResp_1 */ + 1, /* ID: 198, type: enum, name: semAnoEvtResp_2 */ + 1, /* ID: 199, type: enum, name: semAnoEvtResp_3 */ + 1, /* ID: 200, type: enum, name: semAnoEvtResp_4 */ + 1, /* ID: 201, type: enum, name: semAnoEvtResp_5 */ + 1, /* ID: 202, type: enum, name: semAnoEvtResp_6 */ + 1, /* ID: 203, type: enum, name: semAnoEvtResp_7 */ + 1, /* ID: 204, type: enum, name: semAnoEvtResp_8 */ + 1, /* ID: 205, type: enum, name: semAnoEvtResp_9 */ + 1, /* ID: 206, type: enum, name: semAnoEvtResp_10 */ + 1, /* ID: 207, type: enum, name: semAnoEvtResp_11 */ + 1, /* ID: 208, type: enum, name: semAnoEvtResp_12 */ + 1, /* ID: 209, type: enum, name: semAnoEvtResp_13 */ + 1, /* ID: 210, type: enum, name: semAnoEvtResp_14 */ + 1, /* ID: 211, type: enum, name: semAnoEvtResp_15 */ + 1, /* ID: 212, type: enum, name: semAnoEvtResp_16 */ + 1, /* ID: 213, type: enum, name: semAnoEvtResp_17 */ + 1, /* ID: 214, type: enum, name: semAnoEvtResp_18 */ + 1, /* ID: 215, type: enum, name: semAnoEvtResp_19 */ + 1, /* ID: 216, type: enum, name: semAnoEvtResp_20 */ + 1, /* ID: 217, type: enum, name: semAnoEvtResp_21 */ + 1, /* ID: 218, type: enum, name: semAnoEvtResp_22 */ + 1, /* ID: 219, type: enum, name: semAnoEvtResp_23 */ + 1, /* ID: 220, type: enum, name: semAnoEvtResp_24 */ + 1, /* ID: 221, type: enum, name: semAnoEvtResp_25 */ + 1, /* ID: 222, type: enum, name: semAnoEvtResp_26 */ + 1, /* ID: 223, type: enum, name: semAnoEvtResp_27 */ + 1, /* ID: 224, type: enum, name: semAnoEvtResp_28 */ + 1, /* ID: 225, type: enum, name: semAnoEvtResp_29 */ + 1, /* ID: 226, type: enum, name: FdCheckSemLimitState */ + 1, /* ID: 227, type: bool, name: FdCheckSemLimitIntEn */ + 1, /* ID: 228, type: bool, name: FdCheckSemLimitExtEn */ + 1, /* ID: 229, type: bool, name: RpSemLimitIntEn */ + 1, /* ID: 230, type: bool, name: RpSemLimitExtEn */ + 1, /* ID: 231, type: ushort, name: FdCheckSemLimitCnt */ + 1, /* ID: 232, type: ushort, name: FdCheckSemLimitSpCnt */ + 1, /* ID: 233, type: ushort, name: FdCheckSemLimitCntThr */ + 1, /* ID: 234, type: ushort, name: SEM_LIM_DEL_T */ + 1, /* ID: 235, type: enum, name: FdCheckDpuHkState */ + 1, /* ID: 236, type: bool, name: FdCheckDpuHkIntEn */ + 1, /* ID: 237, type: bool, name: FdCheckDpuHkExtEn */ + 1, /* ID: 238, type: bool, name: RpDpuHkIntEn */ + 1, /* ID: 239, type: bool, name: RpDpuHkExtEn */ + 1, /* ID: 240, type: ushort, name: FdCheckDpuHkCnt */ + 1, /* ID: 241, type: ushort, name: FdCheckDpuHkSpCnt */ + 1, /* ID: 242, type: ushort, name: FdCheckDpuHkCntThr */ + 1, /* ID: 243, type: enum, name: FdCheckCentConsState */ + 1, /* ID: 244, type: bool, name: FdCheckCentConsIntEn */ + 1, /* ID: 245, type: bool, name: FdCheckCentConsExtEn */ + 1, /* ID: 246, type: bool, name: RpCentConsIntEn */ + 1, /* ID: 247, type: bool, name: RpCentConsExtEn */ + 1, /* ID: 248, type: ushort, name: FdCheckCentConsCnt */ + 1, /* ID: 249, type: ushort, name: FdCheckCentConsSpCnt */ + 1, /* ID: 250, type: ushort, name: FdCheckCentConsCntThr */ + 1, /* ID: 251, type: enum, name: FdCheckResState */ + 1, /* ID: 252, type: bool, name: FdCheckResIntEn */ + 1, /* ID: 253, type: bool, name: FdCheckResExtEn */ + 1, /* ID: 254, type: bool, name: RpResIntEn */ + 1, /* ID: 255, type: bool, name: RpResExtEn */ + 1, /* ID: 256, type: ushort, name: FdCheckResCnt */ + 1, /* ID: 257, type: ushort, name: FdCheckResSpCnt */ + 1, /* ID: 258, type: ushort, name: FdCheckResCntThr */ + 1, /* ID: 259, type: float, name: CPU1_USAGE_MAX */ + 1, /* ID: 260, type: float, name: MEM_USAGE_MAX */ + 1, /* ID: 261, type: enum, name: FdCheckSemCons */ + 1, /* ID: 262, type: bool, name: FdCheckSemConsIntEn */ + 1, /* ID: 263, type: bool, name: FdCheckSemConsExtEn */ + 1, /* ID: 264, type: bool, name: RpSemConsIntEn */ + 1, /* ID: 265, type: bool, name: RpSemConsExtEn */ + 1, /* ID: 266, type: ushort, name: FdCheckSemConsCnt */ + 1, /* ID: 267, type: ushort, name: FdCheckSemConsSpCnt */ + 1, /* ID: 268, type: ushort, name: FdCheckSemConsCntThr */ + 1, /* ID: 269, type: enum, name: semState */ + 1, /* ID: 270, type: enum, name: semOperState */ + 1, /* ID: 271, type: uint, name: semStateCnt */ + 1, /* ID: 272, type: uint, name: semOperStateCnt */ + 1, /* ID: 273, type: uint, name: imageCycleCnt */ + 1, /* ID: 274, type: uint, name: acqImageCnt */ + 1, /* ID: 275, type: enum, name: sciSubMode */ + 1, /* ID: 276, type: bool, name: LastSemPckt */ + 1, /* ID: 277, type: uchar, name: SEM_ON_CODE */ + 1, /* ID: 278, type: uchar, name: SEM_OFF_CODE */ + 1, /* ID: 279, type: ushort, name: SEM_INIT_T1 */ + 1, /* ID: 280, type: ushort, name: SEM_INIT_T2 */ + 1, /* ID: 281, type: ushort, name: SEM_OPER_T1 */ + 1, /* ID: 282, type: ushort, name: SEM_SHUTDOWN_T1 */ + 1, /* ID: 283, type: ushort, name: SEM_SHUTDOWN_T11 */ + 1, /* ID: 284, type: ushort, name: SEM_SHUTDOWN_T12 */ + 1, /* ID: 285, type: ushort, name: SEM_SHUTDOWN_T2 */ + 1, /* ID: 286, type: enum, name: iaswState */ + 1, /* ID: 287, type: uint, name: iaswStateCnt */ + 1, /* ID: 288, type: uint, name: iaswCycleCnt */ + 1, /* ID: 289, type: enum, name: prepScienceNode */ + 1, /* ID: 290, type: uint, name: prepScienceCnt */ + 1, /* ID: 291, type: enum, name: controlledSwitchOffNode */ + 1, /* ID: 292, type: uint, name: controlledSwitchOffCnt */ + 1, /* ID: 293, type: ushort, name: CTRLD_SWITCH_OFF_T1 */ + 1, /* ID: 294, type: enum, name: algoCent0State */ + 1, /* ID: 295, type: uint, name: algoCent0Cnt */ + 1, /* ID: 296, type: bool, name: algoCent0Enabled */ + 1, /* ID: 297, type: enum, name: algoCent1State */ + 1, /* ID: 298, type: uint, name: algoCent1Cnt */ + 1, /* ID: 299, type: bool, name: algoCent1Enabled */ + 1, /* ID: 300, type: uint, name: CENT_EXEC_PHASE */ + 1, /* ID: 301, type: enum, name: algoAcq1State */ + 1, /* ID: 302, type: uint, name: algoAcq1Cnt */ + 1, /* ID: 303, type: bool, name: algoAcq1Enabled */ + 1, /* ID: 304, type: ushort, name: ACQ_PH */ + 1, /* ID: 305, type: enum, name: algoCcState */ + 1, /* ID: 306, type: uint, name: algoCcCnt */ + 1, /* ID: 307, type: bool, name: algoCcEnabled */ + 1, /* ID: 308, type: ushort, name: STCK_ORDER */ + 1, /* ID: 309, type: enum, name: algoTTC1State */ + 1, /* ID: 310, type: uint, name: algoTTC1Cnt */ + 1, /* ID: 311, type: bool, name: algoTTC1Enabled */ + 1, /* ID: 312, type: uint, name: TTC1_EXEC_PHASE */ + 1, /* ID: 313, type: int, name: TTC1_EXEC_PER */ + 1, /* ID: 314, type: float, name: TTC1_LL_FRT */ + 1, /* ID: 315, type: float, name: TTC1_LL_AFT */ + 1, /* ID: 316, type: float, name: TTC1_UL_FRT */ + 1, /* ID: 317, type: float, name: TTC1_UL_AFT */ + 1, /* ID: 318, type: float, name: ttc1AvTempAft */ + 1, /* ID: 319, type: float, name: ttc1AvTempFrt */ + 1, /* ID: 320, type: enum, name: algoTTC2State */ + 1, /* ID: 321, type: uint, name: algoTTC2Cnt */ + 1, /* ID: 322, type: bool, name: algoTTC2Enabled */ + 1, /* ID: 323, type: int, name: TTC2_EXEC_PER */ + 1, /* ID: 324, type: float, name: TTC2_REF_TEMP */ + 1, /* ID: 325, type: float, name: TTC2_OFFSETA */ + 1, /* ID: 326, type: float, name: TTC2_OFFSETF */ + 1, /* ID: 327, type: float, name: intTimeAft */ + 1, /* ID: 328, type: float, name: onTimeAft */ + 1, /* ID: 329, type: float, name: intTimeFront */ + 1, /* ID: 330, type: float, name: onTimeFront */ + 1, /* ID: 331, type: float, name: TTC2_PA */ + 1, /* ID: 332, type: float, name: TTC2_DA */ + 1, /* ID: 333, type: float, name: TTC2_IA */ + 1, /* ID: 334, type: float, name: TTC2_PF */ + 1, /* ID: 335, type: float, name: TTC2_DF */ + 1, /* ID: 336, type: float, name: TTC2_IF */ + 1, /* ID: 337, type: enum, name: algoSaaEvalState */ + 1, /* ID: 338, type: uint, name: algoSaaEvalCnt */ + 1, /* ID: 339, type: bool, name: algoSaaEvalEnabled */ + 1, /* ID: 340, type: uint, name: SAA_EXEC_PHASE */ + 1, /* ID: 341, type: int, name: SAA_EXEC_PER */ + 1, /* ID: 342, type: bool, name: isSaaActive */ + 1, /* ID: 343, type: uint, name: saaCounter */ + 1, /* ID: 344, type: uint, name: pInitSaaCounter */ + 1, /* ID: 345, type: enum, name: algoSdsEvalState */ + 1, /* ID: 346, type: uint, name: algoSdsEvalCnt */ + 1, /* ID: 347, type: bool, name: algoSdsEvalEnabled */ + 1, /* ID: 348, type: uint, name: SDS_EXEC_PHASE */ + 1, /* ID: 349, type: int, name: SDS_EXEC_PER */ + 1, /* ID: 350, type: bool, name: isSdsActive */ + 1, /* ID: 351, type: bool, name: SDS_FORCED */ + 1, /* ID: 352, type: bool, name: SDS_INHIBITED */ + 1, /* ID: 353, type: bool, name: EARTH_OCCULT_ACTIVE */ + 1, /* ID: 354, type: ushort, name: HEARTBEAT_D1 */ + 1, /* ID: 355, type: ushort, name: HEARTBEAT_D2 */ + 1, /* ID: 356, type: bool, name: HbSem */ + 276, /* ID: 357, type: uchar, name: starMap */ + 1, /* ID: 358, type: uint, name: observationId */ + 1, /* ID: 359, type: char, name: centValProcOutput */ + 1, /* ID: 360, type: float, name: CENT_OFFSET_LIM */ + 1, /* ID: 361, type: float, name: CENT_FROZEN_LIM */ + 1, /* ID: 362, type: bool, name: SEM_SERV1_1_FORWARD */ + 1, /* ID: 363, type: bool, name: SEM_SERV1_2_FORWARD */ + 1, /* ID: 364, type: bool, name: SEM_SERV1_7_FORWARD */ + 1, /* ID: 365, type: bool, name: SEM_SERV1_8_FORWARD */ + 1, /* ID: 366, type: bool, name: SEM_SERV3_1_FORWARD */ + 1, /* ID: 367, type: bool, name: SEM_SERV3_2_FORWARD */ + 1, /* ID: 368, type: uint, name: SEM_HK_TS_DEF_CRS */ + 1, /* ID: 369, type: ushort, name: SEM_HK_TS_DEF_FINE */ + 1, /* ID: 370, type: uint, name: SEM_HK_TS_EXT_CRS */ + 1, /* ID: 371, type: ushort, name: SEM_HK_TS_EXT_FINE */ + 1, /* ID: 372, type: enum, name: STAT_MODE */ + 1, /* ID: 373, type: ushort, name: STAT_FLAGS */ + 1, /* ID: 374, type: enum, name: STAT_LAST_SPW_ERR */ + 1, /* ID: 375, type: ushort, name: STAT_LAST_ERR_ID */ + 1, /* ID: 376, type: ushort, name: STAT_LAST_ERR_FREQ */ + 1, /* ID: 377, type: ushort, name: STAT_NUM_CMD_RECEIVED */ + 1, /* ID: 378, type: ushort, name: STAT_NUM_CMD_EXECUTED */ + 1, /* ID: 379, type: ushort, name: STAT_NUM_DATA_SENT */ + 1, /* ID: 380, type: ushort, name: STAT_SCU_PROC_DUTY_CL */ + 1, /* ID: 381, type: ushort, name: STAT_SCU_NUM_AHB_ERR */ + 1, /* ID: 382, type: ushort, name: STAT_SCU_NUM_AHB_CERR */ + 1, /* ID: 383, type: ushort, name: STAT_SCU_NUM_LUP_ERR */ + 1, /* ID: 384, type: float, name: TEMP_SEM_SCU */ + 1, /* ID: 385, type: float, name: TEMP_SEM_PCU */ + 1, /* ID: 386, type: float, name: VOLT_SCU_P3_4 */ + 1, /* ID: 387, type: float, name: VOLT_SCU_P5 */ + 1, /* ID: 388, type: float, name: TEMP_FEE_CCD */ + 1, /* ID: 389, type: float, name: TEMP_FEE_STRAP */ + 1, /* ID: 390, type: float, name: TEMP_FEE_ADC */ + 1, /* ID: 391, type: float, name: TEMP_FEE_BIAS */ + 1, /* ID: 392, type: float, name: TEMP_FEE_DEB */ + 1, /* ID: 393, type: float, name: VOLT_FEE_VOD */ + 1, /* ID: 394, type: float, name: VOLT_FEE_VRD */ + 1, /* ID: 395, type: float, name: VOLT_FEE_VOG */ + 1, /* ID: 396, type: float, name: VOLT_FEE_VSS */ + 1, /* ID: 397, type: float, name: VOLT_FEE_CCD */ + 1, /* ID: 398, type: float, name: VOLT_FEE_CLK */ + 1, /* ID: 399, type: float, name: VOLT_FEE_ANA_P5 */ + 1, /* ID: 400, type: float, name: VOLT_FEE_ANA_N5 */ + 1, /* ID: 401, type: float, name: VOLT_FEE_ANA_P3_3 */ + 1, /* ID: 402, type: float, name: CURR_FEE_CLK_BUF */ + 1, /* ID: 403, type: float, name: VOLT_SCU_FPGA_P1_5 */ + 1, /* ID: 404, type: float, name: CURR_SCU_P3_4 */ + 1, /* ID: 405, type: uchar, name: STAT_NUM_SPW_ERR_CRE */ + 1, /* ID: 406, type: uchar, name: STAT_NUM_SPW_ERR_ESC */ + 1, /* ID: 407, type: uchar, name: STAT_NUM_SPW_ERR_DISC */ + 1, /* ID: 408, type: uchar, name: STAT_NUM_SPW_ERR_PAR */ + 1, /* ID: 409, type: uchar, name: STAT_NUM_SPW_ERR_WRSY */ + 1, /* ID: 410, type: uchar, name: STAT_NUM_SPW_ERR_INVA */ + 1, /* ID: 411, type: uchar, name: STAT_NUM_SPW_ERR_EOP */ + 1, /* ID: 412, type: uchar, name: STAT_NUM_SPW_ERR_RXAH */ + 1, /* ID: 413, type: uchar, name: STAT_NUM_SPW_ERR_TXAH */ + 1, /* ID: 414, type: uchar, name: STAT_NUM_SPW_ERR_TXBL */ + 1, /* ID: 415, type: uchar, name: STAT_NUM_SPW_ERR_TXLE */ + 1, /* ID: 416, type: uchar, name: STAT_NUM_SP_ERR_RX */ + 1, /* ID: 417, type: uchar, name: STAT_NUM_SP_ERR_TX */ + 1, /* ID: 418, type: uchar, name: STAT_HEAT_PWM_FPA_CCD */ + 1, /* ID: 419, type: uchar, name: STAT_HEAT_PWM_FEE_STR */ + 1, /* ID: 420, type: uchar, name: STAT_HEAT_PWM_FEE_ANA */ + 1, /* ID: 421, type: uchar, name: STAT_HEAT_PWM_SPARE */ + 1, /* ID: 422, type: uchar, name: STAT_HEAT_PWM_FLAGS */ + 1, /* ID: 423, type: ushort, name: STAT_OBTIME_SYNC_DELTA */ + 1, /* ID: 424, type: float, name: TEMP_SEM_SCU_LW */ + 1, /* ID: 425, type: float, name: TEMP_SEM_PCU_LW */ + 1, /* ID: 426, type: float, name: VOLT_SCU_P3_4_LW */ + 1, /* ID: 427, type: float, name: VOLT_SCU_P5_LW */ + 1, /* ID: 428, type: float, name: TEMP_FEE_CCD_LW */ + 1, /* ID: 429, type: float, name: TEMP_FEE_STRAP_LW */ + 1, /* ID: 430, type: float, name: TEMP_FEE_ADC_LW */ + 1, /* ID: 431, type: float, name: TEMP_FEE_BIAS_LW */ + 1, /* ID: 432, type: float, name: TEMP_FEE_DEB_LW */ + 1, /* ID: 433, type: float, name: VOLT_FEE_VOD_LW */ + 1, /* ID: 434, type: float, name: VOLT_FEE_VRD_LW */ + 1, /* ID: 435, type: float, name: VOLT_FEE_VOG_LW */ + 1, /* ID: 436, type: float, name: VOLT_FEE_VSS_LW */ + 1, /* ID: 437, type: float, name: VOLT_FEE_CCD_LW */ + 1, /* ID: 438, type: float, name: VOLT_FEE_CLK_LW */ + 1, /* ID: 439, type: float, name: VOLT_FEE_ANA_P5_LW */ + 1, /* ID: 440, type: float, name: VOLT_FEE_ANA_N5_LW */ + 1, /* ID: 441, type: float, name: VOLT_FEE_ANA_P3_3_LW */ + 1, /* ID: 442, type: float, name: CURR_FEE_CLK_BUF_LW */ + 1, /* ID: 443, type: float, name: VOLT_SCU_FPGA_P1_5_LW */ + 1, /* ID: 444, type: float, name: CURR_SCU_P3_4_LW */ + 1, /* ID: 445, type: float, name: TEMP_SEM_SCU_UW */ + 1, /* ID: 446, type: float, name: TEMP_SEM_PCU_UW */ + 1, /* ID: 447, type: float, name: VOLT_SCU_P3_4_UW */ + 1, /* ID: 448, type: float, name: VOLT_SCU_P5_UW */ + 1, /* ID: 449, type: float, name: TEMP_FEE_CCD_UW */ + 1, /* ID: 450, type: float, name: TEMP_FEE_STRAP_UW */ + 1, /* ID: 451, type: float, name: TEMP_FEE_ADC_UW */ + 1, /* ID: 452, type: float, name: TEMP_FEE_BIAS_UW */ + 1, /* ID: 453, type: float, name: TEMP_FEE_DEB_UW */ + 1, /* ID: 454, type: float, name: VOLT_FEE_VOD_UW */ + 1, /* ID: 455, type: float, name: VOLT_FEE_VRD_UW */ + 1, /* ID: 456, type: float, name: VOLT_FEE_VOG_UW */ + 1, /* ID: 457, type: float, name: VOLT_FEE_VSS_UW */ + 1, /* ID: 458, type: float, name: VOLT_FEE_CCD_UW */ + 1, /* ID: 459, type: float, name: VOLT_FEE_CLK_UW */ + 1, /* ID: 460, type: float, name: VOLT_FEE_ANA_P5_UW */ + 1, /* ID: 461, type: float, name: VOLT_FEE_ANA_N5_UW */ + 1, /* ID: 462, type: float, name: VOLT_FEE_ANA_P3_3_UW */ + 1, /* ID: 463, type: float, name: CURR_FEE_CLK_BUF_UW */ + 1, /* ID: 464, type: float, name: VOLT_SCU_FPGA_P1_5_UW */ + 1, /* ID: 465, type: float, name: CURR_SCU_P3_4_UW */ + 1, /* ID: 466, type: float, name: TEMP_SEM_SCU_LA */ + 1, /* ID: 467, type: float, name: TEMP_SEM_PCU_LA */ + 1, /* ID: 468, type: float, name: VOLT_SCU_P3_4_LA */ + 1, /* ID: 469, type: float, name: VOLT_SCU_P5_LA */ + 1, /* ID: 470, type: float, name: TEMP_FEE_CCD_LA */ + 1, /* ID: 471, type: float, name: TEMP_FEE_STRAP_LA */ + 1, /* ID: 472, type: float, name: TEMP_FEE_ADC_LA */ + 1, /* ID: 473, type: float, name: TEMP_FEE_BIAS_LA */ + 1, /* ID: 474, type: float, name: TEMP_FEE_DEB_LA */ + 1, /* ID: 475, type: float, name: VOLT_FEE_VOD_LA */ + 1, /* ID: 476, type: float, name: VOLT_FEE_VRD_LA */ + 1, /* ID: 477, type: float, name: VOLT_FEE_VOG_LA */ + 1, /* ID: 478, type: float, name: VOLT_FEE_VSS_LA */ + 1, /* ID: 479, type: float, name: VOLT_FEE_CCD_LA */ + 1, /* ID: 480, type: float, name: VOLT_FEE_CLK_LA */ + 1, /* ID: 481, type: float, name: VOLT_FEE_ANA_P5_LA */ + 1, /* ID: 482, type: float, name: VOLT_FEE_ANA_N5_LA */ + 1, /* ID: 483, type: float, name: VOLT_FEE_ANA_P3_3_LA */ + 1, /* ID: 484, type: float, name: CURR_FEE_CLK_BUF_LA */ + 1, /* ID: 485, type: float, name: VOLT_SCU_FPGA_P1_5_LA */ + 1, /* ID: 486, type: float, name: CURR_SCU_P3_4_LA */ + 1, /* ID: 487, type: float, name: TEMP_SEM_SCU_UA */ + 1, /* ID: 488, type: float, name: TEMP_SEM_PCU_UA */ + 1, /* ID: 489, type: float, name: VOLT_SCU_P3_4_UA */ + 1, /* ID: 490, type: float, name: VOLT_SCU_P5_UA */ + 1, /* ID: 491, type: float, name: TEMP_FEE_CCD_UA */ + 1, /* ID: 492, type: float, name: TEMP_FEE_STRAP_UA */ + 1, /* ID: 493, type: float, name: TEMP_FEE_ADC_UA */ + 1, /* ID: 494, type: float, name: TEMP_FEE_BIAS_UA */ + 1, /* ID: 495, type: float, name: TEMP_FEE_DEB_UA */ + 1, /* ID: 496, type: float, name: VOLT_FEE_VOD_UA */ + 1, /* ID: 497, type: float, name: VOLT_FEE_VRD_UA */ + 1, /* ID: 498, type: float, name: VOLT_FEE_VOG_UA */ + 1, /* ID: 499, type: float, name: VOLT_FEE_VSS_UA */ + 1, /* ID: 500, type: float, name: VOLT_FEE_CCD_UA */ + 1, /* ID: 501, type: float, name: VOLT_FEE_CLK_UA */ + 1, /* ID: 502, type: float, name: VOLT_FEE_ANA_P5_UA */ + 1, /* ID: 503, type: float, name: VOLT_FEE_ANA_N5_UA */ + 1, /* ID: 504, type: float, name: VOLT_FEE_ANA_P3_3_UA */ + 1, /* ID: 505, type: float, name: CURR_FEE_CLK_BUF_UA */ + 1, /* ID: 506, type: float, name: VOLT_SCU_FPGA_P1_5_UA */ + 1, /* ID: 507, type: float, name: CURR_SCU_P3_4_UA */ + 1, /* ID: 508, type: uint, name: semEvtCounter */ + 1, /* ID: 509, type: bool, name: SEM_SERV5_1_FORWARD */ + 1, /* ID: 510, type: bool, name: SEM_SERV5_2_FORWARD */ + 1, /* ID: 511, type: bool, name: SEM_SERV5_3_FORWARD */ + 1, /* ID: 512, type: bool, name: SEM_SERV5_4_FORWARD */ + 1, /* ID: 513, type: uint, name: pExpTime */ + 1, /* ID: 514, type: uint, name: pImageRep */ + 1, /* ID: 515, type: uint, name: pAcqNum */ + 1, /* ID: 516, type: enum, name: pDataOs */ + 1, /* ID: 517, type: enum, name: pCcdRdMode */ + 1, /* ID: 518, type: ushort, name: pWinPosX */ + 1, /* ID: 519, type: ushort, name: pWinPosY */ + 1, /* ID: 520, type: ushort, name: pWinSizeX */ + 1, /* ID: 521, type: ushort, name: pWinSizeY */ + 1, /* ID: 522, type: enum, name: pDtAcqSrc */ + 1, /* ID: 523, type: enum, name: pTempCtrlTarget */ + 1, /* ID: 524, type: float, name: pVoltFeeVod */ + 1, /* ID: 525, type: float, name: pVoltFeeVrd */ + 1, /* ID: 526, type: float, name: pVoltFeeVss */ + 1, /* ID: 527, type: float, name: pHeatTempFpaCCd */ + 1, /* ID: 528, type: float, name: pHeatTempFeeStrap */ + 1, /* ID: 529, type: float, name: pHeatTempFeeAnach */ + 1, /* ID: 530, type: float, name: pHeatTempSpare */ + 1, /* ID: 531, type: enum, name: pStepEnDiagCcd */ + 1, /* ID: 532, type: enum, name: pStepEnDiagFee */ + 1, /* ID: 533, type: enum, name: pStepEnDiagTemp */ + 1, /* ID: 534, type: enum, name: pStepEnDiagAna */ + 1, /* ID: 535, type: enum, name: pStepEnDiagExpos */ + 1, /* ID: 536, type: enum, name: pStepDebDiagCcd */ + 1, /* ID: 537, type: enum, name: pStepDebDiagFee */ + 1, /* ID: 538, type: enum, name: pStepDebDiagTemp */ + 1, /* ID: 539, type: enum, name: pStepDebDiagAna */ + 1, /* ID: 540, type: enum, name: pStepDebDiagExpos */ + 1, /* ID: 541, type: bool, name: SEM_SERV220_6_FORWARD */ + 1, /* ID: 542, type: bool, name: SEM_SERV220_12_FORWARD */ + 1, /* ID: 543, type: bool, name: SEM_SERV222_6_FORWARD */ + 1, /* ID: 544, type: enum, name: saveImagesNode */ + 1, /* ID: 545, type: uint, name: saveImagesCnt */ + 1, /* ID: 546, type: enum, name: SaveImages_pSaveTarget */ + 1, /* ID: 547, type: uchar, name: SaveImages_pFbfInit */ + 1, /* ID: 548, type: uchar, name: SaveImages_pFbfEnd */ + 1, /* ID: 549, type: enum, name: acqFullDropNode */ + 1, /* ID: 550, type: uint, name: acqFullDropCnt */ + 1, /* ID: 551, type: uint, name: AcqFullDrop_pExpTime */ + 1, /* ID: 552, type: uint, name: AcqFullDrop_pImageRep */ + 1, /* ID: 553, type: uint, name: acqFullDropT1 */ + 1, /* ID: 554, type: uint, name: acqFullDropT2 */ + 1, /* ID: 555, type: enum, name: calFullSnapNode */ + 1, /* ID: 556, type: uint, name: calFullSnapCnt */ + 1, /* ID: 557, type: uint, name: CalFullSnap_pExpTime */ + 1, /* ID: 558, type: uint, name: CalFullSnap_pImageRep */ + 1, /* ID: 559, type: uint, name: CalFullSnap_pNmbImages */ + 1, /* ID: 560, type: enum, name: CalFullSnap_pCentSel */ + 1, /* ID: 561, type: uint, name: calFullSnapT1 */ + 1, /* ID: 562, type: uint, name: calFullSnapT2 */ + 1, /* ID: 563, type: enum, name: SciWinNode */ + 1, /* ID: 564, type: uint, name: SciWinCnt */ + 1, /* ID: 565, type: uint, name: SciWin_pNmbImages */ + 1, /* ID: 566, type: enum, name: SciWin_pCcdRdMode */ + 1, /* ID: 567, type: uint, name: SciWin_pExpTime */ + 1, /* ID: 568, type: uint, name: SciWin_pImageRep */ + 1, /* ID: 569, type: ushort, name: SciWin_pWinPosX */ + 1, /* ID: 570, type: ushort, name: SciWin_pWinPosY */ + 1, /* ID: 571, type: ushort, name: SciWin_pWinSizeX */ + 1, /* ID: 572, type: ushort, name: SciWin_pWinSizeY */ + 1, /* ID: 573, type: enum, name: SciWin_pCentSel */ + 1, /* ID: 574, type: uint, name: sciWinT1 */ + 1, /* ID: 575, type: uint, name: sciWinT2 */ + 1, /* ID: 576, type: enum, name: fbfLoadNode */ + 1, /* ID: 577, type: uint, name: fbfLoadCnt */ + 1, /* ID: 578, type: enum, name: fbfSaveNode */ + 1, /* ID: 579, type: uint, name: fbfSaveCnt */ + 1, /* ID: 580, type: uchar, name: FbfLoad_pFbfId */ + 1, /* ID: 581, type: uchar, name: FbfLoad_pFbfNBlocks */ + 1, /* ID: 582, type: ushort, name: FbfLoad_pFbfRamAreaId */ + 1, /* ID: 583, type: uint, name: FbfLoad_pFbfRamAddr */ + 1, /* ID: 584, type: uchar, name: FbfSave_pFbfId */ + 1, /* ID: 585, type: uchar, name: FbfSave_pFbfNBlocks */ + 1, /* ID: 586, type: ushort, name: FbfSave_pFbfRamAreaId */ + 1, /* ID: 587, type: uint, name: FbfSave_pFbfRamAddr */ + 1, /* ID: 588, type: uchar, name: fbfLoadBlockCounter */ + 1, /* ID: 589, type: uchar, name: fbfSaveBlockCounter */ + 1, /* ID: 590, type: enum, name: transFbfToGrndNode */ + 1, /* ID: 591, type: uint, name: transFbfToGrndCnt */ + 1, /* ID: 592, type: uchar, name: TransFbfToGrnd_pNmbFbf */ + 1, /* ID: 593, type: uchar, name: TransFbfToGrnd_pFbfInit */ + 1, /* ID: 594, type: uchar, name: TransFbfToGrnd_pFbfSize */ + 1, /* ID: 595, type: enum, name: nomSciNode */ + 1, /* ID: 596, type: uint, name: nomSciCnt */ + 1, /* ID: 597, type: bool, name: NomSci_pAcqFlag */ + 1, /* ID: 598, type: bool, name: NomSci_pCal1Flag */ + 1, /* ID: 599, type: bool, name: NomSci_pSciFlag */ + 1, /* ID: 600, type: bool, name: NomSci_pCal2Flag */ + 1, /* ID: 601, type: uchar, name: NomSci_pCibNFull */ + 1, /* ID: 602, type: ushort, name: NomSci_pCibSizeFull */ + 1, /* ID: 603, type: uchar, name: NomSci_pSibNFull */ + 1, /* ID: 604, type: ushort, name: NomSci_pSibSizeFull */ + 1, /* ID: 605, type: uchar, name: NomSci_pGibNFull */ + 1, /* ID: 606, type: ushort, name: NomSci_pGibSizeFull */ + 1, /* ID: 607, type: uchar, name: NomSci_pSibNWin */ + 1, /* ID: 608, type: ushort, name: NomSci_pSibSizeWin */ + 1, /* ID: 609, type: uchar, name: NomSci_pCibNWin */ + 1, /* ID: 610, type: ushort, name: NomSci_pCibSizeWin */ + 1, /* ID: 611, type: uchar, name: NomSci_pGibNWin */ + 1, /* ID: 612, type: ushort, name: NomSci_pGibSizeWin */ + 1, /* ID: 613, type: uint, name: NomSci_pExpTimeAcq */ + 1, /* ID: 614, type: uint, name: NomSci_pImageRepAcq */ + 1, /* ID: 615, type: uint, name: NomSci_pExpTimeCal1 */ + 1, /* ID: 616, type: uint, name: NomSci_pImageRepCal1 */ + 1, /* ID: 617, type: uint, name: NomSci_pNmbImagesCal1 */ + 1, /* ID: 618, type: enum, name: NomSci_pCentSelCal1 */ + 1, /* ID: 619, type: uint, name: NomSci_pNmbImagesSci */ + 1, /* ID: 620, type: enum, name: NomSci_pCcdRdModeSci */ + 1, /* ID: 621, type: uint, name: NomSci_pExpTimeSci */ + 1, /* ID: 622, type: uint, name: NomSci_pImageRepSci */ + 1, /* ID: 623, type: ushort, name: NomSci_pWinPosXSci */ + 1, /* ID: 624, type: ushort, name: NomSci_pWinPosYSci */ + 1, /* ID: 625, type: ushort, name: NomSci_pWinSizeXSci */ + 1, /* ID: 626, type: ushort, name: NomSci_pWinSizeYSci */ + 1, /* ID: 627, type: enum, name: NomSci_pCentSelSci */ + 1, /* ID: 628, type: uint, name: NomSci_pExpTimeCal2 */ + 1, /* ID: 629, type: uint, name: NomSci_pImageRepCal2 */ + 1, /* ID: 630, type: uint, name: NomSci_pNmbImagesCal2 */ + 1, /* ID: 631, type: enum, name: NomSci_pCentSelCal2 */ + 1, /* ID: 632, type: enum, name: NomSci_pSaveTarget */ + 1, /* ID: 633, type: uchar, name: NomSci_pFbfInit */ + 1, /* ID: 634, type: uchar, name: NomSci_pFbfEnd */ + 1, /* ID: 635, type: ushort, name: NomSci_pStckOrderCal1 */ + 1, /* ID: 636, type: ushort, name: NomSci_pStckOrderSci */ + 1, /* ID: 637, type: ushort, name: NomSci_pStckOrderCal2 */ + 1, /* ID: 638, type: enum, name: ConfigSdb_pSdbCmd */ + 1, /* ID: 639, type: uchar, name: ConfigSdb_pCibNFull */ + 1, /* ID: 640, type: ushort, name: ConfigSdb_pCibSizeFull */ + 1, /* ID: 641, type: uchar, name: ConfigSdb_pSibNFull */ + 1, /* ID: 642, type: ushort, name: ConfigSdb_pSibSizeFull */ + 1, /* ID: 643, type: uchar, name: ConfigSdb_pGibNFull */ + 1, /* ID: 644, type: ushort, name: ConfigSdb_pGibSizeFull */ + 1, /* ID: 645, type: uchar, name: ConfigSdb_pSibNWin */ + 1, /* ID: 646, type: ushort, name: ConfigSdb_pSibSizeWin */ + 1, /* ID: 647, type: uchar, name: ConfigSdb_pCibNWin */ + 1, /* ID: 648, type: ushort, name: ConfigSdb_pCibSizeWin */ + 1, /* ID: 649, type: uchar, name: ConfigSdb_pGibNWin */ + 1, /* ID: 650, type: ushort, name: ConfigSdb_pGibSizeWin */ + 1, /* ID: 651, type: float, name: ADC_P3V3 */ + 1, /* ID: 652, type: float, name: ADC_P5V */ + 1, /* ID: 653, type: float, name: ADC_P1V8 */ + 1, /* ID: 654, type: float, name: ADC_P2V5 */ + 1, /* ID: 655, type: float, name: ADC_N5V */ + 1, /* ID: 656, type: float, name: ADC_PGND */ + 1, /* ID: 657, type: float, name: ADC_TEMPOH1A */ + 1, /* ID: 658, type: float, name: ADC_TEMP1 */ + 1, /* ID: 659, type: float, name: ADC_TEMPOH2A */ + 1, /* ID: 660, type: float, name: ADC_TEMPOH1B */ + 1, /* ID: 661, type: float, name: ADC_TEMPOH3A */ + 1, /* ID: 662, type: float, name: ADC_TEMPOH2B */ + 1, /* ID: 663, type: float, name: ADC_TEMPOH4A */ + 1, /* ID: 664, type: float, name: ADC_TEMPOH3B */ + 1, /* ID: 665, type: float, name: ADC_TEMPOH4B */ + 1, /* ID: 666, type: float, name: SEM_P15V */ + 1, /* ID: 667, type: float, name: SEM_P30V */ + 1, /* ID: 668, type: float, name: SEM_P5V0 */ + 1, /* ID: 669, type: float, name: SEM_P7V0 */ + 1, /* ID: 670, type: float, name: SEM_N5V0 */ + 1, /* ID: 671, type: short, name: ADC_P3V3_RAW */ + 1, /* ID: 672, type: short, name: ADC_P5V_RAW */ + 1, /* ID: 673, type: short, name: ADC_P1V8_RAW */ + 1, /* ID: 674, type: short, name: ADC_P2V5_RAW */ + 1, /* ID: 675, type: short, name: ADC_N5V_RAW */ + 1, /* ID: 676, type: short, name: ADC_PGND_RAW */ + 1, /* ID: 677, type: short, name: ADC_TEMPOH1A_RAW */ + 1, /* ID: 678, type: short, name: ADC_TEMP1_RAW */ + 1, /* ID: 679, type: short, name: ADC_TEMPOH2A_RAW */ + 1, /* ID: 680, type: short, name: ADC_TEMPOH1B_RAW */ + 1, /* ID: 681, type: short, name: ADC_TEMPOH3A_RAW */ + 1, /* ID: 682, type: short, name: ADC_TEMPOH2B_RAW */ + 1, /* ID: 683, type: short, name: ADC_TEMPOH4A_RAW */ + 1, /* ID: 684, type: short, name: ADC_TEMPOH3B_RAW */ + 1, /* ID: 685, type: short, name: ADC_TEMPOH4B_RAW */ + 1, /* ID: 686, type: short, name: SEM_P15V_RAW */ + 1, /* ID: 687, type: short, name: SEM_P30V_RAW */ + 1, /* ID: 688, type: short, name: SEM_P5V0_RAW */ + 1, /* ID: 689, type: short, name: SEM_P7V0_RAW */ + 1, /* ID: 690, type: short, name: SEM_N5V0_RAW */ + 1, /* ID: 691, type: float, name: ADC_P3V3_U */ + 1, /* ID: 692, type: float, name: ADC_P5V_U */ + 1, /* ID: 693, type: float, name: ADC_P1V8_U */ + 1, /* ID: 694, type: float, name: ADC_P2V5_U */ + 1, /* ID: 695, type: float, name: ADC_N5V_L */ + 1, /* ID: 696, type: float, name: ADC_PGND_U */ + 1, /* ID: 697, type: float, name: ADC_PGND_L */ + 1, /* ID: 698, type: float, name: ADC_TEMPOH1A_U */ + 1, /* ID: 699, type: float, name: ADC_TEMP1_U */ + 1, /* ID: 700, type: float, name: ADC_TEMPOH2A_U */ + 1, /* ID: 701, type: float, name: ADC_TEMPOH1B_U */ + 1, /* ID: 702, type: float, name: ADC_TEMPOH3A_U */ + 1, /* ID: 703, type: float, name: ADC_TEMPOH2B_U */ + 1, /* ID: 704, type: float, name: ADC_TEMPOH4A_U */ + 1, /* ID: 705, type: float, name: ADC_TEMPOH3B_U */ + 1, /* ID: 706, type: float, name: ADC_TEMPOH4B_U */ + 1, /* ID: 707, type: float, name: SEM_P15V_U */ + 1, /* ID: 708, type: float, name: SEM_P30V_U */ + 1, /* ID: 709, type: float, name: SEM_P5V0_U */ + 1, /* ID: 710, type: float, name: SEM_P7V0_U */ + 1, /* ID: 711, type: float, name: SEM_N5V0_L */ + 1, /* ID: 712, type: ushort, name: HbSemPassword */ + 1, /* ID: 713, type: uint, name: HbSemCounter */ + 1, /* ID: 714, type: bool, name: isWatchdogEnabled */ + 1, /* ID: 715, type: bool, name: isSynchronized */ + 1, /* ID: 716, type: int, name: missedMsgCnt */ + 1, /* ID: 717, type: int, name: missedPulseCnt */ + 1, /* ID: 718, type: uint, name: milFrameDelay */ + 1, /* ID: 719, type: enum, name: EL1_CHIP */ + 1, /* ID: 720, type: enum, name: EL2_CHIP */ + 1, /* ID: 721, type: uint, name: EL1_ADDR */ + 1, /* ID: 722, type: uint, name: EL2_ADDR */ + 1, /* ID: 723, type: bool, name: ERR_LOG_ENB */ + 1, /* ID: 724, type: bool, name: isErrLogValid */ + 1, /* ID: 725, type: ushort, name: nOfErrLogEntries */ + 1, /* ID: 726, type: uint, name: MAX_SEM_PCKT_CYC */ + 1, /* ID: 727, type: uint, name: FBF_BLCK_WR_DUR */ + 1, /* ID: 728, type: uint, name: FBF_BLCK_RD_DUR */ + 250, /* ID: 729, type: bool, name: isFbfOpen */ + 250, /* ID: 730, type: bool, name: isFbfValid */ + 250, /* ID: 731, type: bool, name: FBF_ENB */ + 250, /* ID: 732, type: enum, name: FBF_CHIP */ + 250, /* ID: 733, type: uint, name: FBF_ADDR */ + 250, /* ID: 734, type: ushort, name: fbfNBlocks */ + 1, /* ID: 735, type: float, name: THR_MA_A_1 */ + 1, /* ID: 736, type: float, name: THR_MA_A_2 */ + 1, /* ID: 737, type: float, name: THR_MA_A_3 */ + 1, /* ID: 738, type: float, name: THR_MA_A_4 */ + 1, /* ID: 739, type: float, name: THR_MA_A_5 */ + 1, /* ID: 740, type: float, name: wcet_1 */ + 1, /* ID: 741, type: float, name: wcet_2 */ + 1, /* ID: 742, type: float, name: wcet_3 */ + 1, /* ID: 743, type: float, name: wcet_4 */ + 1, /* ID: 744, type: float, name: wcet_5 */ + 1, /* ID: 745, type: float, name: wcetAver_1 */ + 1, /* ID: 746, type: float, name: wcetAver_2 */ + 1, /* ID: 747, type: float, name: wcetAver_3 */ + 1, /* ID: 748, type: float, name: wcetAver_4 */ + 1, /* ID: 749, type: float, name: wcetAver_5 */ + 1, /* ID: 750, type: float, name: wcetMax_1 */ + 1, /* ID: 751, type: float, name: wcetMax_2 */ + 1, /* ID: 752, type: float, name: wcetMax_3 */ + 1, /* ID: 753, type: float, name: wcetMax_4 */ + 1, /* ID: 754, type: float, name: wcetMax_5 */ + 1, /* ID: 755, type: uint, name: nOfNotif_1 */ + 1, /* ID: 756, type: uint, name: nOfNotif_2 */ + 1, /* ID: 757, type: uint, name: nOfNotif_3 */ + 1, /* ID: 758, type: uint, name: nOfNotif_4 */ + 1, /* ID: 759, type: uint, name: nOfNotif_5 */ + 1, /* ID: 760, type: uint, name: nofFuncExec_1 */ + 1, /* ID: 761, type: uint, name: nofFuncExec_2 */ + 1, /* ID: 762, type: uint, name: nofFuncExec_3 */ + 1, /* ID: 763, type: uint, name: nofFuncExec_4 */ + 1, /* ID: 764, type: uint, name: nofFuncExec_5 */ + 1, /* ID: 765, type: ushort, name: wcetTimeStampFine_1 */ + 1, /* ID: 766, type: ushort, name: wcetTimeStampFine_2 */ + 1, /* ID: 767, type: ushort, name: wcetTimeStampFine_3 */ + 1, /* ID: 768, type: ushort, name: wcetTimeStampFine_4 */ + 1, /* ID: 769, type: ushort, name: wcetTimeStampFine_5 */ + 1, /* ID: 770, type: uint, name: wcetTimeStampCoarse_1 */ + 1, /* ID: 771, type: uint, name: wcetTimeStampCoarse_2 */ + 1, /* ID: 772, type: uint, name: wcetTimeStampCoarse_3 */ + 1, /* ID: 773, type: uint, name: wcetTimeStampCoarse_4 */ + 1, /* ID: 774, type: uint, name: wcetTimeStampCoarse_5 */ + 1, /* ID: 775, type: uint, name: flashContStepCnt */ + 1, /* ID: 776, type: float, name: OTA_TM1A_NOM */ + 1, /* ID: 777, type: float, name: OTA_TM1A_RED */ + 1, /* ID: 778, type: float, name: OTA_TM1B_NOM */ + 1, /* ID: 779, type: float, name: OTA_TM1B_RED */ + 1, /* ID: 780, type: float, name: OTA_TM2A_NOM */ + 1, /* ID: 781, type: float, name: OTA_TM2A_RED */ + 1, /* ID: 782, type: float, name: OTA_TM2B_NOM */ + 1, /* ID: 783, type: float, name: OTA_TM2B_RED */ + 1, /* ID: 784, type: float, name: OTA_TM3A_NOM */ + 1, /* ID: 785, type: float, name: OTA_TM3A_RED */ + 1, /* ID: 786, type: float, name: OTA_TM3B_NOM */ + 1, /* ID: 787, type: float, name: OTA_TM3B_RED */ + 1, /* ID: 788, type: float, name: OTA_TM4A_NOM */ + 1, /* ID: 789, type: float, name: OTA_TM4A_RED */ + 1, /* ID: 790, type: float, name: OTA_TM4B_NOM */ + 1, /* ID: 791, type: float, name: OTA_TM4B_RED */ + 1, /* ID: 792, type: uchar, name: Core0Load */ + 1, /* ID: 793, type: uchar, name: Core1Load */ + 1, /* ID: 794, type: uint, name: InterruptRate */ + 1, /* ID: 795, type: uchar, name: CyclicalActivitiesCtr */ + 1, /* ID: 796, type: uint, name: Uptime */ + 1, /* ID: 797, type: uchar, name: SemTick */ + 1, /* ID: 798, type: uint, name: SemPwrOnTimestamp */ + 1, /* ID: 799, type: uint, name: SemPwrOffTimestamp */ + 1, /* ID: 800, type: ushort, name: IASW_EVT_CTR */ + 1, /* ID: 801, type: uint, name: BAD_COPY_ID */ + 1, /* ID: 802, type: uint, name: BAD_PASTE_ID */ + 1, /* ID: 803, type: uint, name: ObcInputBufferPackets */ + 1, /* ID: 804, type: uint, name: GrndInputBufferPackets */ + 1, /* ID: 805, type: uint, name: MilBusBytesIn */ + 1, /* ID: 806, type: uint, name: MilBusBytesOut */ + 1, /* ID: 807, type: ushort, name: MilBusDroppedBytes */ + 1, /* ID: 808, type: ushort, name: IRL1 */ + 1, /* ID: 809, type: uchar, name: IRL1_AHBSTAT */ + 1, /* ID: 810, type: uchar, name: IRL1_GRGPIO_6 */ + 1, /* ID: 811, type: uchar, name: IRL1_GRTIMER */ + 1, /* ID: 812, type: uchar, name: IRL1_GPTIMER_0 */ + 1, /* ID: 813, type: uchar, name: IRL1_GPTIMER_1 */ + 1, /* ID: 814, type: uchar, name: IRL1_GPTIMER_2 */ + 1, /* ID: 815, type: uchar, name: IRL1_GPTIMER_3 */ + 1, /* ID: 816, type: uchar, name: IRL1_IRQMP */ + 1, /* ID: 817, type: uchar, name: IRL1_B1553BRM */ + 1, /* ID: 818, type: ushort, name: IRL2 */ + 1, /* ID: 819, type: uchar, name: IRL2_GRSPW2_0 */ + 1, /* ID: 820, type: uchar, name: IRL2_GRSPW2_1 */ + 1, /* ID: 821, type: enum, name: SemRoute */ + 1, /* ID: 822, type: uint, name: SpW0BytesIn */ + 1, /* ID: 823, type: uint, name: SpW0BytesOut */ + 1, /* ID: 824, type: uint, name: SpW1BytesIn */ + 1, /* ID: 825, type: uint, name: SpW1BytesOut */ + 1, /* ID: 826, type: uchar, name: Spw0TxDescAvail */ + 1, /* ID: 827, type: uchar, name: Spw0RxPcktAvail */ + 1, /* ID: 828, type: uchar, name: Spw1TxDescAvail */ + 1, /* ID: 829, type: uchar, name: Spw1RxPcktAvail */ + 1, /* ID: 830, type: uint, name: MilCucCoarseTime */ + 1, /* ID: 831, type: ushort, name: MilCucFineTime */ + 1, /* ID: 832, type: uint, name: CucCoarseTime */ + 1, /* ID: 833, type: ushort, name: CucFineTime */ + 1, /* ID: 834, type: uint, name: Sram1ScrCurrAddr */ + 1, /* ID: 835, type: uint, name: Sram2ScrCurrAddr */ + 1, /* ID: 836, type: ushort, name: Sram1ScrLength */ + 1, /* ID: 837, type: ushort, name: Sram2ScrLength */ + 1, /* ID: 838, type: uchar, name: EdacSingleRepaired */ + 1, /* ID: 839, type: ushort, name: EdacSingleFaults */ + 1, /* ID: 840, type: uint, name: EdacLastSingleFail */ + 1, /* ID: 841, type: uchar, name: EdacDoubleFaults */ + 1, /* ID: 842, type: uint, name: EdacDoubleFAddr */ + 1, /* ID: 843, type: enum, name: Cpu2ProcStatus */ + 1, /* ID: 844, type: uchar, name: HEARTBEAT_ENABLED */ + 1, /* ID: 845, type: uint, name: S1AllocDbs */ + 1, /* ID: 846, type: uint, name: S1AllocSw */ + 1, /* ID: 847, type: uint, name: S1AllocHeap */ + 1, /* ID: 848, type: uint, name: S1AllocFlash */ + 1, /* ID: 849, type: uint, name: S1AllocAux */ + 1, /* ID: 850, type: uint, name: S1AllocRes */ + 1, /* ID: 851, type: uint, name: S1AllocSwap */ + 1, /* ID: 852, type: uint, name: S2AllocSciHeap */ + 1, /* ID: 853, type: enum, name: TaAlgoId */ + 1, /* ID: 854, type: ushort, name: TAACQALGOID */ + 1, /* ID: 855, type: uint, name: TASPARE32 */ + 1, /* ID: 856, type: ushort, name: TaTimingPar1 */ + 1, /* ID: 857, type: ushort, name: TaTimingPar2 */ + 1, /* ID: 858, type: ushort, name: TaDistanceThrd */ + 1, /* ID: 859, type: ushort, name: TaIterations */ + 1, /* ID: 860, type: ushort, name: TaRebinningFact */ + 1, /* ID: 861, type: ushort, name: TaDetectionThrd */ + 1, /* ID: 862, type: ushort, name: TaSeReducedExtr */ + 1, /* ID: 863, type: ushort, name: TaSeReducedRadius */ + 1, /* ID: 864, type: ushort, name: TaSeTolerance */ + 1, /* ID: 865, type: ushort, name: TaMvaTolerance */ + 1, /* ID: 866, type: ushort, name: TaAmaTolerance */ + 1, /* ID: 867, type: ushort, name: TAPOINTUNCERT */ + 1, /* ID: 868, type: uint, name: TATARGETSIG */ + 1, /* ID: 869, type: ushort, name: TANROFSTARS */ + 1, /* ID: 870, type: float, name: TaMaxSigFract */ + 1, /* ID: 871, type: float, name: TaBias */ + 1, /* ID: 872, type: float, name: TaDark */ + 1, /* ID: 873, type: float, name: TaSkyBg */ + 1, /* ID: 874, type: uchar, name: COGBITS */ + 1, /* ID: 875, type: float, name: CENT_MULT_X */ + 1, /* ID: 876, type: float, name: CENT_MULT_Y */ + 1, /* ID: 877, type: float, name: CENT_OFFSET_X */ + 1, /* ID: 878, type: float, name: CENT_OFFSET_Y */ + 1, /* ID: 879, type: uchar, name: CENT_MEDIANFILTER */ + 1, /* ID: 880, type: ushort, name: CENT_DIM_X */ + 1, /* ID: 881, type: ushort, name: CENT_DIM_Y */ + 1, /* ID: 882, type: bool, name: CENT_CHECKS */ + 1, /* ID: 883, type: uint, name: CEN_SIGMALIMIT */ + 1, /* ID: 884, type: uint, name: CEN_SIGNALLIMIT */ + 1, /* ID: 885, type: uint, name: CEN_MEDIAN_THRD */ + 1, /* ID: 886, type: float, name: OPT_AXIS_X */ + 1, /* ID: 887, type: float, name: OPT_AXIS_Y */ + 1, /* ID: 888, type: bool, name: DIST_CORR */ + 1, /* ID: 889, type: uchar, name: pStckOrderSci */ + 1, /* ID: 890, type: ushort, name: pWinSizeXSci */ + 1, /* ID: 891, type: ushort, name: pWinSizeYSci */ + 1, /* ID: 892, type: enum, name: SdpImageAptShape */ + 1, /* ID: 893, type: ushort, name: SdpImageAptX */ + 1, /* ID: 894, type: ushort, name: SdpImageAptY */ + 1, /* ID: 895, type: enum, name: SdpImgttAptShape */ + 1, /* ID: 896, type: ushort, name: SdpImgttAptX */ + 1, /* ID: 897, type: ushort, name: SdpImgttAptY */ + 1, /* ID: 898, type: uchar, name: SdpImgttStckOrder */ + 1, /* ID: 899, type: uchar, name: SdpLosStckOrder */ + 1, /* ID: 900, type: uchar, name: SdpLblkStckOrder */ + 1, /* ID: 901, type: uchar, name: SdpLdkStckOrder */ + 1, /* ID: 902, type: uchar, name: SdpRdkStckOrder */ + 1, /* ID: 903, type: uchar, name: SdpRblkStckOrder */ + 1, /* ID: 904, type: uchar, name: SdpTosStckOrder */ + 1, /* ID: 905, type: uchar, name: SdpTdkStckOrder */ + 1, /* ID: 906, type: enum, name: SdpImgttStrat */ + 1, /* ID: 907, type: float, name: Sdp3StatAmpl */ + 1, /* ID: 908, type: enum, name: SdpPhotStrat */ + 1, /* ID: 909, type: uchar, name: SdpPhotRcent */ + 1, /* ID: 910, type: uchar, name: SdpPhotRann1 */ + 1, /* ID: 911, type: uchar, name: SdpPhotRann2 */ + 1, /* ID: 912, type: uchar, name: SdpCrc */ + 1, /* ID: 913, type: ushort, name: CCPRODUCT */ + 1, /* ID: 914, type: ushort, name: CCSTEP */ + 1, /* ID: 915, type: ushort, name: XIB_FAILURES */ + FEE_SCRIPTS, /* ID: 916, type: uchar, name: FEE_SIDE_A */ + FEE_SCRIPTS, /* ID: 917, type: uchar, name: FEE_SIDE_B */ + 28, /* ID: 918, type: uint, name: NLCBORDERS */ + 28, /* ID: 919, type: float, name: NLCCOEFF_A */ + 28, /* ID: 920, type: float, name: NLCCOEFF_B */ + 28, /* ID: 921, type: float, name: NLCCOEFF_C */ + 28, /* ID: 922, type: float, name: NLCCOEFF_D */ + 1, /* ID: 923, type: ushort, name: SdpGlobalBias */ + 1, /* ID: 924, type: enum, name: BiasOrigin */ + 1, /* ID: 925, type: float, name: SdpGlobalGain */ + 1, /* ID: 926, type: uint, name: SdpWinImageCeKey */ + 1, /* ID: 927, type: uint, name: SdpWinImgttCeKey */ + 1, /* ID: 928, type: uint, name: SdpWinHdrCeKey */ + 1, /* ID: 929, type: uint, name: SdpWinMLOSCeKey */ + 1, /* ID: 930, type: uint, name: SdpWinMLBLKCeKey */ + 1, /* ID: 931, type: uint, name: SdpWinMLDKCeKey */ + 1, /* ID: 932, type: uint, name: SdpWinMRDKCeKey */ + 1, /* ID: 933, type: uint, name: SdpWinMRBLKCeKey */ + 1, /* ID: 934, type: uint, name: SdpWinMTOSCeKey */ + 1, /* ID: 935, type: uint, name: SdpWinMTDKCeKey */ + 1, /* ID: 936, type: uint, name: SdpFullImgCeKey */ + 1, /* ID: 937, type: uint, name: SdpFullHdrCeKey */ + 1, /* ID: 938, type: uint, name: CE_Timetag_crs */ + 1, /* ID: 939, type: ushort, name: CE_Timetag_fine */ + 1, /* ID: 940, type: ushort, name: CE_Counter */ + 1, /* ID: 941, type: ushort, name: CE_Version */ + 1, /* ID: 942, type: uchar, name: CE_Integrity */ + 1, /* ID: 943, type: ushort, name: CE_SemWindowPosX */ + 1, /* ID: 944, type: ushort, name: CE_SemWindowPosY */ + 1, /* ID: 945, type: ushort, name: CE_SemWindowSizeX */ + 1, /* ID: 946, type: ushort, name: CE_SemWindowSizeY */ + 1, /* ID: 947, type: uint, name: SPILL_CTR */ + 1, /* ID: 948, type: uchar, name: RZIP_ITER1 */ + 1, /* ID: 949, type: uchar, name: RZIP_ITER2 */ + 1, /* ID: 950, type: uchar, name: RZIP_ITER3 */ + 1, /* ID: 951, type: uchar, name: RZIP_ITER4 */ + 1, /* ID: 952, type: ushort, name: SdpLdkColMask */ + 1, /* ID: 953, type: ushort, name: SdpRdkColMask */ + 1, /* ID: 954, type: ushort, name: FPGA_Version */ + 1, /* ID: 955, type: ushort, name: FPGA_DPU_Status */ + 1, /* ID: 956, type: ushort, name: FPGA_DPU_Address */ + 1, /* ID: 957, type: ushort, name: FPGA_RESET_Status */ + 1, /* ID: 958, type: ushort, name: FPGA_SEM_Status */ + 1, /* ID: 959, type: ushort, name: FPGA_Oper_Heater_Status */ + 1, /* ID: 960, type: ushort, name: GIBTOTRANSFER */ + 1, /* ID: 961, type: ushort, name: TRANSFERMODE */ + 1, /* ID: 962, type: uint, name: S2TOTRANSFERSIZE */ + 1, /* ID: 963, type: uint, name: S4TOTRANSFERSIZE */ + 1, /* ID: 964, type: uchar, name: TransferComplete */ + 28, /* ID: 965, type: uint, name: NLCBORDERS_2 */ + 28, /* ID: 966, type: float, name: NLCCOEFF_A_2 */ + 28, /* ID: 967, type: float, name: NLCCOEFF_B_2 */ + 28, /* ID: 968, type: float, name: NLCCOEFF_C_2 */ + 12, /* ID: 969, type: uchar, name: RF100 */ + 12, /* ID: 970, type: uchar, name: RF230 */ + 1, /* ID: 971, type: float, name: distc1 */ + 1, /* ID: 972, type: float, name: distc2 */ + 1, /* ID: 973, type: float, name: distc3 */ + 1, /* ID: 974, type: uint, name: SPARE_UI_0 */ + 1, /* ID: 975, type: uint, name: SPARE_UI_1 */ + 1, /* ID: 976, type: uint, name: SPARE_UI_2 */ + 1, /* ID: 977, type: uint, name: SPARE_UI_3 */ + 1, /* ID: 978, type: uint, name: SPARE_UI_4 */ + 1, /* ID: 979, type: uint, name: SPARE_UI_5 */ + 1, /* ID: 980, type: uint, name: SPARE_UI_6 */ + 1, /* ID: 981, type: uint, name: SPARE_UI_7 */ + 1, /* ID: 982, type: uint, name: SPARE_UI_8 */ + 1, /* ID: 983, type: uint, name: SPARE_UI_9 */ + 1, /* ID: 984, type: uint, name: SPARE_UI_10 */ + 1, /* ID: 985, type: uint, name: SPARE_UI_11 */ + 1, /* ID: 986, type: uint, name: SPARE_UI_12 */ + 1, /* ID: 987, type: uint, name: SPARE_UI_13 */ + 1, /* ID: 988, type: uint, name: SPARE_UI_14 */ + 1, /* ID: 989, type: uint, name: SPARE_UI_15 */ + 1, /* ID: 990, type: float, name: SPARE_F_0 */ + 1, /* ID: 991, type: float, name: SPARE_F_1 */ + 1, /* ID: 992, type: float, name: SPARE_F_2 */ + 1, /* ID: 993, type: float, name: SPARE_F_3 */ + 1, /* ID: 994, type: float, name: SPARE_F_4 */ + 1, /* ID: 995, type: float, name: SPARE_F_5 */ + 1, /* ID: 996, type: float, name: SPARE_F_6 */ + 1, /* ID: 997, type: float, name: SPARE_F_7 */ + 1, /* ID: 998, type: float, name: SPARE_F_8 */ + 1, /* ID: 999, type: float, name: SPARE_F_9 */ + 1, /* ID: 1000, type: float, name: SPARE_F_10 */ + 1, /* ID: 1001, type: float, name: SPARE_F_11 */ + 1, /* ID: 1002, type: float, name: SPARE_F_12 */ + 1, /* ID: 1003, type: float, name: SPARE_F_13 */ + 1, /* ID: 1004, type: float, name: SPARE_F_14 */ + 1, /* ID: 1005, type: float, name: SPARE_F_15 */ +}; + + + +#ifdef PC_TARGET +void InitDataPool() +{ + dpCordet = dpCordetInit; + dpIasw = dpIaswInit; + dpIbsw = dpIbswInit; +} + +/* + NOTE: content generated with: + cat src/CrIaDataPool.c | sed -n -e "3092,/1005/p" | sed -e "s/,/);/g" -e "s/\./->/g" -e "s/&/\&(p/g" > mycolumn +*/ +void initDpAddresses (struct DataPoolCordet *pdpCordet, struct DataPoolIasw *pdpIasw, struct DataPoolIbsw *pdpIbsw) +{ + dataPoolAddr[0] = NULL; /* ID: 0, unused */ + dataPoolAddr[1] = (void *)&(pdpIasw->buildNumber); /* ID: 1 */ + dataPoolAddr[2] = (void *)&(pdpCordet->AppErrCode); /* ID: 2 */ + dataPoolAddr[3] = (void *)&(pdpCordet->NofAllocatedInRep); /* ID: 3 */ + dataPoolAddr[4] = (void *)&(pdpCordet->MaxNOfInRep); /* ID: 4 */ + dataPoolAddr[5] = (void *)&(pdpCordet->NofAllocatedInCmd); /* ID: 5 */ + dataPoolAddr[6] = (void *)&(pdpCordet->MaxNOfInCmd); /* ID: 6 */ + dataPoolAddr[7] = (void *)&(pdpCordet->Sem_NOfPendingInCmp); /* ID: 7 */ + dataPoolAddr[8] = (void *)&(pdpCordet->Sem_PCRLSize); /* ID: 8 */ + dataPoolAddr[9] = (void *)&(pdpCordet->Sem_NOfLoadedInCmp); /* ID: 9 */ + dataPoolAddr[10] = (void *)&(pdpCordet->GrdObc_NOfPendingInCmp); /* ID: 10 */ + dataPoolAddr[11] = (void *)&(pdpCordet->GrdObc_PCRLSize); /* ID: 11 */ + dataPoolAddr[12] = (void *)&(pdpCordet->NOfAllocatedOutCmp); /* ID: 12 */ + dataPoolAddr[13] = (void *)&(pdpCordet->MaxNOfOutCmp); /* ID: 13 */ + dataPoolAddr[14] = (void *)&(pdpCordet->NOfInstanceId); /* ID: 14 */ + dataPoolAddr[15] = (void *)&(pdpCordet->OutMg1_NOfPendingOutCmp); /* ID: 15 */ + dataPoolAddr[16] = (void *)&(pdpCordet->OutMg1_POCLSize); /* ID: 16 */ + dataPoolAddr[17] = (void *)&(pdpCordet->OutMg1_NOfLoadedOutCmp); /* ID: 17 */ + dataPoolAddr[18] = (void *)&(pdpCordet->OutMg2_NOfPendingOutCmp); /* ID: 18 */ + dataPoolAddr[19] = (void *)&(pdpCordet->OutMg2_POCLSize); /* ID: 19 */ + dataPoolAddr[20] = (void *)&(pdpCordet->OutMg2_NOfLoadedOutCmp); /* ID: 20 */ + dataPoolAddr[21] = (void *)&(pdpCordet->OutMg3_NOfPendingOutCmp); /* ID: 21 */ + dataPoolAddr[22] = (void *)&(pdpCordet->OutMg3_POCLSize); /* ID: 22 */ + dataPoolAddr[23] = (void *)&(pdpCordet->OutMg3_NOfLoadedOutCmp); /* ID: 23 */ + dataPoolAddr[24] = (void *)&(pdpCordet->InSem_SeqCnt); /* ID: 24 */ + dataPoolAddr[25] = (void *)&(pdpCordet->InSem_NOfPendingPckts); /* ID: 25 */ + dataPoolAddr[26] = (void *)&(pdpCordet->InSem_NOfGroups); /* ID: 26 */ + dataPoolAddr[27] = (void *)&(pdpCordet->InSem_PcktQueueSize); /* ID: 27 */ + dataPoolAddr[28] = (void *)&(pdpCordet->InSem_Src); /* ID: 28 */ + dataPoolAddr[29] = (void *)&(pdpCordet->InObc_NOfPendingPckts); /* ID: 29 */ + dataPoolAddr[30] = (void *)&(pdpCordet->InObc_NOfGroups); /* ID: 30 */ + dataPoolAddr[31] = (void *)&(pdpCordet->InObc_PcktQueueSize); /* ID: 31 */ + dataPoolAddr[32] = (void *)&(pdpCordet->InObc_Src); /* ID: 32 */ + dataPoolAddr[33] = (void *)&(pdpCordet->InGrd_NOfPendingPckts); /* ID: 33 */ + dataPoolAddr[34] = (void *)&(pdpCordet->InGrd_NOfGroups); /* ID: 34 */ + dataPoolAddr[35] = (void *)&(pdpCordet->InGrd_PcktQueueSize); /* ID: 35 */ + dataPoolAddr[36] = (void *)&(pdpCordet->InGrd_Src); /* ID: 36 */ + dataPoolAddr[37] = (void *)&(pdpCordet->OutSem_Dest); /* ID: 37 */ + dataPoolAddr[38] = (void *)&(pdpCordet->OutSem_SeqCnt); /* ID: 38 */ + dataPoolAddr[39] = (void *)&(pdpCordet->OutSem_NOfPendingPckts); /* ID: 39 */ + dataPoolAddr[40] = (void *)&(pdpCordet->OutSem_NOfGroups); /* ID: 40 */ + dataPoolAddr[41] = (void *)&(pdpCordet->OutSem_PcktQueueSize); /* ID: 41 */ + dataPoolAddr[42] = (void *)&(pdpCordet->OutObc_Dest); /* ID: 42 */ + dataPoolAddr[43] = (void *)&(pdpCordet->OutObc_SeqCnt_Group0); /* ID: 43 */ + dataPoolAddr[44] = (void *)&(pdpCordet->OutObc_SeqCnt_Group1); /* ID: 44 */ + dataPoolAddr[45] = (void *)&(pdpCordet->OutObc_NOfPendingPckts); /* ID: 45 */ + dataPoolAddr[46] = (void *)&(pdpCordet->OutObc_NOfGroups); /* ID: 46 */ + dataPoolAddr[47] = (void *)&(pdpCordet->OutObc_PcktQueueSize); /* ID: 47 */ + dataPoolAddr[48] = (void *)&(pdpCordet->OutGrd_Dest); /* ID: 48 */ + dataPoolAddr[49] = (void *)&(pdpCordet->OutGrd_SeqCnt_Group0); /* ID: 49 */ + dataPoolAddr[50] = (void *)&(pdpCordet->OutGrd_SeqCnt_Group1); /* ID: 50 */ + dataPoolAddr[51] = (void *)&(pdpCordet->OutGrd_SeqCnt_Group2); /* ID: 51 */ + dataPoolAddr[52] = (void *)&(pdpCordet->OutGrd_NOfPendingPckts); /* ID: 52 */ + dataPoolAddr[53] = (void *)&(pdpCordet->OutGrd_NOfGroups); /* ID: 53 */ + dataPoolAddr[54] = (void *)&(pdpCordet->OutGrd_PcktQueueSize); /* ID: 54 */ + dataPoolAddr[55] = (void *)&(pdpIasw->sibNFull); /* ID: 55 */ + dataPoolAddr[56] = (void *)&(pdpIasw->cibNFull); /* ID: 56 */ + dataPoolAddr[57] = (void *)&(pdpIasw->gibNFull); /* ID: 57 */ + dataPoolAddr[58] = (void *)&(pdpIasw->sibNWin); /* ID: 58 */ + dataPoolAddr[59] = (void *)&(pdpIasw->cibNWin); /* ID: 59 */ + dataPoolAddr[60] = (void *)&(pdpIasw->gibNWin); /* ID: 60 */ + dataPoolAddr[61] = (void *)&(pdpIasw->sibSizeFull); /* ID: 61 */ + dataPoolAddr[62] = (void *)&(pdpIasw->cibSizeFull); /* ID: 62 */ + dataPoolAddr[63] = (void *)&(pdpIasw->gibSizeFull); /* ID: 63 */ + dataPoolAddr[64] = (void *)&(pdpIasw->sibSizeWin); /* ID: 64 */ + dataPoolAddr[65] = (void *)&(pdpIasw->cibSizeWin); /* ID: 65 */ + dataPoolAddr[66] = (void *)&(pdpIasw->gibSizeWin); /* ID: 66 */ + dataPoolAddr[67] = (void *)&(pdpIasw->sibIn); /* ID: 67 */ + dataPoolAddr[68] = (void *)&(pdpIasw->sibOut); /* ID: 68 */ + dataPoolAddr[69] = (void *)&(pdpIasw->cibIn); /* ID: 69 */ + dataPoolAddr[70] = (void *)&(pdpIasw->gibIn); /* ID: 70 */ + dataPoolAddr[71] = (void *)&(pdpIasw->gibOut); /* ID: 71 */ + dataPoolAddr[72] = (void *)&(pdpIasw->sdbState); /* ID: 72 */ + dataPoolAddr[73] = (void *)&(pdpIasw->sdbStateCnt); /* ID: 73 */ + dataPoolAddr[74] = (void *)&(pdpIasw->OffsetX); /* ID: 74 */ + dataPoolAddr[75] = (void *)&(pdpIasw->OffsetY); /* ID: 75 */ + dataPoolAddr[76] = (void *)&(pdpIasw->TargetLocationX); /* ID: 76 */ + dataPoolAddr[77] = (void *)&(pdpIasw->TargetLocationY); /* ID: 77 */ + dataPoolAddr[78] = (void *)&(pdpIasw->IntegStartTimeCrs); /* ID: 78 */ + dataPoolAddr[79] = (void *)&(pdpIasw->IntegStartTimeFine); /* ID: 79 */ + dataPoolAddr[80] = (void *)&(pdpIasw->IntegEndTimeCrs); /* ID: 80 */ + dataPoolAddr[81] = (void *)&(pdpIasw->IntegEndTimeFine); /* ID: 81 */ + dataPoolAddr[82] = (void *)&(pdpIasw->DataCadence); /* ID: 82 */ + dataPoolAddr[83] = (void *)&(pdpIasw->ValidityStatus); /* ID: 83 */ + dataPoolAddr[84] = (void *)&(pdpIasw->NOfTcAcc); /* ID: 84 */ + dataPoolAddr[85] = (void *)&(pdpIasw->NOfAccFailedTc); /* ID: 85 */ + dataPoolAddr[86] = (void *)&(pdpIasw->SeqCntLastAccTcFromObc); /* ID: 86 */ + dataPoolAddr[87] = (void *)&(pdpIasw->SeqCntLastAccTcFromGrd); /* ID: 87 */ + dataPoolAddr[88] = (void *)&(pdpIasw->SeqCntLastAccFailTc); /* ID: 88 */ + dataPoolAddr[89] = (void *)&(pdpIasw->NOfStartFailedTc); /* ID: 89 */ + dataPoolAddr[90] = (void *)&(pdpIasw->SeqCntLastStartFailTc); /* ID: 90 */ + dataPoolAddr[91] = (void *)&(pdpIasw->NOfTcTerm); /* ID: 91 */ + dataPoolAddr[92] = (void *)&(pdpIasw->NOfTermFailedTc); /* ID: 92 */ + dataPoolAddr[93] = (void *)&(pdpIasw->SeqCntLastTermFailTc); /* ID: 93 */ + dataPoolAddr[94] = (void *)&(pdpIasw->RdlSidList); /* ID: 94 */ + dataPoolAddr[95] = (void *)&(pdpIasw->isRdlFree); /* ID: 95 */ + dataPoolAddr[96] = (void *)&(pdpIasw->RdlCycCntList); /* ID: 96 */ + dataPoolAddr[97] = (void *)&(pdpIasw->RdlPeriodList); /* ID: 97 */ + dataPoolAddr[98] = (void *)&(pdpIasw->RdlEnabledList); /* ID: 98 */ + dataPoolAddr[99] = (void *)&(pdpIasw->RdlDestList); /* ID: 99 */ + dataPoolAddr[100] = (void *)&(pdpIasw->RdlDataItemList_0); /* ID: 100 */ + dataPoolAddr[101] = (void *)&(pdpIasw->RdlDataItemList_1); /* ID: 101 */ + dataPoolAddr[102] = (void *)&(pdpIasw->RdlDataItemList_2); /* ID: 102 */ + dataPoolAddr[103] = (void *)&(pdpIasw->RdlDataItemList_3); /* ID: 103 */ + dataPoolAddr[104] = (void *)&(pdpIasw->RdlDataItemList_4); /* ID: 104 */ + dataPoolAddr[105] = (void *)&(pdpIasw->RdlDataItemList_5); /* ID: 105 */ + dataPoolAddr[106] = (void *)&(pdpIasw->RdlDataItemList_6); /* ID: 106 */ + dataPoolAddr[107] = (void *)&(pdpIasw->RdlDataItemList_7); /* ID: 107 */ + dataPoolAddr[108] = (void *)&(pdpIasw->RdlDataItemList_8); /* ID: 108 */ + dataPoolAddr[109] = (void *)&(pdpIasw->RdlDataItemList_9); /* ID: 109 */ + dataPoolAddr[110] = (void *)&(pdpIasw->DEBUG_VAR); /* ID: 110 */ + dataPoolAddr[111] = (void *)&(pdpIasw->DEBUG_VAR_ADDR); /* ID: 111 */ + dataPoolAddr[112] = (void *)&(pdpIasw->EVTFILTERDEF); /* ID: 112 */ + dataPoolAddr[113] = (void *)&(pdpIasw->evtEnabledList); /* ID: 113 */ + dataPoolAddr[114] = (void *)&(pdpIasw->lastPatchedAddr); /* ID: 114 */ + dataPoolAddr[115] = (void *)&(pdpIasw->lastDumpAddr); /* ID: 115 */ + dataPoolAddr[116] = (void *)&(pdpIasw->sdu2State); /* ID: 116 */ + dataPoolAddr[117] = (void *)&(pdpIasw->sdu4State); /* ID: 117 */ + dataPoolAddr[118] = (void *)&(pdpIasw->sdu2StateCnt); /* ID: 118 */ + dataPoolAddr[119] = (void *)&(pdpIasw->sdu4StateCnt); /* ID: 119 */ + dataPoolAddr[120] = (void *)&(pdpIasw->sdu2BlockCnt); /* ID: 120 */ + dataPoolAddr[121] = (void *)&(pdpIasw->sdu4BlockCnt); /* ID: 121 */ + dataPoolAddr[122] = (void *)&(pdpIasw->sdu2RemSize); /* ID: 122 */ + dataPoolAddr[123] = (void *)&(pdpIasw->sdu4RemSize); /* ID: 123 */ + dataPoolAddr[124] = (void *)&(pdpIasw->sdu2DownTransferSize); /* ID: 124 */ + dataPoolAddr[125] = (void *)&(pdpIasw->sdu4DownTransferSize); /* ID: 125 */ + dataPoolAddr[126] = (void *)&(pdpIasw->sdsCounter); /* ID: 126 */ + dataPoolAddr[127] = (void *)&(pdpIasw->FdGlbEnable); /* ID: 127 */ + dataPoolAddr[128] = (void *)&(pdpIasw->RpGlbEnable); /* ID: 128 */ + dataPoolAddr[129] = (void *)&(pdpIasw->FdCheckTTMState); /* ID: 129 */ + dataPoolAddr[130] = (void *)&(pdpIasw->FdCheckTTMIntEn); /* ID: 130 */ + dataPoolAddr[131] = (void *)&(pdpIasw->FdCheckTTMExtEn); /* ID: 131 */ + dataPoolAddr[132] = (void *)&(pdpIasw->RpTTMIntEn); /* ID: 132 */ + dataPoolAddr[133] = (void *)&(pdpIasw->RpTTMExtEn); /* ID: 133 */ + dataPoolAddr[134] = (void *)&(pdpIasw->FdCheckTTMCnt); /* ID: 134 */ + dataPoolAddr[135] = (void *)&(pdpIasw->FdCheckTTMSpCnt); /* ID: 135 */ + dataPoolAddr[136] = (void *)&(pdpIasw->FdCheckTTMCntThr); /* ID: 136 */ + dataPoolAddr[137] = (void *)&(pdpIasw->TTC_LL); /* ID: 137 */ + dataPoolAddr[138] = (void *)&(pdpIasw->TTC_UL); /* ID: 138 */ + dataPoolAddr[139] = (void *)&(pdpIasw->TTM_LIM); /* ID: 139 */ + dataPoolAddr[140] = (void *)&(pdpIasw->FdCheckSDSCState); /* ID: 140 */ + dataPoolAddr[141] = (void *)&(pdpIasw->FdCheckSDSCIntEn); /* ID: 141 */ + dataPoolAddr[142] = (void *)&(pdpIasw->FdCheckSDSCExtEn); /* ID: 142 */ + dataPoolAddr[143] = (void *)&(pdpIasw->RpSDSCIntEn); /* ID: 143 */ + dataPoolAddr[144] = (void *)&(pdpIasw->RpSDSCExtEn); /* ID: 144 */ + dataPoolAddr[145] = (void *)&(pdpIasw->FdCheckSDSCCnt); /* ID: 145 */ + dataPoolAddr[146] = (void *)&(pdpIasw->FdCheckSDSCSpCnt); /* ID: 146 */ + dataPoolAddr[147] = (void *)&(pdpIasw->FdCheckSDSCCntThr); /* ID: 147 */ + dataPoolAddr[148] = (void *)&(pdpIasw->FdCheckComErrState); /* ID: 148 */ + dataPoolAddr[149] = (void *)&(pdpIasw->FdCheckComErrIntEn); /* ID: 149 */ + dataPoolAddr[150] = (void *)&(pdpIasw->FdCheckComErrExtEn); /* ID: 150 */ + dataPoolAddr[151] = (void *)&(pdpIasw->RpComErrIntEn); /* ID: 151 */ + dataPoolAddr[152] = (void *)&(pdpIasw->RpComErrExtEn); /* ID: 152 */ + dataPoolAddr[153] = (void *)&(pdpIasw->FdCheckComErrCnt); /* ID: 153 */ + dataPoolAddr[154] = (void *)&(pdpIasw->FdCheckComErrSpCnt); /* ID: 154 */ + dataPoolAddr[155] = (void *)&(pdpIasw->FdCheckComErrCntThr); /* ID: 155 */ + dataPoolAddr[156] = (void *)&(pdpIasw->FdCheckTimeOutState); /* ID: 156 */ + dataPoolAddr[157] = (void *)&(pdpIasw->FdCheckTimeOutIntEn); /* ID: 157 */ + dataPoolAddr[158] = (void *)&(pdpIasw->FdCheckTimeOutExtEn); /* ID: 158 */ + dataPoolAddr[159] = (void *)&(pdpIasw->RpTimeOutIntEn); /* ID: 159 */ + dataPoolAddr[160] = (void *)&(pdpIasw->RpTimeOutExtEn); /* ID: 160 */ + dataPoolAddr[161] = (void *)&(pdpIasw->FdCheckTimeOutCnt); /* ID: 161 */ + dataPoolAddr[162] = (void *)&(pdpIasw->FdCheckTimeOutSpCnt); /* ID: 162 */ + dataPoolAddr[163] = (void *)&(pdpIasw->FdCheckTimeOutCntThr); /* ID: 163 */ + dataPoolAddr[164] = (void *)&(pdpIasw->SEM_TO_POWERON); /* ID: 164 */ + dataPoolAddr[165] = (void *)&(pdpIasw->SEM_TO_SAFE); /* ID: 165 */ + dataPoolAddr[166] = (void *)&(pdpIasw->SEM_TO_STAB); /* ID: 166 */ + dataPoolAddr[167] = (void *)&(pdpIasw->SEM_TO_TEMP); /* ID: 167 */ + dataPoolAddr[168] = (void *)&(pdpIasw->SEM_TO_CCD); /* ID: 168 */ + dataPoolAddr[169] = (void *)&(pdpIasw->SEM_TO_DIAG); /* ID: 169 */ + dataPoolAddr[170] = (void *)&(pdpIasw->SEM_TO_STANDBY); /* ID: 170 */ + dataPoolAddr[171] = (void *)&(pdpIasw->FdCheckSafeModeState); /* ID: 171 */ + dataPoolAddr[172] = (void *)&(pdpIasw->FdCheckSafeModeIntEn); /* ID: 172 */ + dataPoolAddr[173] = (void *)&(pdpIasw->FdCheckSafeModeExtEn); /* ID: 173 */ + dataPoolAddr[174] = (void *)&(pdpIasw->RpSafeModeIntEn); /* ID: 174 */ + dataPoolAddr[175] = (void *)&(pdpIasw->RpSafeModeExtEn); /* ID: 175 */ + dataPoolAddr[176] = (void *)&(pdpIasw->FdCheckSafeModeCnt); /* ID: 176 */ + dataPoolAddr[177] = (void *)&(pdpIasw->FdCheckSafeModeSpCnt); /* ID: 177 */ + dataPoolAddr[178] = (void *)&(pdpIasw->FdCheckSafeModeCntThr); /* ID: 178 */ + dataPoolAddr[179] = (void *)&(pdpIasw->FdCheckAliveState); /* ID: 179 */ + dataPoolAddr[180] = (void *)&(pdpIasw->FdCheckAliveIntEn); /* ID: 180 */ + dataPoolAddr[181] = (void *)&(pdpIasw->FdCheckAliveExtEn); /* ID: 181 */ + dataPoolAddr[182] = (void *)&(pdpIasw->RpAliveIntEn); /* ID: 182 */ + dataPoolAddr[183] = (void *)&(pdpIasw->RpAliveExtEn); /* ID: 183 */ + dataPoolAddr[184] = (void *)&(pdpIasw->FdCheckAliveCnt); /* ID: 184 */ + dataPoolAddr[185] = (void *)&(pdpIasw->FdCheckAliveSpCnt); /* ID: 185 */ + dataPoolAddr[186] = (void *)&(pdpIasw->FdCheckAliveCntThr); /* ID: 186 */ + dataPoolAddr[187] = (void *)&(pdpIasw->SEM_HK_DEF_PER); /* ID: 187 */ + dataPoolAddr[188] = (void *)&(pdpIasw->SEMALIVE_DELAYEDSEMHK); /* ID: 188 */ + dataPoolAddr[189] = (void *)&(pdpIasw->FdCheckSemAnoEvtState); /* ID: 189 */ + dataPoolAddr[190] = (void *)&(pdpIasw->FdCheckSemAnoEvtIntEn); /* ID: 190 */ + dataPoolAddr[191] = (void *)&(pdpIasw->FdCheckSemAnoEvtExtEn); /* ID: 191 */ + dataPoolAddr[192] = (void *)&(pdpIasw->RpSemAnoEvtIntEn); /* ID: 192 */ + dataPoolAddr[193] = (void *)&(pdpIasw->RpSemAnoEvtExtEn); /* ID: 193 */ + dataPoolAddr[194] = (void *)&(pdpIasw->FdCheckSemAnoEvtCnt); /* ID: 194 */ + dataPoolAddr[195] = (void *)&(pdpIasw->FdCheckSemAnoEvtSpCnt); /* ID: 195 */ + dataPoolAddr[196] = (void *)&(pdpIasw->FdCheckSemAnoEvtCntThr); /* ID: 196 */ + dataPoolAddr[197] = (void *)&(pdpIasw->semAnoEvtResp_1); /* ID: 197 */ + dataPoolAddr[198] = (void *)&(pdpIasw->semAnoEvtResp_2); /* ID: 198 */ + dataPoolAddr[199] = (void *)&(pdpIasw->semAnoEvtResp_3); /* ID: 199 */ + dataPoolAddr[200] = (void *)&(pdpIasw->semAnoEvtResp_4); /* ID: 200 */ + dataPoolAddr[201] = (void *)&(pdpIasw->semAnoEvtResp_5); /* ID: 201 */ + dataPoolAddr[202] = (void *)&(pdpIasw->semAnoEvtResp_6); /* ID: 202 */ + dataPoolAddr[203] = (void *)&(pdpIasw->semAnoEvtResp_7); /* ID: 203 */ + dataPoolAddr[204] = (void *)&(pdpIasw->semAnoEvtResp_8); /* ID: 204 */ + dataPoolAddr[205] = (void *)&(pdpIasw->semAnoEvtResp_9); /* ID: 205 */ + dataPoolAddr[206] = (void *)&(pdpIasw->semAnoEvtResp_10); /* ID: 206 */ + dataPoolAddr[207] = (void *)&(pdpIasw->semAnoEvtResp_11); /* ID: 207 */ + dataPoolAddr[208] = (void *)&(pdpIasw->semAnoEvtResp_12); /* ID: 208 */ + dataPoolAddr[209] = (void *)&(pdpIasw->semAnoEvtResp_13); /* ID: 209 */ + dataPoolAddr[210] = (void *)&(pdpIasw->semAnoEvtResp_14); /* ID: 210 */ + dataPoolAddr[211] = (void *)&(pdpIasw->semAnoEvtResp_15); /* ID: 211 */ + dataPoolAddr[212] = (void *)&(pdpIasw->semAnoEvtResp_16); /* ID: 212 */ + dataPoolAddr[213] = (void *)&(pdpIasw->semAnoEvtResp_17); /* ID: 213 */ + dataPoolAddr[214] = (void *)&(pdpIasw->semAnoEvtResp_18); /* ID: 214 */ + dataPoolAddr[215] = (void *)&(pdpIasw->semAnoEvtResp_19); /* ID: 215 */ + dataPoolAddr[216] = (void *)&(pdpIasw->semAnoEvtResp_20); /* ID: 216 */ + dataPoolAddr[217] = (void *)&(pdpIasw->semAnoEvtResp_21); /* ID: 217 */ + dataPoolAddr[218] = (void *)&(pdpIasw->semAnoEvtResp_22); /* ID: 218 */ + dataPoolAddr[219] = (void *)&(pdpIasw->semAnoEvtResp_23); /* ID: 219 */ + dataPoolAddr[220] = (void *)&(pdpIasw->semAnoEvtResp_24); /* ID: 220 */ + dataPoolAddr[221] = (void *)&(pdpIasw->semAnoEvtResp_25); /* ID: 221 */ + dataPoolAddr[222] = (void *)&(pdpIasw->semAnoEvtResp_26); /* ID: 222 */ + dataPoolAddr[223] = (void *)&(pdpIasw->semAnoEvtResp_27); /* ID: 223 */ + dataPoolAddr[224] = (void *)&(pdpIasw->semAnoEvtResp_28); /* ID: 224 */ + dataPoolAddr[225] = (void *)&(pdpIasw->semAnoEvtResp_29); /* ID: 225 */ + dataPoolAddr[226] = (void *)&(pdpIasw->FdCheckSemLimitState); /* ID: 226 */ + dataPoolAddr[227] = (void *)&(pdpIasw->FdCheckSemLimitIntEn); /* ID: 227 */ + dataPoolAddr[228] = (void *)&(pdpIasw->FdCheckSemLimitExtEn); /* ID: 228 */ + dataPoolAddr[229] = (void *)&(pdpIasw->RpSemLimitIntEn); /* ID: 229 */ + dataPoolAddr[230] = (void *)&(pdpIasw->RpSemLimitExtEn); /* ID: 230 */ + dataPoolAddr[231] = (void *)&(pdpIasw->FdCheckSemLimitCnt); /* ID: 231 */ + dataPoolAddr[232] = (void *)&(pdpIasw->FdCheckSemLimitSpCnt); /* ID: 232 */ + dataPoolAddr[233] = (void *)&(pdpIasw->FdCheckSemLimitCntThr); /* ID: 233 */ + dataPoolAddr[234] = (void *)&(pdpIasw->SEM_LIM_DEL_T); /* ID: 234 */ + dataPoolAddr[235] = (void *)&(pdpIasw->FdCheckDpuHkState); /* ID: 235 */ + dataPoolAddr[236] = (void *)&(pdpIasw->FdCheckDpuHkIntEn); /* ID: 236 */ + dataPoolAddr[237] = (void *)&(pdpIasw->FdCheckDpuHkExtEn); /* ID: 237 */ + dataPoolAddr[238] = (void *)&(pdpIasw->RpDpuHkIntEn); /* ID: 238 */ + dataPoolAddr[239] = (void *)&(pdpIasw->RpDpuHkExtEn); /* ID: 239 */ + dataPoolAddr[240] = (void *)&(pdpIasw->FdCheckDpuHkCnt); /* ID: 240 */ + dataPoolAddr[241] = (void *)&(pdpIasw->FdCheckDpuHkSpCnt); /* ID: 241 */ + dataPoolAddr[242] = (void *)&(pdpIasw->FdCheckDpuHkCntThr); /* ID: 242 */ + dataPoolAddr[243] = (void *)&(pdpIasw->FdCheckCentConsState); /* ID: 243 */ + dataPoolAddr[244] = (void *)&(pdpIasw->FdCheckCentConsIntEn); /* ID: 244 */ + dataPoolAddr[245] = (void *)&(pdpIasw->FdCheckCentConsExtEn); /* ID: 245 */ + dataPoolAddr[246] = (void *)&(pdpIasw->RpCentConsIntEn); /* ID: 246 */ + dataPoolAddr[247] = (void *)&(pdpIasw->RpCentConsExtEn); /* ID: 247 */ + dataPoolAddr[248] = (void *)&(pdpIasw->FdCheckCentConsCnt); /* ID: 248 */ + dataPoolAddr[249] = (void *)&(pdpIasw->FdCheckCentConsSpCnt); /* ID: 249 */ + dataPoolAddr[250] = (void *)&(pdpIasw->FdCheckCentConsCntThr); /* ID: 250 */ + dataPoolAddr[251] = (void *)&(pdpIasw->FdCheckResState); /* ID: 251 */ + dataPoolAddr[252] = (void *)&(pdpIasw->FdCheckResIntEn); /* ID: 252 */ + dataPoolAddr[253] = (void *)&(pdpIasw->FdCheckResExtEn); /* ID: 253 */ + dataPoolAddr[254] = (void *)&(pdpIasw->RpResIntEn); /* ID: 254 */ + dataPoolAddr[255] = (void *)&(pdpIasw->RpResExtEn); /* ID: 255 */ + dataPoolAddr[256] = (void *)&(pdpIasw->FdCheckResCnt); /* ID: 256 */ + dataPoolAddr[257] = (void *)&(pdpIasw->FdCheckResSpCnt); /* ID: 257 */ + dataPoolAddr[258] = (void *)&(pdpIasw->FdCheckResCntThr); /* ID: 258 */ + dataPoolAddr[259] = (void *)&(pdpIasw->CPU1_USAGE_MAX); /* ID: 259 */ + dataPoolAddr[260] = (void *)&(pdpIasw->MEM_USAGE_MAX); /* ID: 260 */ + dataPoolAddr[261] = (void *)&(pdpIasw->FdCheckSemCons); /* ID: 261 */ + dataPoolAddr[262] = (void *)&(pdpIasw->FdCheckSemConsIntEn); /* ID: 262 */ + dataPoolAddr[263] = (void *)&(pdpIasw->FdCheckSemConsExtEn); /* ID: 263 */ + dataPoolAddr[264] = (void *)&(pdpIasw->RpSemConsIntEn); /* ID: 264 */ + dataPoolAddr[265] = (void *)&(pdpIasw->RpSemConsExtEn); /* ID: 265 */ + dataPoolAddr[266] = (void *)&(pdpIasw->FdCheckSemConsCnt); /* ID: 266 */ + dataPoolAddr[267] = (void *)&(pdpIasw->FdCheckSemConsSpCnt); /* ID: 267 */ + dataPoolAddr[268] = (void *)&(pdpIasw->FdCheckSemConsCntThr); /* ID: 268 */ + dataPoolAddr[269] = (void *)&(pdpIasw->semState); /* ID: 269 */ + dataPoolAddr[270] = (void *)&(pdpIasw->semOperState); /* ID: 270 */ + dataPoolAddr[271] = (void *)&(pdpIasw->semStateCnt); /* ID: 271 */ + dataPoolAddr[272] = (void *)&(pdpIasw->semOperStateCnt); /* ID: 272 */ + dataPoolAddr[273] = (void *)&(pdpIasw->imageCycleCnt); /* ID: 273 */ + dataPoolAddr[274] = (void *)&(pdpIasw->acqImageCnt); /* ID: 274 */ + dataPoolAddr[275] = (void *)&(pdpIasw->sciSubMode); /* ID: 275 */ + dataPoolAddr[276] = (void *)&(pdpIasw->LastSemPckt); /* ID: 276 */ + dataPoolAddr[277] = (void *)&(pdpIasw->SEM_ON_CODE); /* ID: 277 */ + dataPoolAddr[278] = (void *)&(pdpIasw->SEM_OFF_CODE); /* ID: 278 */ + dataPoolAddr[279] = (void *)&(pdpIasw->SEM_INIT_T1); /* ID: 279 */ + dataPoolAddr[280] = (void *)&(pdpIasw->SEM_INIT_T2); /* ID: 280 */ + dataPoolAddr[281] = (void *)&(pdpIasw->SEM_OPER_T1); /* ID: 281 */ + dataPoolAddr[282] = (void *)&(pdpIasw->SEM_SHUTDOWN_T1); /* ID: 282 */ + dataPoolAddr[283] = (void *)&(pdpIasw->SEM_SHUTDOWN_T11); /* ID: 283 */ + dataPoolAddr[284] = (void *)&(pdpIasw->SEM_SHUTDOWN_T12); /* ID: 284 */ + dataPoolAddr[285] = (void *)&(pdpIasw->SEM_SHUTDOWN_T2); /* ID: 285 */ + dataPoolAddr[286] = (void *)&(pdpIasw->iaswState); /* ID: 286 */ + dataPoolAddr[287] = (void *)&(pdpIasw->iaswStateCnt); /* ID: 287 */ + dataPoolAddr[288] = (void *)&(pdpIasw->iaswCycleCnt); /* ID: 288 */ + dataPoolAddr[289] = (void *)&(pdpIasw->prepScienceNode); /* ID: 289 */ + dataPoolAddr[290] = (void *)&(pdpIasw->prepScienceCnt); /* ID: 290 */ + dataPoolAddr[291] = (void *)&(pdpIasw->controlledSwitchOffNode); /* ID: 291 */ + dataPoolAddr[292] = (void *)&(pdpIasw->controlledSwitchOffCnt); /* ID: 292 */ + dataPoolAddr[293] = (void *)&(pdpIasw->CTRLD_SWITCH_OFF_T1); /* ID: 293 */ + dataPoolAddr[294] = (void *)&(pdpIasw->algoCent0State); /* ID: 294 */ + dataPoolAddr[295] = (void *)&(pdpIasw->algoCent0Cnt); /* ID: 295 */ + dataPoolAddr[296] = (void *)&(pdpIasw->algoCent0Enabled); /* ID: 296 */ + dataPoolAddr[297] = (void *)&(pdpIasw->algoCent1State); /* ID: 297 */ + dataPoolAddr[298] = (void *)&(pdpIasw->algoCent1Cnt); /* ID: 298 */ + dataPoolAddr[299] = (void *)&(pdpIasw->algoCent1Enabled); /* ID: 299 */ + dataPoolAddr[300] = (void *)&(pdpIasw->CENT_EXEC_PHASE); /* ID: 300 */ + dataPoolAddr[301] = (void *)&(pdpIasw->algoAcq1State); /* ID: 301 */ + dataPoolAddr[302] = (void *)&(pdpIasw->algoAcq1Cnt); /* ID: 302 */ + dataPoolAddr[303] = (void *)&(pdpIasw->algoAcq1Enabled); /* ID: 303 */ + dataPoolAddr[304] = (void *)&(pdpIasw->ACQ_PH); /* ID: 304 */ + dataPoolAddr[305] = (void *)&(pdpIasw->algoCcState); /* ID: 305 */ + dataPoolAddr[306] = (void *)&(pdpIasw->algoCcCnt); /* ID: 306 */ + dataPoolAddr[307] = (void *)&(pdpIasw->algoCcEnabled); /* ID: 307 */ + dataPoolAddr[308] = (void *)&(pdpIasw->STCK_ORDER); /* ID: 308 */ + dataPoolAddr[309] = (void *)&(pdpIasw->algoTTC1State); /* ID: 309 */ + dataPoolAddr[310] = (void *)&(pdpIasw->algoTTC1Cnt); /* ID: 310 */ + dataPoolAddr[311] = (void *)&(pdpIasw->algoTTC1Enabled); /* ID: 311 */ + dataPoolAddr[312] = (void *)&(pdpIasw->TTC1_EXEC_PHASE); /* ID: 312 */ + dataPoolAddr[313] = (void *)&(pdpIasw->TTC1_EXEC_PER); /* ID: 313 */ + dataPoolAddr[314] = (void *)&(pdpIasw->TTC1_LL_FRT); /* ID: 314 */ + dataPoolAddr[315] = (void *)&(pdpIasw->TTC1_LL_AFT); /* ID: 315 */ + dataPoolAddr[316] = (void *)&(pdpIasw->TTC1_UL_FRT); /* ID: 316 */ + dataPoolAddr[317] = (void *)&(pdpIasw->TTC1_UL_AFT); /* ID: 317 */ + dataPoolAddr[318] = (void *)&(pdpIasw->ttc1AvTempAft); /* ID: 318 */ + dataPoolAddr[319] = (void *)&(pdpIasw->ttc1AvTempFrt); /* ID: 319 */ + dataPoolAddr[320] = (void *)&(pdpIasw->algoTTC2State); /* ID: 320 */ + dataPoolAddr[321] = (void *)&(pdpIasw->algoTTC2Cnt); /* ID: 321 */ + dataPoolAddr[322] = (void *)&(pdpIasw->algoTTC2Enabled); /* ID: 322 */ + dataPoolAddr[323] = (void *)&(pdpIasw->TTC2_EXEC_PER); /* ID: 323 */ + dataPoolAddr[324] = (void *)&(pdpIasw->TTC2_REF_TEMP); /* ID: 324 */ + dataPoolAddr[325] = (void *)&(pdpIasw->TTC2_OFFSETA); /* ID: 325 */ + dataPoolAddr[326] = (void *)&(pdpIasw->TTC2_OFFSETF); /* ID: 326 */ + dataPoolAddr[327] = (void *)&(pdpIasw->intTimeAft); /* ID: 327 */ + dataPoolAddr[328] = (void *)&(pdpIasw->onTimeAft); /* ID: 328 */ + dataPoolAddr[329] = (void *)&(pdpIasw->intTimeFront); /* ID: 329 */ + dataPoolAddr[330] = (void *)&(pdpIasw->onTimeFront); /* ID: 330 */ + dataPoolAddr[331] = (void *)&(pdpIasw->TTC2_PA); /* ID: 331 */ + dataPoolAddr[332] = (void *)&(pdpIasw->TTC2_DA); /* ID: 332 */ + dataPoolAddr[333] = (void *)&(pdpIasw->TTC2_IA); /* ID: 333 */ + dataPoolAddr[334] = (void *)&(pdpIasw->TTC2_PF); /* ID: 334 */ + dataPoolAddr[335] = (void *)&(pdpIasw->TTC2_DF); /* ID: 335 */ + dataPoolAddr[336] = (void *)&(pdpIasw->TTC2_IF); /* ID: 336 */ + dataPoolAddr[337] = (void *)&(pdpIasw->algoSaaEvalState); /* ID: 337 */ + dataPoolAddr[338] = (void *)&(pdpIasw->algoSaaEvalCnt); /* ID: 338 */ + dataPoolAddr[339] = (void *)&(pdpIasw->algoSaaEvalEnabled); /* ID: 339 */ + dataPoolAddr[340] = (void *)&(pdpIasw->SAA_EXEC_PHASE); /* ID: 340 */ + dataPoolAddr[341] = (void *)&(pdpIasw->SAA_EXEC_PER); /* ID: 341 */ + dataPoolAddr[342] = (void *)&(pdpIasw->isSaaActive); /* ID: 342 */ + dataPoolAddr[343] = (void *)&(pdpIasw->saaCounter); /* ID: 343 */ + dataPoolAddr[344] = (void *)&(pdpIasw->pInitSaaCounter); /* ID: 344 */ + dataPoolAddr[345] = (void *)&(pdpIasw->algoSdsEvalState); /* ID: 345 */ + dataPoolAddr[346] = (void *)&(pdpIasw->algoSdsEvalCnt); /* ID: 346 */ + dataPoolAddr[347] = (void *)&(pdpIasw->algoSdsEvalEnabled); /* ID: 347 */ + dataPoolAddr[348] = (void *)&(pdpIasw->SDS_EXEC_PHASE); /* ID: 348 */ + dataPoolAddr[349] = (void *)&(pdpIasw->SDS_EXEC_PER); /* ID: 349 */ + dataPoolAddr[350] = (void *)&(pdpIasw->isSdsActive); /* ID: 350 */ + dataPoolAddr[351] = (void *)&(pdpIasw->SDS_FORCED); /* ID: 351 */ + dataPoolAddr[352] = (void *)&(pdpIasw->SDS_INHIBITED); /* ID: 352 */ + dataPoolAddr[353] = (void *)&(pdpIasw->EARTH_OCCULT_ACTIVE); /* ID: 353 */ + dataPoolAddr[354] = (void *)&(pdpIasw->HEARTBEAT_D1); /* ID: 354 */ + dataPoolAddr[355] = (void *)&(pdpIasw->HEARTBEAT_D2); /* ID: 355 */ + dataPoolAddr[356] = (void *)&(pdpIasw->HbSem); /* ID: 356 */ + dataPoolAddr[357] = (void *)&(pdpIasw->starMap); /* ID: 357 */ + dataPoolAddr[358] = (void *)&(pdpIasw->observationId); /* ID: 358 */ + dataPoolAddr[359] = (void *)&(pdpIasw->centValProcOutput); /* ID: 359 */ + dataPoolAddr[360] = (void *)&(pdpIasw->CENT_OFFSET_LIM); /* ID: 360 */ + dataPoolAddr[361] = (void *)&(pdpIasw->CENT_FROZEN_LIM); /* ID: 361 */ + dataPoolAddr[362] = (void *)&(pdpIasw->SEM_SERV1_1_FORWARD); /* ID: 362 */ + dataPoolAddr[363] = (void *)&(pdpIasw->SEM_SERV1_2_FORWARD); /* ID: 363 */ + dataPoolAddr[364] = (void *)&(pdpIasw->SEM_SERV1_7_FORWARD); /* ID: 364 */ + dataPoolAddr[365] = (void *)&(pdpIasw->SEM_SERV1_8_FORWARD); /* ID: 365 */ + dataPoolAddr[366] = (void *)&(pdpIasw->SEM_SERV3_1_FORWARD); /* ID: 366 */ + dataPoolAddr[367] = (void *)&(pdpIasw->SEM_SERV3_2_FORWARD); /* ID: 367 */ + dataPoolAddr[368] = (void *)&(pdpIasw->SEM_HK_TS_DEF_CRS); /* ID: 368 */ + dataPoolAddr[369] = (void *)&(pdpIasw->SEM_HK_TS_DEF_FINE); /* ID: 369 */ + dataPoolAddr[370] = (void *)&(pdpIasw->SEM_HK_TS_EXT_CRS); /* ID: 370 */ + dataPoolAddr[371] = (void *)&(pdpIasw->SEM_HK_TS_EXT_FINE); /* ID: 371 */ + dataPoolAddr[372] = (void *)&(pdpIasw->STAT_MODE); /* ID: 372 */ + dataPoolAddr[373] = (void *)&(pdpIasw->STAT_FLAGS); /* ID: 373 */ + dataPoolAddr[374] = (void *)&(pdpIasw->STAT_LAST_SPW_ERR); /* ID: 374 */ + dataPoolAddr[375] = (void *)&(pdpIasw->STAT_LAST_ERR_ID); /* ID: 375 */ + dataPoolAddr[376] = (void *)&(pdpIasw->STAT_LAST_ERR_FREQ); /* ID: 376 */ + dataPoolAddr[377] = (void *)&(pdpIasw->STAT_NUM_CMD_RECEIVED); /* ID: 377 */ + dataPoolAddr[378] = (void *)&(pdpIasw->STAT_NUM_CMD_EXECUTED); /* ID: 378 */ + dataPoolAddr[379] = (void *)&(pdpIasw->STAT_NUM_DATA_SENT); /* ID: 379 */ + dataPoolAddr[380] = (void *)&(pdpIasw->STAT_SCU_PROC_DUTY_CL); /* ID: 380 */ + dataPoolAddr[381] = (void *)&(pdpIasw->STAT_SCU_NUM_AHB_ERR); /* ID: 381 */ + dataPoolAddr[382] = (void *)&(pdpIasw->STAT_SCU_NUM_AHB_CERR); /* ID: 382 */ + dataPoolAddr[383] = (void *)&(pdpIasw->STAT_SCU_NUM_LUP_ERR); /* ID: 383 */ + dataPoolAddr[384] = (void *)&(pdpIasw->TEMP_SEM_SCU); /* ID: 384 */ + dataPoolAddr[385] = (void *)&(pdpIasw->TEMP_SEM_PCU); /* ID: 385 */ + dataPoolAddr[386] = (void *)&(pdpIasw->VOLT_SCU_P3_4); /* ID: 386 */ + dataPoolAddr[387] = (void *)&(pdpIasw->VOLT_SCU_P5); /* ID: 387 */ + dataPoolAddr[388] = (void *)&(pdpIasw->TEMP_FEE_CCD); /* ID: 388 */ + dataPoolAddr[389] = (void *)&(pdpIasw->TEMP_FEE_STRAP); /* ID: 389 */ + dataPoolAddr[390] = (void *)&(pdpIasw->TEMP_FEE_ADC); /* ID: 390 */ + dataPoolAddr[391] = (void *)&(pdpIasw->TEMP_FEE_BIAS); /* ID: 391 */ + dataPoolAddr[392] = (void *)&(pdpIasw->TEMP_FEE_DEB); /* ID: 392 */ + dataPoolAddr[393] = (void *)&(pdpIasw->VOLT_FEE_VOD); /* ID: 393 */ + dataPoolAddr[394] = (void *)&(pdpIasw->VOLT_FEE_VRD); /* ID: 394 */ + dataPoolAddr[395] = (void *)&(pdpIasw->VOLT_FEE_VOG); /* ID: 395 */ + dataPoolAddr[396] = (void *)&(pdpIasw->VOLT_FEE_VSS); /* ID: 396 */ + dataPoolAddr[397] = (void *)&(pdpIasw->VOLT_FEE_CCD); /* ID: 397 */ + dataPoolAddr[398] = (void *)&(pdpIasw->VOLT_FEE_CLK); /* ID: 398 */ + dataPoolAddr[399] = (void *)&(pdpIasw->VOLT_FEE_ANA_P5); /* ID: 399 */ + dataPoolAddr[400] = (void *)&(pdpIasw->VOLT_FEE_ANA_N5); /* ID: 400 */ + dataPoolAddr[401] = (void *)&(pdpIasw->VOLT_FEE_ANA_P3_3); /* ID: 401 */ + dataPoolAddr[402] = (void *)&(pdpIasw->CURR_FEE_CLK_BUF); /* ID: 402 */ + dataPoolAddr[403] = (void *)&(pdpIasw->VOLT_SCU_FPGA_P1_5); /* ID: 403 */ + dataPoolAddr[404] = (void *)&(pdpIasw->CURR_SCU_P3_4); /* ID: 404 */ + dataPoolAddr[405] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_CRE); /* ID: 405 */ + dataPoolAddr[406] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_ESC); /* ID: 406 */ + dataPoolAddr[407] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_DISC); /* ID: 407 */ + dataPoolAddr[408] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_PAR); /* ID: 408 */ + dataPoolAddr[409] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_WRSY); /* ID: 409 */ + dataPoolAddr[410] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_INVA); /* ID: 410 */ + dataPoolAddr[411] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_EOP); /* ID: 411 */ + dataPoolAddr[412] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_RXAH); /* ID: 412 */ + dataPoolAddr[413] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_TXAH); /* ID: 413 */ + dataPoolAddr[414] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_TXBL); /* ID: 414 */ + dataPoolAddr[415] = (void *)&(pdpIasw->STAT_NUM_SPW_ERR_TXLE); /* ID: 415 */ + dataPoolAddr[416] = (void *)&(pdpIasw->STAT_NUM_SP_ERR_RX); /* ID: 416 */ + dataPoolAddr[417] = (void *)&(pdpIasw->STAT_NUM_SP_ERR_TX); /* ID: 417 */ + dataPoolAddr[418] = (void *)&(pdpIasw->STAT_HEAT_PWM_FPA_CCD); /* ID: 418 */ + dataPoolAddr[419] = (void *)&(pdpIasw->STAT_HEAT_PWM_FEE_STR); /* ID: 419 */ + dataPoolAddr[420] = (void *)&(pdpIasw->STAT_HEAT_PWM_FEE_ANA); /* ID: 420 */ + dataPoolAddr[421] = (void *)&(pdpIasw->STAT_HEAT_PWM_SPARE); /* ID: 421 */ + dataPoolAddr[422] = (void *)&(pdpIasw->STAT_HEAT_PWM_FLAGS); /* ID: 422 */ + dataPoolAddr[423] = (void *)&(pdpIasw->STAT_OBTIME_SYNC_DELTA); /* ID: 423 */ + dataPoolAddr[424] = (void *)&(pdpIasw->TEMP_SEM_SCU_LW); /* ID: 424 */ + dataPoolAddr[425] = (void *)&(pdpIasw->TEMP_SEM_PCU_LW); /* ID: 425 */ + dataPoolAddr[426] = (void *)&(pdpIasw->VOLT_SCU_P3_4_LW); /* ID: 426 */ + dataPoolAddr[427] = (void *)&(pdpIasw->VOLT_SCU_P5_LW); /* ID: 427 */ + dataPoolAddr[428] = (void *)&(pdpIasw->TEMP_FEE_CCD_LW); /* ID: 428 */ + dataPoolAddr[429] = (void *)&(pdpIasw->TEMP_FEE_STRAP_LW); /* ID: 429 */ + dataPoolAddr[430] = (void *)&(pdpIasw->TEMP_FEE_ADC_LW); /* ID: 430 */ + dataPoolAddr[431] = (void *)&(pdpIasw->TEMP_FEE_BIAS_LW); /* ID: 431 */ + dataPoolAddr[432] = (void *)&(pdpIasw->TEMP_FEE_DEB_LW); /* ID: 432 */ + dataPoolAddr[433] = (void *)&(pdpIasw->VOLT_FEE_VOD_LW); /* ID: 433 */ + dataPoolAddr[434] = (void *)&(pdpIasw->VOLT_FEE_VRD_LW); /* ID: 434 */ + dataPoolAddr[435] = (void *)&(pdpIasw->VOLT_FEE_VOG_LW); /* ID: 435 */ + dataPoolAddr[436] = (void *)&(pdpIasw->VOLT_FEE_VSS_LW); /* ID: 436 */ + dataPoolAddr[437] = (void *)&(pdpIasw->VOLT_FEE_CCD_LW); /* ID: 437 */ + dataPoolAddr[438] = (void *)&(pdpIasw->VOLT_FEE_CLK_LW); /* ID: 438 */ + dataPoolAddr[439] = (void *)&(pdpIasw->VOLT_FEE_ANA_P5_LW); /* ID: 439 */ + dataPoolAddr[440] = (void *)&(pdpIasw->VOLT_FEE_ANA_N5_LW); /* ID: 440 */ + dataPoolAddr[441] = (void *)&(pdpIasw->VOLT_FEE_ANA_P3_3_LW); /* ID: 441 */ + dataPoolAddr[442] = (void *)&(pdpIasw->CURR_FEE_CLK_BUF_LW); /* ID: 442 */ + dataPoolAddr[443] = (void *)&(pdpIasw->VOLT_SCU_FPGA_P1_5_LW); /* ID: 443 */ + dataPoolAddr[444] = (void *)&(pdpIasw->CURR_SCU_P3_4_LW); /* ID: 444 */ + dataPoolAddr[445] = (void *)&(pdpIasw->TEMP_SEM_SCU_UW); /* ID: 445 */ + dataPoolAddr[446] = (void *)&(pdpIasw->TEMP_SEM_PCU_UW); /* ID: 446 */ + dataPoolAddr[447] = (void *)&(pdpIasw->VOLT_SCU_P3_4_UW); /* ID: 447 */ + dataPoolAddr[448] = (void *)&(pdpIasw->VOLT_SCU_P5_UW); /* ID: 448 */ + dataPoolAddr[449] = (void *)&(pdpIasw->TEMP_FEE_CCD_UW); /* ID: 449 */ + dataPoolAddr[450] = (void *)&(pdpIasw->TEMP_FEE_STRAP_UW); /* ID: 450 */ + dataPoolAddr[451] = (void *)&(pdpIasw->TEMP_FEE_ADC_UW); /* ID: 451 */ + dataPoolAddr[452] = (void *)&(pdpIasw->TEMP_FEE_BIAS_UW); /* ID: 452 */ + dataPoolAddr[453] = (void *)&(pdpIasw->TEMP_FEE_DEB_UW); /* ID: 453 */ + dataPoolAddr[454] = (void *)&(pdpIasw->VOLT_FEE_VOD_UW); /* ID: 454 */ + dataPoolAddr[455] = (void *)&(pdpIasw->VOLT_FEE_VRD_UW); /* ID: 455 */ + dataPoolAddr[456] = (void *)&(pdpIasw->VOLT_FEE_VOG_UW); /* ID: 456 */ + dataPoolAddr[457] = (void *)&(pdpIasw->VOLT_FEE_VSS_UW); /* ID: 457 */ + dataPoolAddr[458] = (void *)&(pdpIasw->VOLT_FEE_CCD_UW); /* ID: 458 */ + dataPoolAddr[459] = (void *)&(pdpIasw->VOLT_FEE_CLK_UW); /* ID: 459 */ + dataPoolAddr[460] = (void *)&(pdpIasw->VOLT_FEE_ANA_P5_UW); /* ID: 460 */ + dataPoolAddr[461] = (void *)&(pdpIasw->VOLT_FEE_ANA_N5_UW); /* ID: 461 */ + dataPoolAddr[462] = (void *)&(pdpIasw->VOLT_FEE_ANA_P3_3_UW); /* ID: 462 */ + dataPoolAddr[463] = (void *)&(pdpIasw->CURR_FEE_CLK_BUF_UW); /* ID: 463 */ + dataPoolAddr[464] = (void *)&(pdpIasw->VOLT_SCU_FPGA_P1_5_UW); /* ID: 464 */ + dataPoolAddr[465] = (void *)&(pdpIasw->CURR_SCU_P3_4_UW); /* ID: 465 */ + dataPoolAddr[466] = (void *)&(pdpIasw->TEMP_SEM_SCU_LA); /* ID: 466 */ + dataPoolAddr[467] = (void *)&(pdpIasw->TEMP_SEM_PCU_LA); /* ID: 467 */ + dataPoolAddr[468] = (void *)&(pdpIasw->VOLT_SCU_P3_4_LA); /* ID: 468 */ + dataPoolAddr[469] = (void *)&(pdpIasw->VOLT_SCU_P5_LA); /* ID: 469 */ + dataPoolAddr[470] = (void *)&(pdpIasw->TEMP_FEE_CCD_LA); /* ID: 470 */ + dataPoolAddr[471] = (void *)&(pdpIasw->TEMP_FEE_STRAP_LA); /* ID: 471 */ + dataPoolAddr[472] = (void *)&(pdpIasw->TEMP_FEE_ADC_LA); /* ID: 472 */ + dataPoolAddr[473] = (void *)&(pdpIasw->TEMP_FEE_BIAS_LA); /* ID: 473 */ + dataPoolAddr[474] = (void *)&(pdpIasw->TEMP_FEE_DEB_LA); /* ID: 474 */ + dataPoolAddr[475] = (void *)&(pdpIasw->VOLT_FEE_VOD_LA); /* ID: 475 */ + dataPoolAddr[476] = (void *)&(pdpIasw->VOLT_FEE_VRD_LA); /* ID: 476 */ + dataPoolAddr[477] = (void *)&(pdpIasw->VOLT_FEE_VOG_LA); /* ID: 477 */ + dataPoolAddr[478] = (void *)&(pdpIasw->VOLT_FEE_VSS_LA); /* ID: 478 */ + dataPoolAddr[479] = (void *)&(pdpIasw->VOLT_FEE_CCD_LA); /* ID: 479 */ + dataPoolAddr[480] = (void *)&(pdpIasw->VOLT_FEE_CLK_LA); /* ID: 480 */ + dataPoolAddr[481] = (void *)&(pdpIasw->VOLT_FEE_ANA_P5_LA); /* ID: 481 */ + dataPoolAddr[482] = (void *)&(pdpIasw->VOLT_FEE_ANA_N5_LA); /* ID: 482 */ + dataPoolAddr[483] = (void *)&(pdpIasw->VOLT_FEE_ANA_P3_3_LA); /* ID: 483 */ + dataPoolAddr[484] = (void *)&(pdpIasw->CURR_FEE_CLK_BUF_LA); /* ID: 484 */ + dataPoolAddr[485] = (void *)&(pdpIasw->VOLT_SCU_FPGA_P1_5_LA); /* ID: 485 */ + dataPoolAddr[486] = (void *)&(pdpIasw->CURR_SCU_P3_4_LA); /* ID: 486 */ + dataPoolAddr[487] = (void *)&(pdpIasw->TEMP_SEM_SCU_UA); /* ID: 487 */ + dataPoolAddr[488] = (void *)&(pdpIasw->TEMP_SEM_PCU_UA); /* ID: 488 */ + dataPoolAddr[489] = (void *)&(pdpIasw->VOLT_SCU_P3_4_UA); /* ID: 489 */ + dataPoolAddr[490] = (void *)&(pdpIasw->VOLT_SCU_P5_UA); /* ID: 490 */ + dataPoolAddr[491] = (void *)&(pdpIasw->TEMP_FEE_CCD_UA); /* ID: 491 */ + dataPoolAddr[492] = (void *)&(pdpIasw->TEMP_FEE_STRAP_UA); /* ID: 492 */ + dataPoolAddr[493] = (void *)&(pdpIasw->TEMP_FEE_ADC_UA); /* ID: 493 */ + dataPoolAddr[494] = (void *)&(pdpIasw->TEMP_FEE_BIAS_UA); /* ID: 494 */ + dataPoolAddr[495] = (void *)&(pdpIasw->TEMP_FEE_DEB_UA); /* ID: 495 */ + dataPoolAddr[496] = (void *)&(pdpIasw->VOLT_FEE_VOD_UA); /* ID: 496 */ + dataPoolAddr[497] = (void *)&(pdpIasw->VOLT_FEE_VRD_UA); /* ID: 497 */ + dataPoolAddr[498] = (void *)&(pdpIasw->VOLT_FEE_VOG_UA); /* ID: 498 */ + dataPoolAddr[499] = (void *)&(pdpIasw->VOLT_FEE_VSS_UA); /* ID: 499 */ + dataPoolAddr[500] = (void *)&(pdpIasw->VOLT_FEE_CCD_UA); /* ID: 500 */ + dataPoolAddr[501] = (void *)&(pdpIasw->VOLT_FEE_CLK_UA); /* ID: 501 */ + dataPoolAddr[502] = (void *)&(pdpIasw->VOLT_FEE_ANA_P5_UA); /* ID: 502 */ + dataPoolAddr[503] = (void *)&(pdpIasw->VOLT_FEE_ANA_N5_UA); /* ID: 503 */ + dataPoolAddr[504] = (void *)&(pdpIasw->VOLT_FEE_ANA_P3_3_UA); /* ID: 504 */ + dataPoolAddr[505] = (void *)&(pdpIasw->CURR_FEE_CLK_BUF_UA); /* ID: 505 */ + dataPoolAddr[506] = (void *)&(pdpIasw->VOLT_SCU_FPGA_P1_5_UA); /* ID: 506 */ + dataPoolAddr[507] = (void *)&(pdpIasw->CURR_SCU_P3_4_UA); /* ID: 507 */ + dataPoolAddr[508] = (void *)&(pdpIasw->semEvtCounter); /* ID: 508 */ + dataPoolAddr[509] = (void *)&(pdpIasw->SEM_SERV5_1_FORWARD); /* ID: 509 */ + dataPoolAddr[510] = (void *)&(pdpIasw->SEM_SERV5_2_FORWARD); /* ID: 510 */ + dataPoolAddr[511] = (void *)&(pdpIasw->SEM_SERV5_3_FORWARD); /* ID: 511 */ + dataPoolAddr[512] = (void *)&(pdpIasw->SEM_SERV5_4_FORWARD); /* ID: 512 */ + dataPoolAddr[513] = (void *)&(pdpIasw->pExpTime); /* ID: 513 */ + dataPoolAddr[514] = (void *)&(pdpIasw->pImageRep); /* ID: 514 */ + dataPoolAddr[515] = (void *)&(pdpIasw->pAcqNum); /* ID: 515 */ + dataPoolAddr[516] = (void *)&(pdpIasw->pDataOs); /* ID: 516 */ + dataPoolAddr[517] = (void *)&(pdpIasw->pCcdRdMode); /* ID: 517 */ + dataPoolAddr[518] = (void *)&(pdpIasw->pWinPosX); /* ID: 518 */ + dataPoolAddr[519] = (void *)&(pdpIasw->pWinPosY); /* ID: 519 */ + dataPoolAddr[520] = (void *)&(pdpIasw->pWinSizeX); /* ID: 520 */ + dataPoolAddr[521] = (void *)&(pdpIasw->pWinSizeY); /* ID: 521 */ + dataPoolAddr[522] = (void *)&(pdpIasw->pDtAcqSrc); /* ID: 522 */ + dataPoolAddr[523] = (void *)&(pdpIasw->pTempCtrlTarget); /* ID: 523 */ + dataPoolAddr[524] = (void *)&(pdpIasw->pVoltFeeVod); /* ID: 524 */ + dataPoolAddr[525] = (void *)&(pdpIasw->pVoltFeeVrd); /* ID: 525 */ + dataPoolAddr[526] = (void *)&(pdpIasw->pVoltFeeVss); /* ID: 526 */ + dataPoolAddr[527] = (void *)&(pdpIasw->pHeatTempFpaCCd); /* ID: 527 */ + dataPoolAddr[528] = (void *)&(pdpIasw->pHeatTempFeeStrap); /* ID: 528 */ + dataPoolAddr[529] = (void *)&(pdpIasw->pHeatTempFeeAnach); /* ID: 529 */ + dataPoolAddr[530] = (void *)&(pdpIasw->pHeatTempSpare); /* ID: 530 */ + dataPoolAddr[531] = (void *)&(pdpIasw->pStepEnDiagCcd); /* ID: 531 */ + dataPoolAddr[532] = (void *)&(pdpIasw->pStepEnDiagFee); /* ID: 532 */ + dataPoolAddr[533] = (void *)&(pdpIasw->pStepEnDiagTemp); /* ID: 533 */ + dataPoolAddr[534] = (void *)&(pdpIasw->pStepEnDiagAna); /* ID: 534 */ + dataPoolAddr[535] = (void *)&(pdpIasw->pStepEnDiagExpos); /* ID: 535 */ + dataPoolAddr[536] = (void *)&(pdpIasw->pStepDebDiagCcd); /* ID: 536 */ + dataPoolAddr[537] = (void *)&(pdpIasw->pStepDebDiagFee); /* ID: 537 */ + dataPoolAddr[538] = (void *)&(pdpIasw->pStepDebDiagTemp); /* ID: 538 */ + dataPoolAddr[539] = (void *)&(pdpIasw->pStepDebDiagAna); /* ID: 539 */ + dataPoolAddr[540] = (void *)&(pdpIasw->pStepDebDiagExpos); /* ID: 540 */ + dataPoolAddr[541] = (void *)&(pdpIasw->SEM_SERV220_6_FORWARD); /* ID: 541 */ + dataPoolAddr[542] = (void *)&(pdpIasw->SEM_SERV220_12_FORWARD); /* ID: 542 */ + dataPoolAddr[543] = (void *)&(pdpIasw->SEM_SERV222_6_FORWARD); /* ID: 543 */ + dataPoolAddr[544] = (void *)&(pdpIasw->saveImagesNode); /* ID: 544 */ + dataPoolAddr[545] = (void *)&(pdpIasw->saveImagesCnt); /* ID: 545 */ + dataPoolAddr[546] = (void *)&(pdpIasw->SaveImages_pSaveTarget); /* ID: 546 */ + dataPoolAddr[547] = (void *)&(pdpIasw->SaveImages_pFbfInit); /* ID: 547 */ + dataPoolAddr[548] = (void *)&(pdpIasw->SaveImages_pFbfEnd); /* ID: 548 */ + dataPoolAddr[549] = (void *)&(pdpIasw->acqFullDropNode); /* ID: 549 */ + dataPoolAddr[550] = (void *)&(pdpIasw->acqFullDropCnt); /* ID: 550 */ + dataPoolAddr[551] = (void *)&(pdpIasw->AcqFullDrop_pExpTime); /* ID: 551 */ + dataPoolAddr[552] = (void *)&(pdpIasw->AcqFullDrop_pImageRep); /* ID: 552 */ + dataPoolAddr[553] = (void *)&(pdpIasw->acqFullDropT1); /* ID: 553 */ + dataPoolAddr[554] = (void *)&(pdpIasw->acqFullDropT2); /* ID: 554 */ + dataPoolAddr[555] = (void *)&(pdpIasw->calFullSnapNode); /* ID: 555 */ + dataPoolAddr[556] = (void *)&(pdpIasw->calFullSnapCnt); /* ID: 556 */ + dataPoolAddr[557] = (void *)&(pdpIasw->CalFullSnap_pExpTime); /* ID: 557 */ + dataPoolAddr[558] = (void *)&(pdpIasw->CalFullSnap_pImageRep); /* ID: 558 */ + dataPoolAddr[559] = (void *)&(pdpIasw->CalFullSnap_pNmbImages); /* ID: 559 */ + dataPoolAddr[560] = (void *)&(pdpIasw->CalFullSnap_pCentSel); /* ID: 560 */ + dataPoolAddr[561] = (void *)&(pdpIasw->calFullSnapT1); /* ID: 561 */ + dataPoolAddr[562] = (void *)&(pdpIasw->calFullSnapT2); /* ID: 562 */ + dataPoolAddr[563] = (void *)&(pdpIasw->SciWinNode); /* ID: 563 */ + dataPoolAddr[564] = (void *)&(pdpIasw->SciWinCnt); /* ID: 564 */ + dataPoolAddr[565] = (void *)&(pdpIasw->SciWin_pNmbImages); /* ID: 565 */ + dataPoolAddr[566] = (void *)&(pdpIasw->SciWin_pCcdRdMode); /* ID: 566 */ + dataPoolAddr[567] = (void *)&(pdpIasw->SciWin_pExpTime); /* ID: 567 */ + dataPoolAddr[568] = (void *)&(pdpIasw->SciWin_pImageRep); /* ID: 568 */ + dataPoolAddr[569] = (void *)&(pdpIasw->SciWin_pWinPosX); /* ID: 569 */ + dataPoolAddr[570] = (void *)&(pdpIasw->SciWin_pWinPosY); /* ID: 570 */ + dataPoolAddr[571] = (void *)&(pdpIasw->SciWin_pWinSizeX); /* ID: 571 */ + dataPoolAddr[572] = (void *)&(pdpIasw->SciWin_pWinSizeY); /* ID: 572 */ + dataPoolAddr[573] = (void *)&(pdpIasw->SciWin_pCentSel); /* ID: 573 */ + dataPoolAddr[574] = (void *)&(pdpIasw->sciWinT1); /* ID: 574 */ + dataPoolAddr[575] = (void *)&(pdpIasw->sciWinT2); /* ID: 575 */ + dataPoolAddr[576] = (void *)&(pdpIasw->fbfLoadNode); /* ID: 576 */ + dataPoolAddr[577] = (void *)&(pdpIasw->fbfLoadCnt); /* ID: 577 */ + dataPoolAddr[578] = (void *)&(pdpIasw->fbfSaveNode); /* ID: 578 */ + dataPoolAddr[579] = (void *)&(pdpIasw->fbfSaveCnt); /* ID: 579 */ + dataPoolAddr[580] = (void *)&(pdpIasw->FbfLoad_pFbfId); /* ID: 580 */ + dataPoolAddr[581] = (void *)&(pdpIasw->FbfLoad_pFbfNBlocks); /* ID: 581 */ + dataPoolAddr[582] = (void *)&(pdpIasw->FbfLoad_pFbfRamAreaId); /* ID: 582 */ + dataPoolAddr[583] = (void *)&(pdpIasw->FbfLoad_pFbfRamAddr); /* ID: 583 */ + dataPoolAddr[584] = (void *)&(pdpIasw->FbfSave_pFbfId); /* ID: 584 */ + dataPoolAddr[585] = (void *)&(pdpIasw->FbfSave_pFbfNBlocks); /* ID: 585 */ + dataPoolAddr[586] = (void *)&(pdpIasw->FbfSave_pFbfRamAreaId); /* ID: 586 */ + dataPoolAddr[587] = (void *)&(pdpIasw->FbfSave_pFbfRamAddr); /* ID: 587 */ + dataPoolAddr[588] = (void *)&(pdpIasw->fbfLoadBlockCounter); /* ID: 588 */ + dataPoolAddr[589] = (void *)&(pdpIasw->fbfSaveBlockCounter); /* ID: 589 */ + dataPoolAddr[590] = (void *)&(pdpIasw->transFbfToGrndNode); /* ID: 590 */ + dataPoolAddr[591] = (void *)&(pdpIasw->transFbfToGrndCnt); /* ID: 591 */ + dataPoolAddr[592] = (void *)&(pdpIasw->TransFbfToGrnd_pNmbFbf); /* ID: 592 */ + dataPoolAddr[593] = (void *)&(pdpIasw->TransFbfToGrnd_pFbfInit); /* ID: 593 */ + dataPoolAddr[594] = (void *)&(pdpIasw->TransFbfToGrnd_pFbfSize); /* ID: 594 */ + dataPoolAddr[595] = (void *)&(pdpIasw->nomSciNode); /* ID: 595 */ + dataPoolAddr[596] = (void *)&(pdpIasw->nomSciCnt); /* ID: 596 */ + dataPoolAddr[597] = (void *)&(pdpIasw->NomSci_pAcqFlag); /* ID: 597 */ + dataPoolAddr[598] = (void *)&(pdpIasw->NomSci_pCal1Flag); /* ID: 598 */ + dataPoolAddr[599] = (void *)&(pdpIasw->NomSci_pSciFlag); /* ID: 599 */ + dataPoolAddr[600] = (void *)&(pdpIasw->NomSci_pCal2Flag); /* ID: 600 */ + dataPoolAddr[601] = (void *)&(pdpIasw->NomSci_pCibNFull); /* ID: 601 */ + dataPoolAddr[602] = (void *)&(pdpIasw->NomSci_pCibSizeFull); /* ID: 602 */ + dataPoolAddr[603] = (void *)&(pdpIasw->NomSci_pSibNFull); /* ID: 603 */ + dataPoolAddr[604] = (void *)&(pdpIasw->NomSci_pSibSizeFull); /* ID: 604 */ + dataPoolAddr[605] = (void *)&(pdpIasw->NomSci_pGibNFull); /* ID: 605 */ + dataPoolAddr[606] = (void *)&(pdpIasw->NomSci_pGibSizeFull); /* ID: 606 */ + dataPoolAddr[607] = (void *)&(pdpIasw->NomSci_pSibNWin); /* ID: 607 */ + dataPoolAddr[608] = (void *)&(pdpIasw->NomSci_pSibSizeWin); /* ID: 608 */ + dataPoolAddr[609] = (void *)&(pdpIasw->NomSci_pCibNWin); /* ID: 609 */ + dataPoolAddr[610] = (void *)&(pdpIasw->NomSci_pCibSizeWin); /* ID: 610 */ + dataPoolAddr[611] = (void *)&(pdpIasw->NomSci_pGibNWin); /* ID: 611 */ + dataPoolAddr[612] = (void *)&(pdpIasw->NomSci_pGibSizeWin); /* ID: 612 */ + dataPoolAddr[613] = (void *)&(pdpIasw->NomSci_pExpTimeAcq); /* ID: 613 */ + dataPoolAddr[614] = (void *)&(pdpIasw->NomSci_pImageRepAcq); /* ID: 614 */ + dataPoolAddr[615] = (void *)&(pdpIasw->NomSci_pExpTimeCal1); /* ID: 615 */ + dataPoolAddr[616] = (void *)&(pdpIasw->NomSci_pImageRepCal1); /* ID: 616 */ + dataPoolAddr[617] = (void *)&(pdpIasw->NomSci_pNmbImagesCal1); /* ID: 617 */ + dataPoolAddr[618] = (void *)&(pdpIasw->NomSci_pCentSelCal1); /* ID: 618 */ + dataPoolAddr[619] = (void *)&(pdpIasw->NomSci_pNmbImagesSci); /* ID: 619 */ + dataPoolAddr[620] = (void *)&(pdpIasw->NomSci_pCcdRdModeSci); /* ID: 620 */ + dataPoolAddr[621] = (void *)&(pdpIasw->NomSci_pExpTimeSci); /* ID: 621 */ + dataPoolAddr[622] = (void *)&(pdpIasw->NomSci_pImageRepSci); /* ID: 622 */ + dataPoolAddr[623] = (void *)&(pdpIasw->NomSci_pWinPosXSci); /* ID: 623 */ + dataPoolAddr[624] = (void *)&(pdpIasw->NomSci_pWinPosYSci); /* ID: 624 */ + dataPoolAddr[625] = (void *)&(pdpIasw->NomSci_pWinSizeXSci); /* ID: 625 */ + dataPoolAddr[626] = (void *)&(pdpIasw->NomSci_pWinSizeYSci); /* ID: 626 */ + dataPoolAddr[627] = (void *)&(pdpIasw->NomSci_pCentSelSci); /* ID: 627 */ + dataPoolAddr[628] = (void *)&(pdpIasw->NomSci_pExpTimeCal2); /* ID: 628 */ + dataPoolAddr[629] = (void *)&(pdpIasw->NomSci_pImageRepCal2); /* ID: 629 */ + dataPoolAddr[630] = (void *)&(pdpIasw->NomSci_pNmbImagesCal2); /* ID: 630 */ + dataPoolAddr[631] = (void *)&(pdpIasw->NomSci_pCentSelCal2); /* ID: 631 */ + dataPoolAddr[632] = (void *)&(pdpIasw->NomSci_pSaveTarget); /* ID: 632 */ + dataPoolAddr[633] = (void *)&(pdpIasw->NomSci_pFbfInit); /* ID: 633 */ + dataPoolAddr[634] = (void *)&(pdpIasw->NomSci_pFbfEnd); /* ID: 634 */ + dataPoolAddr[635] = (void *)&(pdpIasw->NomSci_pStckOrderCal1); /* ID: 635 */ + dataPoolAddr[636] = (void *)&(pdpIasw->NomSci_pStckOrderSci); /* ID: 636 */ + dataPoolAddr[637] = (void *)&(pdpIasw->NomSci_pStckOrderCal2); /* ID: 637 */ + dataPoolAddr[638] = (void *)&(pdpIasw->ConfigSdb_pSdbCmd); /* ID: 638 */ + dataPoolAddr[639] = (void *)&(pdpIasw->ConfigSdb_pCibNFull); /* ID: 639 */ + dataPoolAddr[640] = (void *)&(pdpIasw->ConfigSdb_pCibSizeFull); /* ID: 640 */ + dataPoolAddr[641] = (void *)&(pdpIasw->ConfigSdb_pSibNFull); /* ID: 641 */ + dataPoolAddr[642] = (void *)&(pdpIasw->ConfigSdb_pSibSizeFull); /* ID: 642 */ + dataPoolAddr[643] = (void *)&(pdpIasw->ConfigSdb_pGibNFull); /* ID: 643 */ + dataPoolAddr[644] = (void *)&(pdpIasw->ConfigSdb_pGibSizeFull); /* ID: 644 */ + dataPoolAddr[645] = (void *)&(pdpIasw->ConfigSdb_pSibNWin); /* ID: 645 */ + dataPoolAddr[646] = (void *)&(pdpIasw->ConfigSdb_pSibSizeWin); /* ID: 646 */ + dataPoolAddr[647] = (void *)&(pdpIasw->ConfigSdb_pCibNWin); /* ID: 647 */ + dataPoolAddr[648] = (void *)&(pdpIasw->ConfigSdb_pCibSizeWin); /* ID: 648 */ + dataPoolAddr[649] = (void *)&(pdpIasw->ConfigSdb_pGibNWin); /* ID: 649 */ + dataPoolAddr[650] = (void *)&(pdpIasw->ConfigSdb_pGibSizeWin); /* ID: 650 */ + dataPoolAddr[651] = (void *)&(pdpIasw->ADC_P3V3); /* ID: 651 */ + dataPoolAddr[652] = (void *)&(pdpIasw->ADC_P5V); /* ID: 652 */ + dataPoolAddr[653] = (void *)&(pdpIasw->ADC_P1V8); /* ID: 653 */ + dataPoolAddr[654] = (void *)&(pdpIasw->ADC_P2V5); /* ID: 654 */ + dataPoolAddr[655] = (void *)&(pdpIasw->ADC_N5V); /* ID: 655 */ + dataPoolAddr[656] = (void *)&(pdpIasw->ADC_PGND); /* ID: 656 */ + dataPoolAddr[657] = (void *)&(pdpIasw->ADC_TEMPOH1A); /* ID: 657 */ + dataPoolAddr[658] = (void *)&(pdpIasw->ADC_TEMP1); /* ID: 658 */ + dataPoolAddr[659] = (void *)&(pdpIasw->ADC_TEMPOH2A); /* ID: 659 */ + dataPoolAddr[660] = (void *)&(pdpIasw->ADC_TEMPOH1B); /* ID: 660 */ + dataPoolAddr[661] = (void *)&(pdpIasw->ADC_TEMPOH3A); /* ID: 661 */ + dataPoolAddr[662] = (void *)&(pdpIasw->ADC_TEMPOH2B); /* ID: 662 */ + dataPoolAddr[663] = (void *)&(pdpIasw->ADC_TEMPOH4A); /* ID: 663 */ + dataPoolAddr[664] = (void *)&(pdpIasw->ADC_TEMPOH3B); /* ID: 664 */ + dataPoolAddr[665] = (void *)&(pdpIasw->ADC_TEMPOH4B); /* ID: 665 */ + dataPoolAddr[666] = (void *)&(pdpIasw->SEM_P15V); /* ID: 666 */ + dataPoolAddr[667] = (void *)&(pdpIasw->SEM_P30V); /* ID: 667 */ + dataPoolAddr[668] = (void *)&(pdpIasw->SEM_P5V0); /* ID: 668 */ + dataPoolAddr[669] = (void *)&(pdpIasw->SEM_P7V0); /* ID: 669 */ + dataPoolAddr[670] = (void *)&(pdpIasw->SEM_N5V0); /* ID: 670 */ + dataPoolAddr[671] = (void *)&(pdpIasw->ADC_P3V3_RAW); /* ID: 671 */ + dataPoolAddr[672] = (void *)&(pdpIasw->ADC_P5V_RAW); /* ID: 672 */ + dataPoolAddr[673] = (void *)&(pdpIasw->ADC_P1V8_RAW); /* ID: 673 */ + dataPoolAddr[674] = (void *)&(pdpIasw->ADC_P2V5_RAW); /* ID: 674 */ + dataPoolAddr[675] = (void *)&(pdpIasw->ADC_N5V_RAW); /* ID: 675 */ + dataPoolAddr[676] = (void *)&(pdpIasw->ADC_PGND_RAW); /* ID: 676 */ + dataPoolAddr[677] = (void *)&(pdpIasw->ADC_TEMPOH1A_RAW); /* ID: 677 */ + dataPoolAddr[678] = (void *)&(pdpIasw->ADC_TEMP1_RAW); /* ID: 678 */ + dataPoolAddr[679] = (void *)&(pdpIasw->ADC_TEMPOH2A_RAW); /* ID: 679 */ + dataPoolAddr[680] = (void *)&(pdpIasw->ADC_TEMPOH1B_RAW); /* ID: 680 */ + dataPoolAddr[681] = (void *)&(pdpIasw->ADC_TEMPOH3A_RAW); /* ID: 681 */ + dataPoolAddr[682] = (void *)&(pdpIasw->ADC_TEMPOH2B_RAW); /* ID: 682 */ + dataPoolAddr[683] = (void *)&(pdpIasw->ADC_TEMPOH4A_RAW); /* ID: 683 */ + dataPoolAddr[684] = (void *)&(pdpIasw->ADC_TEMPOH3B_RAW); /* ID: 684 */ + dataPoolAddr[685] = (void *)&(pdpIasw->ADC_TEMPOH4B_RAW); /* ID: 685 */ + dataPoolAddr[686] = (void *)&(pdpIasw->SEM_P15V_RAW); /* ID: 686 */ + dataPoolAddr[687] = (void *)&(pdpIasw->SEM_P30V_RAW); /* ID: 687 */ + dataPoolAddr[688] = (void *)&(pdpIasw->SEM_P5V0_RAW); /* ID: 688 */ + dataPoolAddr[689] = (void *)&(pdpIasw->SEM_P7V0_RAW); /* ID: 689 */ + dataPoolAddr[690] = (void *)&(pdpIasw->SEM_N5V0_RAW); /* ID: 690 */ + dataPoolAddr[691] = (void *)&(pdpIasw->ADC_P3V3_U); /* ID: 691 */ + dataPoolAddr[692] = (void *)&(pdpIasw->ADC_P5V_U); /* ID: 692 */ + dataPoolAddr[693] = (void *)&(pdpIasw->ADC_P1V8_U); /* ID: 693 */ + dataPoolAddr[694] = (void *)&(pdpIasw->ADC_P2V5_U); /* ID: 694 */ + dataPoolAddr[695] = (void *)&(pdpIasw->ADC_N5V_L); /* ID: 695 */ + dataPoolAddr[696] = (void *)&(pdpIasw->ADC_PGND_U); /* ID: 696 */ + dataPoolAddr[697] = (void *)&(pdpIasw->ADC_PGND_L); /* ID: 697 */ + dataPoolAddr[698] = (void *)&(pdpIasw->ADC_TEMPOH1A_U); /* ID: 698 */ + dataPoolAddr[699] = (void *)&(pdpIasw->ADC_TEMP1_U); /* ID: 699 */ + dataPoolAddr[700] = (void *)&(pdpIasw->ADC_TEMPOH2A_U); /* ID: 700 */ + dataPoolAddr[701] = (void *)&(pdpIasw->ADC_TEMPOH1B_U); /* ID: 701 */ + dataPoolAddr[702] = (void *)&(pdpIasw->ADC_TEMPOH3A_U); /* ID: 702 */ + dataPoolAddr[703] = (void *)&(pdpIasw->ADC_TEMPOH2B_U); /* ID: 703 */ + dataPoolAddr[704] = (void *)&(pdpIasw->ADC_TEMPOH4A_U); /* ID: 704 */ + dataPoolAddr[705] = (void *)&(pdpIasw->ADC_TEMPOH3B_U); /* ID: 705 */ + dataPoolAddr[706] = (void *)&(pdpIasw->ADC_TEMPOH4B_U); /* ID: 706 */ + dataPoolAddr[707] = (void *)&(pdpIasw->SEM_P15V_U); /* ID: 707 */ + dataPoolAddr[708] = (void *)&(pdpIasw->SEM_P30V_U); /* ID: 708 */ + dataPoolAddr[709] = (void *)&(pdpIasw->SEM_P5V0_U); /* ID: 709 */ + dataPoolAddr[710] = (void *)&(pdpIasw->SEM_P7V0_U); /* ID: 710 */ + dataPoolAddr[711] = (void *)&(pdpIasw->SEM_N5V0_L); /* ID: 711 */ + dataPoolAddr[712] = (void *)&(pdpIasw->HbSemPassword); /* ID: 712 */ + dataPoolAddr[713] = (void *)&(pdpIasw->HbSemCounter); /* ID: 713 */ + dataPoolAddr[714] = (void *)&(pdpIbsw->isWatchdogEnabled); /* ID: 714 */ + dataPoolAddr[715] = (void *)&(pdpIbsw->isSynchronized); /* ID: 715 */ + dataPoolAddr[716] = (void *)&(pdpIbsw->missedMsgCnt); /* ID: 716 */ + dataPoolAddr[717] = (void *)&(pdpIbsw->missedPulseCnt); /* ID: 717 */ + dataPoolAddr[718] = (void *)&(pdpIbsw->milFrameDelay); /* ID: 718 */ + dataPoolAddr[719] = (void *)&(pdpIbsw->EL1_CHIP); /* ID: 719 */ + dataPoolAddr[720] = (void *)&(pdpIbsw->EL2_CHIP); /* ID: 720 */ + dataPoolAddr[721] = (void *)&(pdpIbsw->EL1_ADDR); /* ID: 721 */ + dataPoolAddr[722] = (void *)&(pdpIbsw->EL2_ADDR); /* ID: 722 */ + dataPoolAddr[723] = (void *)&(pdpIbsw->ERR_LOG_ENB); /* ID: 723 */ + dataPoolAddr[724] = (void *)&(pdpIbsw->isErrLogValid); /* ID: 724 */ + dataPoolAddr[725] = (void *)&(pdpIbsw->nOfErrLogEntries); /* ID: 725 */ + dataPoolAddr[726] = (void *)&(pdpIasw->MAX_SEM_PCKT_CYC); /* ID: 726 */ + dataPoolAddr[727] = (void *)&(pdpIbsw->FBF_BLCK_WR_DUR); /* ID: 727 */ + dataPoolAddr[728] = (void *)&(pdpIbsw->FBF_BLCK_RD_DUR); /* ID: 728 */ + dataPoolAddr[729] = (void *)&(pdpIbsw->isFbfOpen); /* ID: 729 */ + dataPoolAddr[730] = (void *)&(pdpIbsw->isFbfValid); /* ID: 730 */ + dataPoolAddr[731] = (void *)&(pdpIbsw->FBF_ENB); /* ID: 731 */ + dataPoolAddr[732] = (void *)&(pdpIbsw->FBF_CHIP); /* ID: 732 */ + dataPoolAddr[733] = (void *)&(pdpIbsw->FBF_ADDR); /* ID: 733 */ + dataPoolAddr[734] = (void *)&(pdpIbsw->fbfNBlocks); /* ID: 734 */ + dataPoolAddr[735] = (void *)&(pdpIbsw->THR_MA_A_1); /* ID: 735 */ + dataPoolAddr[736] = (void *)&(pdpIbsw->THR_MA_A_2); /* ID: 736 */ + dataPoolAddr[737] = (void *)&(pdpIbsw->THR_MA_A_3); /* ID: 737 */ + dataPoolAddr[738] = (void *)&(pdpIbsw->THR_MA_A_4); /* ID: 738 */ + dataPoolAddr[739] = (void *)&(pdpIbsw->THR_MA_A_5); /* ID: 739 */ + dataPoolAddr[740] = (void *)&(pdpIbsw->wcet_1); /* ID: 740 */ + dataPoolAddr[741] = (void *)&(pdpIbsw->wcet_2); /* ID: 741 */ + dataPoolAddr[742] = (void *)&(pdpIbsw->wcet_3); /* ID: 742 */ + dataPoolAddr[743] = (void *)&(pdpIbsw->wcet_4); /* ID: 743 */ + dataPoolAddr[744] = (void *)&(pdpIbsw->wcet_5); /* ID: 744 */ + dataPoolAddr[745] = (void *)&(pdpIbsw->wcetAver_1); /* ID: 745 */ + dataPoolAddr[746] = (void *)&(pdpIbsw->wcetAver_2); /* ID: 746 */ + dataPoolAddr[747] = (void *)&(pdpIbsw->wcetAver_3); /* ID: 747 */ + dataPoolAddr[748] = (void *)&(pdpIbsw->wcetAver_4); /* ID: 748 */ + dataPoolAddr[749] = (void *)&(pdpIbsw->wcetAver_5); /* ID: 749 */ + dataPoolAddr[750] = (void *)&(pdpIbsw->wcetMax_1); /* ID: 750 */ + dataPoolAddr[751] = (void *)&(pdpIbsw->wcetMax_2); /* ID: 751 */ + dataPoolAddr[752] = (void *)&(pdpIbsw->wcetMax_3); /* ID: 752 */ + dataPoolAddr[753] = (void *)&(pdpIbsw->wcetMax_4); /* ID: 753 */ + dataPoolAddr[754] = (void *)&(pdpIbsw->wcetMax_5); /* ID: 754 */ + dataPoolAddr[755] = (void *)&(pdpIbsw->nOfNotif_1); /* ID: 755 */ + dataPoolAddr[756] = (void *)&(pdpIbsw->nOfNotif_2); /* ID: 756 */ + dataPoolAddr[757] = (void *)&(pdpIbsw->nOfNotif_3); /* ID: 757 */ + dataPoolAddr[758] = (void *)&(pdpIbsw->nOfNotif_4); /* ID: 758 */ + dataPoolAddr[759] = (void *)&(pdpIbsw->nOfNotif_5); /* ID: 759 */ + dataPoolAddr[760] = (void *)&(pdpIbsw->nofFuncExec_1); /* ID: 760 */ + dataPoolAddr[761] = (void *)&(pdpIbsw->nofFuncExec_2); /* ID: 761 */ + dataPoolAddr[762] = (void *)&(pdpIbsw->nofFuncExec_3); /* ID: 762 */ + dataPoolAddr[763] = (void *)&(pdpIbsw->nofFuncExec_4); /* ID: 763 */ + dataPoolAddr[764] = (void *)&(pdpIbsw->nofFuncExec_5); /* ID: 764 */ + dataPoolAddr[765] = (void *)&(pdpIbsw->wcetTimeStampFine_1); /* ID: 765 */ + dataPoolAddr[766] = (void *)&(pdpIbsw->wcetTimeStampFine_2); /* ID: 766 */ + dataPoolAddr[767] = (void *)&(pdpIbsw->wcetTimeStampFine_3); /* ID: 767 */ + dataPoolAddr[768] = (void *)&(pdpIbsw->wcetTimeStampFine_4); /* ID: 768 */ + dataPoolAddr[769] = (void *)&(pdpIbsw->wcetTimeStampFine_5); /* ID: 769 */ + dataPoolAddr[770] = (void *)&(pdpIbsw->wcetTimeStampCoarse_1); /* ID: 770 */ + dataPoolAddr[771] = (void *)&(pdpIbsw->wcetTimeStampCoarse_2); /* ID: 771 */ + dataPoolAddr[772] = (void *)&(pdpIbsw->wcetTimeStampCoarse_3); /* ID: 772 */ + dataPoolAddr[773] = (void *)&(pdpIbsw->wcetTimeStampCoarse_4); /* ID: 773 */ + dataPoolAddr[774] = (void *)&(pdpIbsw->wcetTimeStampCoarse_5); /* ID: 774 */ + dataPoolAddr[775] = (void *)&(pdpIbsw->flashContStepCnt); /* ID: 775 */ + dataPoolAddr[776] = (void *)&(pdpIbsw->OTA_TM1A_NOM); /* ID: 776 */ + dataPoolAddr[777] = (void *)&(pdpIbsw->OTA_TM1A_RED); /* ID: 777 */ + dataPoolAddr[778] = (void *)&(pdpIbsw->OTA_TM1B_NOM); /* ID: 778 */ + dataPoolAddr[779] = (void *)&(pdpIbsw->OTA_TM1B_RED); /* ID: 779 */ + dataPoolAddr[780] = (void *)&(pdpIbsw->OTA_TM2A_NOM); /* ID: 780 */ + dataPoolAddr[781] = (void *)&(pdpIbsw->OTA_TM2A_RED); /* ID: 781 */ + dataPoolAddr[782] = (void *)&(pdpIbsw->OTA_TM2B_NOM); /* ID: 782 */ + dataPoolAddr[783] = (void *)&(pdpIbsw->OTA_TM2B_RED); /* ID: 783 */ + dataPoolAddr[784] = (void *)&(pdpIbsw->OTA_TM3A_NOM); /* ID: 784 */ + dataPoolAddr[785] = (void *)&(pdpIbsw->OTA_TM3A_RED); /* ID: 785 */ + dataPoolAddr[786] = (void *)&(pdpIbsw->OTA_TM3B_NOM); /* ID: 786 */ + dataPoolAddr[787] = (void *)&(pdpIbsw->OTA_TM3B_RED); /* ID: 787 */ + dataPoolAddr[788] = (void *)&(pdpIbsw->OTA_TM4A_NOM); /* ID: 788 */ + dataPoolAddr[789] = (void *)&(pdpIbsw->OTA_TM4A_RED); /* ID: 789 */ + dataPoolAddr[790] = (void *)&(pdpIbsw->OTA_TM4B_NOM); /* ID: 790 */ + dataPoolAddr[791] = (void *)&(pdpIbsw->OTA_TM4B_RED); /* ID: 791 */ + dataPoolAddr[792] = (void *)&(pdpIbsw->Core0Load); /* ID: 792 */ + dataPoolAddr[793] = (void *)&(pdpIbsw->Core1Load); /* ID: 793 */ + dataPoolAddr[794] = (void *)&(pdpIbsw->InterruptRate); /* ID: 794 */ + dataPoolAddr[795] = (void *)&(pdpIbsw->CyclicalActivitiesCtr); /* ID: 795 */ + dataPoolAddr[796] = (void *)&(pdpIbsw->Uptime); /* ID: 796 */ + dataPoolAddr[797] = (void *)&(pdpIbsw->SemTick); /* ID: 797 */ + dataPoolAddr[798] = (void *)&(pdpIasw->SemPwrOnTimestamp); /* ID: 798 */ + dataPoolAddr[799] = (void *)&(pdpIasw->SemPwrOffTimestamp); /* ID: 799 */ + dataPoolAddr[800] = (void *)&(pdpIasw->IASW_EVT_CTR); /* ID: 800 */ + dataPoolAddr[801] = (void *)&(pdpIbsw->BAD_COPY_ID); /* ID: 801 */ + dataPoolAddr[802] = (void *)&(pdpIbsw->BAD_PASTE_ID); /* ID: 802 */ + dataPoolAddr[803] = (void *)&(pdpIbsw->ObcInputBufferPackets); /* ID: 803 */ + dataPoolAddr[804] = (void *)&(pdpIbsw->GrndInputBufferPackets); /* ID: 804 */ + dataPoolAddr[805] = (void *)&(pdpIbsw->MilBusBytesIn); /* ID: 805 */ + dataPoolAddr[806] = (void *)&(pdpIbsw->MilBusBytesOut); /* ID: 806 */ + dataPoolAddr[807] = (void *)&(pdpIbsw->MilBusDroppedBytes); /* ID: 807 */ + dataPoolAddr[808] = (void *)&(pdpIbsw->IRL1); /* ID: 808 */ + dataPoolAddr[809] = (void *)&(pdpIbsw->IRL1_AHBSTAT); /* ID: 809 */ + dataPoolAddr[810] = (void *)&(pdpIbsw->IRL1_GRGPIO_6); /* ID: 810 */ + dataPoolAddr[811] = (void *)&(pdpIbsw->IRL1_GRTIMER); /* ID: 811 */ + dataPoolAddr[812] = (void *)&(pdpIbsw->IRL1_GPTIMER_0); /* ID: 812 */ + dataPoolAddr[813] = (void *)&(pdpIbsw->IRL1_GPTIMER_1); /* ID: 813 */ + dataPoolAddr[814] = (void *)&(pdpIbsw->IRL1_GPTIMER_2); /* ID: 814 */ + dataPoolAddr[815] = (void *)&(pdpIbsw->IRL1_GPTIMER_3); /* ID: 815 */ + dataPoolAddr[816] = (void *)&(pdpIbsw->IRL1_IRQMP); /* ID: 816 */ + dataPoolAddr[817] = (void *)&(pdpIbsw->IRL1_B1553BRM); /* ID: 817 */ + dataPoolAddr[818] = (void *)&(pdpIbsw->IRL2); /* ID: 818 */ + dataPoolAddr[819] = (void *)&(pdpIbsw->IRL2_GRSPW2_0); /* ID: 819 */ + dataPoolAddr[820] = (void *)&(pdpIbsw->IRL2_GRSPW2_1); /* ID: 820 */ + dataPoolAddr[821] = (void *)&(pdpIbsw->SemRoute); /* ID: 821 */ + dataPoolAddr[822] = (void *)&(pdpIbsw->SpW0BytesIn); /* ID: 822 */ + dataPoolAddr[823] = (void *)&(pdpIbsw->SpW0BytesOut); /* ID: 823 */ + dataPoolAddr[824] = (void *)&(pdpIbsw->SpW1BytesIn); /* ID: 824 */ + dataPoolAddr[825] = (void *)&(pdpIbsw->SpW1BytesOut); /* ID: 825 */ + dataPoolAddr[826] = (void *)&(pdpIbsw->Spw0TxDescAvail); /* ID: 826 */ + dataPoolAddr[827] = (void *)&(pdpIbsw->Spw0RxPcktAvail); /* ID: 827 */ + dataPoolAddr[828] = (void *)&(pdpIbsw->Spw1TxDescAvail); /* ID: 828 */ + dataPoolAddr[829] = (void *)&(pdpIbsw->Spw1RxPcktAvail); /* ID: 829 */ + dataPoolAddr[830] = (void *)&(pdpIbsw->MilCucCoarseTime); /* ID: 830 */ + dataPoolAddr[831] = (void *)&(pdpIbsw->MilCucFineTime); /* ID: 831 */ + dataPoolAddr[832] = (void *)&(pdpIbsw->CucCoarseTime); /* ID: 832 */ + dataPoolAddr[833] = (void *)&(pdpIbsw->CucFineTime); /* ID: 833 */ + dataPoolAddr[834] = (void *)&(pdpIasw->Sram1ScrCurrAddr); /* ID: 834 */ + dataPoolAddr[835] = (void *)&(pdpIasw->Sram2ScrCurrAddr); /* ID: 835 */ + dataPoolAddr[836] = (void *)&(pdpIasw->Sram1ScrLength); /* ID: 836 */ + dataPoolAddr[837] = (void *)&(pdpIasw->Sram2ScrLength); /* ID: 837 */ + dataPoolAddr[838] = (void *)&(pdpIasw->EdacSingleRepaired); /* ID: 838 */ + dataPoolAddr[839] = (void *)&(pdpIasw->EdacSingleFaults); /* ID: 839 */ + dataPoolAddr[840] = (void *)&(pdpIasw->EdacLastSingleFail); /* ID: 840 */ + dataPoolAddr[841] = (void *)&(pdpIbsw->EdacDoubleFaults); /* ID: 841 */ + dataPoolAddr[842] = (void *)&(pdpIbsw->EdacDoubleFAddr); /* ID: 842 */ + dataPoolAddr[843] = (void *)&(pdpIasw->Cpu2ProcStatus); /* ID: 843 */ + dataPoolAddr[844] = (void *)&(pdpIbsw->HEARTBEAT_ENABLED); /* ID: 844 */ + dataPoolAddr[845] = (void *)&(pdpIbsw->S1AllocDbs); /* ID: 845 */ + dataPoolAddr[846] = (void *)&(pdpIbsw->S1AllocSw); /* ID: 846 */ + dataPoolAddr[847] = (void *)&(pdpIbsw->S1AllocHeap); /* ID: 847 */ + dataPoolAddr[848] = (void *)&(pdpIbsw->S1AllocFlash); /* ID: 848 */ + dataPoolAddr[849] = (void *)&(pdpIbsw->S1AllocAux); /* ID: 849 */ + dataPoolAddr[850] = (void *)&(pdpIbsw->S1AllocRes); /* ID: 850 */ + dataPoolAddr[851] = (void *)&(pdpIbsw->S1AllocSwap); /* ID: 851 */ + dataPoolAddr[852] = (void *)&(pdpIbsw->S2AllocSciHeap); /* ID: 852 */ + dataPoolAddr[853] = (void *)&(pdpIasw->TaAlgoId); /* ID: 853 */ + dataPoolAddr[854] = (void *)&(pdpIasw->TAACQALGOID); /* ID: 854 */ + dataPoolAddr[855] = (void *)&(pdpIasw->TASPARE32); /* ID: 855 */ + dataPoolAddr[856] = (void *)&(pdpIasw->TaTimingPar1); /* ID: 856 */ + dataPoolAddr[857] = (void *)&(pdpIasw->TaTimingPar2); /* ID: 857 */ + dataPoolAddr[858] = (void *)&(pdpIasw->TaDistanceThrd); /* ID: 858 */ + dataPoolAddr[859] = (void *)&(pdpIasw->TaIterations); /* ID: 859 */ + dataPoolAddr[860] = (void *)&(pdpIasw->TaRebinningFact); /* ID: 860 */ + dataPoolAddr[861] = (void *)&(pdpIasw->TaDetectionThrd); /* ID: 861 */ + dataPoolAddr[862] = (void *)&(pdpIasw->TaSeReducedExtr); /* ID: 862 */ + dataPoolAddr[863] = (void *)&(pdpIasw->TaSeReducedRadius); /* ID: 863 */ + dataPoolAddr[864] = (void *)&(pdpIasw->TaSeTolerance); /* ID: 864 */ + dataPoolAddr[865] = (void *)&(pdpIasw->TaMvaTolerance); /* ID: 865 */ + dataPoolAddr[866] = (void *)&(pdpIasw->TaAmaTolerance); /* ID: 866 */ + dataPoolAddr[867] = (void *)&(pdpIasw->TAPOINTUNCERT); /* ID: 867 */ + dataPoolAddr[868] = (void *)&(pdpIasw->TATARGETSIG); /* ID: 868 */ + dataPoolAddr[869] = (void *)&(pdpIasw->TANROFSTARS); /* ID: 869 */ + dataPoolAddr[870] = (void *)&(pdpIasw->TaMaxSigFract); /* ID: 870 */ + dataPoolAddr[871] = (void *)&(pdpIasw->TaBias); /* ID: 871 */ + dataPoolAddr[872] = (void *)&(pdpIasw->TaDark); /* ID: 872 */ + dataPoolAddr[873] = (void *)&(pdpIasw->TaSkyBg); /* ID: 873 */ + dataPoolAddr[874] = (void *)&(pdpIasw->COGBITS); /* ID: 874 */ + dataPoolAddr[875] = (void *)&(pdpIasw->CENT_MULT_X); /* ID: 875 */ + dataPoolAddr[876] = (void *)&(pdpIasw->CENT_MULT_Y); /* ID: 876 */ + dataPoolAddr[877] = (void *)&(pdpIasw->CENT_OFFSET_X); /* ID: 877 */ + dataPoolAddr[878] = (void *)&(pdpIasw->CENT_OFFSET_Y); /* ID: 878 */ + dataPoolAddr[879] = (void *)&(pdpIasw->CENT_MEDIANFILTER); /* ID: 879 */ + dataPoolAddr[880] = (void *)&(pdpIasw->CENT_DIM_X); /* ID: 880 */ + dataPoolAddr[881] = (void *)&(pdpIasw->CENT_DIM_Y); /* ID: 881 */ + dataPoolAddr[882] = (void *)&(pdpIasw->CENT_CHECKS); /* ID: 882 */ + dataPoolAddr[883] = (void *)&(pdpIasw->CEN_SIGMALIMIT); /* ID: 883 */ + dataPoolAddr[884] = (void *)&(pdpIasw->CEN_SIGNALLIMIT); /* ID: 884 */ + dataPoolAddr[885] = (void *)&(pdpIasw->CEN_MEDIAN_THRD); /* ID: 885 */ + dataPoolAddr[886] = (void *)&(pdpIasw->OPT_AXIS_X); /* ID: 886 */ + dataPoolAddr[887] = (void *)&(pdpIasw->OPT_AXIS_Y); /* ID: 887 */ + dataPoolAddr[888] = (void *)&(pdpIasw->DIST_CORR); /* ID: 888 */ + dataPoolAddr[889] = (void *)&(pdpIasw->pStckOrderSci); /* ID: 889 */ + dataPoolAddr[890] = (void *)&(pdpIasw->pWinSizeXSci); /* ID: 890 */ + dataPoolAddr[891] = (void *)&(pdpIasw->pWinSizeYSci); /* ID: 891 */ + dataPoolAddr[892] = (void *)&(pdpIasw->SdpImageAptShape); /* ID: 892 */ + dataPoolAddr[893] = (void *)&(pdpIasw->SdpImageAptX); /* ID: 893 */ + dataPoolAddr[894] = (void *)&(pdpIasw->SdpImageAptY); /* ID: 894 */ + dataPoolAddr[895] = (void *)&(pdpIasw->SdpImgttAptShape); /* ID: 895 */ + dataPoolAddr[896] = (void *)&(pdpIasw->SdpImgttAptX); /* ID: 896 */ + dataPoolAddr[897] = (void *)&(pdpIasw->SdpImgttAptY); /* ID: 897 */ + dataPoolAddr[898] = (void *)&(pdpIasw->SdpImgttStckOrder); /* ID: 898 */ + dataPoolAddr[899] = (void *)&(pdpIasw->SdpLosStckOrder); /* ID: 899 */ + dataPoolAddr[900] = (void *)&(pdpIasw->SdpLblkStckOrder); /* ID: 900 */ + dataPoolAddr[901] = (void *)&(pdpIasw->SdpLdkStckOrder); /* ID: 901 */ + dataPoolAddr[902] = (void *)&(pdpIasw->SdpRdkStckOrder); /* ID: 902 */ + dataPoolAddr[903] = (void *)&(pdpIasw->SdpRblkStckOrder); /* ID: 903 */ + dataPoolAddr[904] = (void *)&(pdpIasw->SdpTosStckOrder); /* ID: 904 */ + dataPoolAddr[905] = (void *)&(pdpIasw->SdpTdkStckOrder); /* ID: 905 */ + dataPoolAddr[906] = (void *)&(pdpIasw->SdpImgttStrat); /* ID: 906 */ + dataPoolAddr[907] = (void *)&(pdpIasw->Sdp3StatAmpl); /* ID: 907 */ + dataPoolAddr[908] = (void *)&(pdpIasw->SdpPhotStrat); /* ID: 908 */ + dataPoolAddr[909] = (void *)&(pdpIasw->SdpPhotRcent); /* ID: 909 */ + dataPoolAddr[910] = (void *)&(pdpIasw->SdpPhotRann1); /* ID: 910 */ + dataPoolAddr[911] = (void *)&(pdpIasw->SdpPhotRann2); /* ID: 911 */ + dataPoolAddr[912] = (void *)&(pdpIasw->SdpCrc); /* ID: 912 */ + dataPoolAddr[913] = (void *)&(pdpIasw->CCPRODUCT); /* ID: 913 */ + dataPoolAddr[914] = (void *)&(pdpIasw->CCSTEP); /* ID: 914 */ + dataPoolAddr[915] = (void *)&(pdpIasw->XIB_FAILURES); /* ID: 915 */ + dataPoolAddr[916] = (void *)&(pdpIasw->FEE_SIDE_A); /* ID: 916 */ + dataPoolAddr[917] = (void *)&(pdpIasw->FEE_SIDE_B); /* ID: 917 */ + dataPoolAddr[918] = (void *)&(pdpIasw->NLCBORDERS); /* ID: 918 */ + dataPoolAddr[919] = (void *)&(pdpIasw->NLCCOEFF_A); /* ID: 919 */ + dataPoolAddr[920] = (void *)&(pdpIasw->NLCCOEFF_B); /* ID: 920 */ + dataPoolAddr[921] = (void *)&(pdpIasw->NLCCOEFF_C); /* ID: 921 */ + dataPoolAddr[922] = (void *)&(pdpIasw->NLCCOEFF_D); /* ID: 922 */ + dataPoolAddr[923] = (void *)&(pdpIasw->SdpGlobalBias); /* ID: 923 */ + dataPoolAddr[924] = (void *)&(pdpIasw->BiasOrigin); /* ID: 924 */ + dataPoolAddr[925] = (void *)&(pdpIasw->SdpGlobalGain); /* ID: 925 */ + dataPoolAddr[926] = (void *)&(pdpIasw->SdpWinImageCeKey); /* ID: 926 */ + dataPoolAddr[927] = (void *)&(pdpIasw->SdpWinImgttCeKey); /* ID: 927 */ + dataPoolAddr[928] = (void *)&(pdpIasw->SdpWinHdrCeKey); /* ID: 928 */ + dataPoolAddr[929] = (void *)&(pdpIasw->SdpWinMLOSCeKey); /* ID: 929 */ + dataPoolAddr[930] = (void *)&(pdpIasw->SdpWinMLBLKCeKey); /* ID: 930 */ + dataPoolAddr[931] = (void *)&(pdpIasw->SdpWinMLDKCeKey); /* ID: 931 */ + dataPoolAddr[932] = (void *)&(pdpIasw->SdpWinMRDKCeKey); /* ID: 932 */ + dataPoolAddr[933] = (void *)&(pdpIasw->SdpWinMRBLKCeKey); /* ID: 933 */ + dataPoolAddr[934] = (void *)&(pdpIasw->SdpWinMTOSCeKey); /* ID: 934 */ + dataPoolAddr[935] = (void *)&(pdpIasw->SdpWinMTDKCeKey); /* ID: 935 */ + dataPoolAddr[936] = (void *)&(pdpIasw->SdpFullImgCeKey); /* ID: 936 */ + dataPoolAddr[937] = (void *)&(pdpIasw->SdpFullHdrCeKey); /* ID: 937 */ + dataPoolAddr[938] = (void *)&(pdpIasw->CE_Timetag_crs); /* ID: 938 */ + dataPoolAddr[939] = (void *)&(pdpIasw->CE_Timetag_fine); /* ID: 939 */ + dataPoolAddr[940] = (void *)&(pdpIasw->CE_Counter); /* ID: 940 */ + dataPoolAddr[941] = (void *)&(pdpIasw->CE_Version); /* ID: 941 */ + dataPoolAddr[942] = (void *)&(pdpIasw->CE_Integrity); /* ID: 942 */ + dataPoolAddr[943] = (void *)&(pdpIasw->CE_SemWindowPosX); /* ID: 943 */ + dataPoolAddr[944] = (void *)&(pdpIasw->CE_SemWindowPosY); /* ID: 944 */ + dataPoolAddr[945] = (void *)&(pdpIasw->CE_SemWindowSizeX); /* ID: 945 */ + dataPoolAddr[946] = (void *)&(pdpIasw->CE_SemWindowSizeY); /* ID: 946 */ + dataPoolAddr[947] = (void *)&(pdpIasw->SPILL_CTR); /* ID: 947 */ + dataPoolAddr[948] = (void *)&(pdpIasw->RZIP_ITER1); /* ID: 948 */ + dataPoolAddr[949] = (void *)&(pdpIasw->RZIP_ITER2); /* ID: 949 */ + dataPoolAddr[950] = (void *)&(pdpIasw->RZIP_ITER3); /* ID: 950 */ + dataPoolAddr[951] = (void *)&(pdpIasw->RZIP_ITER4); /* ID: 951 */ + dataPoolAddr[952] = (void *)&(pdpIasw->SdpLdkColMask); /* ID: 952 */ + dataPoolAddr[953] = (void *)&(pdpIasw->SdpRdkColMask); /* ID: 953 */ + dataPoolAddr[954] = (void *)&(pdpIbsw->FPGA_Version); /* ID: 954 */ + dataPoolAddr[955] = (void *)&(pdpIbsw->FPGA_DPU_Status); /* ID: 955 */ + dataPoolAddr[956] = (void *)&(pdpIbsw->FPGA_DPU_Address); /* ID: 956 */ + dataPoolAddr[957] = (void *)&(pdpIbsw->FPGA_RESET_Status); /* ID: 957 */ + dataPoolAddr[958] = (void *)&(pdpIbsw->FPGA_SEM_Status); /* ID: 958 */ + dataPoolAddr[959] = (void *)&(pdpIbsw->FPGA_Oper_Heater_Status); /* ID: 959 */ + dataPoolAddr[960] = (void *)&(pdpIasw->GIBTOTRANSFER); /* ID: 960 */ + dataPoolAddr[961] = (void *)&(pdpIasw->TRANSFERMODE); /* ID: 961 */ + dataPoolAddr[962] = (void *)&(pdpIasw->S2TOTRANSFERSIZE); /* ID: 962 */ + dataPoolAddr[963] = (void *)&(pdpIasw->S4TOTRANSFERSIZE); /* ID: 963 */ + dataPoolAddr[964] = (void *)&(pdpIasw->TransferComplete); /* ID: 964 */ + dataPoolAddr[965] = (void *)&(pdpIasw->NLCBORDERS_2); /* ID: 965 */ + dataPoolAddr[966] = (void *)&(pdpIasw->NLCCOEFF_A_2); /* ID: 966 */ + dataPoolAddr[967] = (void *)&(pdpIasw->NLCCOEFF_B_2); /* ID: 967 */ + dataPoolAddr[968] = (void *)&(pdpIasw->NLCCOEFF_C_2); /* ID: 968 */ + dataPoolAddr[969] = (void *)&(pdpIasw->RF100); /* ID: 969 */ + dataPoolAddr[970] = (void *)&(pdpIasw->RF230); /* ID: 970 */ + dataPoolAddr[971] = (void *)&(pdpIasw->distc1); /* ID: 971 */ + dataPoolAddr[972] = (void *)&(pdpIasw->distc2); /* ID: 972 */ + dataPoolAddr[973] = (void *)&(pdpIasw->distc3); /* ID: 973 */ + dataPoolAddr[974] = (void *)&(pdpIasw->SPARE_UI_0); /* ID: 974 */ + dataPoolAddr[975] = (void *)&(pdpIasw->SPARE_UI_1); /* ID: 975 */ + dataPoolAddr[976] = (void *)&(pdpIasw->SPARE_UI_2); /* ID: 976 */ + dataPoolAddr[977] = (void *)&(pdpIasw->SPARE_UI_3); /* ID: 977 */ + dataPoolAddr[978] = (void *)&(pdpIasw->SPARE_UI_4); /* ID: 978 */ + dataPoolAddr[979] = (void *)&(pdpIasw->SPARE_UI_5); /* ID: 979 */ + dataPoolAddr[980] = (void *)&(pdpIasw->SPARE_UI_6); /* ID: 980 */ + dataPoolAddr[981] = (void *)&(pdpIasw->SPARE_UI_7); /* ID: 981 */ + dataPoolAddr[982] = (void *)&(pdpIasw->SPARE_UI_8); /* ID: 982 */ + dataPoolAddr[983] = (void *)&(pdpIasw->SPARE_UI_9); /* ID: 983 */ + dataPoolAddr[984] = (void *)&(pdpIasw->SPARE_UI_10); /* ID: 984 */ + dataPoolAddr[985] = (void *)&(pdpIasw->SPARE_UI_11); /* ID: 985 */ + dataPoolAddr[986] = (void *)&(pdpIasw->SPARE_UI_12); /* ID: 986 */ + dataPoolAddr[987] = (void *)&(pdpIasw->SPARE_UI_13); /* ID: 987 */ + dataPoolAddr[988] = (void *)&(pdpIasw->SPARE_UI_14); /* ID: 988 */ + dataPoolAddr[989] = (void *)&(pdpIasw->SPARE_UI_15); /* ID: 989 */ + dataPoolAddr[990] = (void *)&(pdpIasw->SPARE_F_0); /* ID: 990 */ + dataPoolAddr[991] = (void *)&(pdpIasw->SPARE_F_1); /* ID: 991 */ + dataPoolAddr[992] = (void *)&(pdpIasw->SPARE_F_2); /* ID: 992 */ + dataPoolAddr[993] = (void *)&(pdpIasw->SPARE_F_3); /* ID: 993 */ + dataPoolAddr[994] = (void *)&(pdpIasw->SPARE_F_4); /* ID: 994 */ + dataPoolAddr[995] = (void *)&(pdpIasw->SPARE_F_5); /* ID: 995 */ + dataPoolAddr[996] = (void *)&(pdpIasw->SPARE_F_6); /* ID: 996 */ + dataPoolAddr[997] = (void *)&(pdpIasw->SPARE_F_7); /* ID: 997 */ + dataPoolAddr[998] = (void *)&(pdpIasw->SPARE_F_8); /* ID: 998 */ + dataPoolAddr[999] = (void *)&(pdpIasw->SPARE_F_9); /* ID: 999 */ + dataPoolAddr[1000] = (void *)&(pdpIasw->SPARE_F_10); /* ID: 1000 */ + dataPoolAddr[1001] = (void *)&(pdpIasw->SPARE_F_11); /* ID: 1001 */ + dataPoolAddr[1002] = (void *)&(pdpIasw->SPARE_F_12); /* ID: 1002 */ + dataPoolAddr[1003] = (void *)&(pdpIasw->SPARE_F_13); /* ID: 1003 */ + dataPoolAddr[1004] = (void *)&(pdpIasw->SPARE_F_14); /* ID: 1004 */ + dataPoolAddr[1005] = (void *)&(pdpIasw->SPARE_F_15); /* ID: 1005 */ + + return; +} +#endif /* PC_TARGET */ + +unsigned char GetFpmSide (unsigned char id) +{ + unsigned int i; + unsigned char myid; + + for (i=0; i<FEE_SCRIPTS; i++) + { + CrIaCopyArrayItem (FEE_SIDE_A_ID, &myid, i); + if (myid == id) + return FPM_SIDE_A; + } + + for (i=0; i<FEE_SCRIPTS; i++) + { + CrIaCopyArrayItem (FEE_SIDE_B_ID, &myid, i); + if (myid == id) + return FPM_SIDE_B; + } + + /* NOTE: in the case of an unknown id, we go ahead with side A */ + + return FPM_SIDE_A; +} + + +unsigned char GetRf (unsigned char id) +{ + unsigned int i; + unsigned char myid; + + for (i=0; i<FEE_SCRIPTS; i++) + { + CrIaCopyArrayItem (RF230_ID, &myid, i); + if (myid == id) + return RF230KHZ; + } + + for (i=0; i<FEE_SCRIPTS; i++) + { + CrIaCopyArrayItem (RF100_ID, &myid, i); + if (myid == id) + return RF100KHZ; + } + + /* NOTE: in the case of an unknown id, we use 230 kHz */ + + return RF230KHZ; +} + + +unsigned int GetDataPoolSize(unsigned int id) +{ + return dataPoolSize[id]; +} + +unsigned int GetDataPoolMult(unsigned int id) +{ + return dataPoolMult[id]; +} + + +void CrIa_Copy(unsigned int id, void * targetAddr, int tgtsize) +{ + int sizeOfTmType; + unsigned int i, dpvalue; + + sizeOfTmType = dataPoolSize[id]; + if (sizeOfTmType != tgtsize) + { + dpIbsw.BAD_COPY_ID = id; + return; + } + + /* the debug variables need special treatment, because the addresses are stored in DEBUG_VAR_ADDR */ + if (id == DEBUG_VAR_ID) + { + for (i=0; i < dataPoolMult[id]; i++) + { + CrIaCopyArrayItem(DEBUG_VAR_ADDR_ID, &dpvalue, i); /* get address of the address(!) into debugvar */ + + if (dpvalue == 0) /* NOTE: we do not check if invalid address. This is the user's responsibility */ + { + /* report the wrong address */ + memcpy (&((unsigned int *)targetAddr)[i], &dpvalue, 4); + } + else + { + memcpy (&((unsigned int *)targetAddr)[i], (unsigned int *)((unsigned long int)dpvalue), 4); + } + } + + return; + } + + /* all normal DP entries are treated hereafter */ + for (i=0; i < dataPoolMult[id]; i++) + { + dpvalue = ((unsigned int *)(dataPoolAddr[id]))[i]; + + switch (sizeOfTmType) + { + + case 1 : + { + ((unsigned char *)targetAddr)[i] = (unsigned char)(dpvalue & 0xff); + break; + } + + case 2 : + { + /* destination can be unaligned */ + ((unsigned char *)targetAddr)[2*i] = (unsigned char)((dpvalue >> 8) & 0xff); + ((unsigned char *)targetAddr)[2*i+1] = (unsigned char)(dpvalue & 0xff); + break; + } + + default : /* sizeOfTmType == 4 */ + { + /* destination can be unaligned */ + ((unsigned char *)targetAddr)[4*i] = (unsigned char)((dpvalue >> 24) & 0xff); + ((unsigned char *)targetAddr)[4*i+1] = (unsigned char)((dpvalue >> 16) & 0xff); + ((unsigned char *)targetAddr)[4*i+2] = (unsigned char)((dpvalue >> 8) & 0xff); + ((unsigned char *)targetAddr)[4*i+3] = (unsigned char)(dpvalue & 0xff); + break; + } + + } + } +} + +#ifdef PC_TARGET +/* copy ALL array elements of a parameter */ +void CrIa_Copy_PC(unsigned int id, void * targetAddr, int tgtsize) +{ + int sizeOfTmType, sizeOfImplType; + unsigned int i, debugvar; + void *dest, *src; + + /* determine size of telemetry and implementation types */ + sizeOfTmType = dataPoolSize[id]; + + sizeOfImplType = 4; /* NOTE: all our DP variables are implemented with a size of 4 */ + + if (tgtsize != sizeOfTmType) { + x_printf("COPY >> Pool ID: %d; arg size should be: %d, is %d caller: %lx\n", + id, sizeOfTmType, tgtsize, (unsigned long int)__builtin_return_address(0)); + return; + } + + /* Copy data item from data pool (where it is stored according to its */ + /* implementation type) to a location in the telemetry packet (where */ + /* it is stored according to its telemetry type) */ + + for (i=0; i < dataPoolMult[id]; i++) + { +#if (__sparc__) + dest = (void *)(((unsigned long int) targetAddr) + i * sizeOfTmType); + src = (void *)(((unsigned long int) dataPoolAddr[id]) + + (sizeOfImplType - sizeOfTmType) + i * sizeOfImplType); +#else + dest = (void *)((unsigned long int) targetAddr + i * sizeOfTmType); + src = (void *)((unsigned long int) dataPoolAddr[id] + i * sizeOfImplType); +#endif + +#if (__sparc__) + /* the debug variables need special treatment, because the addresses are stored in DEBUG_VAR_ADDR */ + if (id == DEBUG_VAR_ID) + { + debugvar = 0; + CrIaCopyArrayItem(DEBUG_VAR_ADDR_ID, &debugvar, i); /* get address of the address(!) into debugvar */ + src = (unsigned int *) debugvar; /* get the address of the value to debug into src */ + if (src == 0) /* NOTE: we do not check if this is an invalid address. This is the user's responsibility. */ + { + /* report the wrong address */ + src = (unsigned int *)(((unsigned long int)(dataPoolAddr[DEBUG_VAR_ADDR_ID])) + i * sizeOfImplType); + } + } +#else + (void) debugvar; +#endif + memcpy(dest, src, sizeOfTmType); + } +} +#endif + +#if !(__sparc__) +/* Copy ALL array elements of a parameter. + This function is needed on PC to swap + the endianess during the copy to a PUS packet. + Do not use it for transfer to local variables. */ +void CrIaCopyPcPckt(unsigned int id, void * targetAddr) +{ + int sizeOfTmType, sizeOfImplType; + unsigned int *src; + unsigned char *dest; + unsigned int value; + unsigned int i; + + /* determine size of telemetry and implementation types */ + sizeOfTmType = dataPoolSize[id]; + if (sizeOfTmType<5) + sizeOfImplType = 4; + else + sizeOfImplType = 8; + + /* Copy data item from data pool (where it is stored according to its */ + /* implementation type) to a location in the telemetry packet (where */ + /* it is stored according to its telemetry type) */ + + for (i=0; i<dataPoolMult[id]; i++) + { + src = (unsigned int *)(((unsigned long int)(dataPoolAddr[id])) + i * sizeOfImplType); + + value = *src; + + dest = ((unsigned char *)targetAddr) + i * sizeOfTmType; + + if (sizeOfTmType == 1) + { + dest[0] = value & 0xff; + } + else if (sizeOfTmType == 2) + { + dest[0] = (value >> 8) & 0xff; + dest[1] = value & 0xff; + } + else /* must be 4 */ + { + dest[0] = (value >> 24) & 0xff; + dest[1] = (value >> 16) & 0xff; + dest[2] = (value >> 8) & 0xff; + dest[3] = value & 0xff; + } + } +} +#endif + +/* Copy a single array element of a parameter */ +void CrIaCopyArrayItem(unsigned int id, void * targetAddr, unsigned int arrayElement) +{ + int sizeOfTmType, sizeOfImplType; + void *src; + + /* determine size of telemetry and implementation types */ + sizeOfTmType = dataPoolSize[id]; + + sizeOfImplType = 4; /* NOTE: all our DP variables are implemented with a size of 4 */ + + /* Copy data item from data pool (where it is stored according to its */ + /* implementation type) to a location in the telemetry packet (where */ + /* it is stored according to its telemetry type) */ + +#if (__sparc__) + src = (void *)(((unsigned long int) dataPoolAddr[id]) + + (sizeOfImplType - sizeOfTmType) + arrayElement * sizeOfImplType); +#else + src = (void *)(((unsigned long int) dataPoolAddr[id]) + arrayElement * sizeOfImplType); +#endif + + memcpy(targetAddr, src, sizeOfTmType); + +} + +#if PC_TARGET +/* Copy a single array element of a parameter. + * This function is needed on PC to swap + * the endianess during the copy to a PUS packet. + * Do not use it for transfer to local variables. +*/ +void CrIaCopyArrayItemPcPckt(unsigned int id, void * targetAddr, unsigned int arrayElement) +{ + int sizeOfTmType, sizeOfImplType; + unsigned int *src; + unsigned char *dest; + unsigned int value; + + /* determine size of telemetry and implementation types */ + sizeOfTmType = dataPoolSize[id]; + if (sizeOfTmType<5) + sizeOfImplType = 4; + else + sizeOfImplType = 8; + + /* Copy data item from data pool (where it is stored according to its + * implementation type) to a location in the telemetry packet (where + * it is stored according to its telemetry type) + */ + src = (unsigned int *)(((unsigned long int)(dataPoolAddr[id])) + arrayElement * sizeOfImplType); + value = *src; + + dest = (unsigned char *)targetAddr; + + if (sizeOfTmType == 1) + { + dest[0] = value & 0xff; + } + else if (sizeOfTmType == 2) + { + dest[0] = (value >> 8) & 0xff; + dest[1] = value & 0xff; + } + else /* must be 4 */ + { + dest[0] = (value >> 24) & 0xff; + dest[1] = (value >> 16) & 0xff; + dest[2] = (value >> 8) & 0xff; + dest[3] = value & 0xff; + } + + return; +} +#endif /* PC_TARGET */ + + +/* paste ALL array elements of a parameter */ +void CrIa_Paste(unsigned int id, void * sourceAddr, int tgtsize) +{ + int sizeOfTmType; + unsigned int i; + + /* determine size of telemetry and implementation types */ + sizeOfTmType = dataPoolSize[id]; + if (sizeOfTmType != tgtsize) + { + dpIbsw.BAD_PASTE_ID = id; + return; + } + + for (i=0; i < dataPoolMult[id]; i++) + { + + switch (sizeOfTmType) + { + + case 1 : + { + ((unsigned int *)(dataPoolAddr[id]))[i] = ((unsigned char *)sourceAddr)[i]; + break; + } + + case 2 : + { + ((unsigned int *)(dataPoolAddr[id]))[i] = ((unsigned short *)sourceAddr)[i]; + break; + } + + default : /* sizeOfTmType == 4 */ + { + ((unsigned int *)(dataPoolAddr[id]))[i] = ((unsigned int *)sourceAddr)[i]; + } + + } + } +} + + +#ifdef PC_TARGET +/* paste ALL array elements of a parameter */ +void CrIa_Paste_PC(unsigned int id, void * sourceAddr, int tgtsize) +{ + int sizeOfTmType, sizeOfImplType; + unsigned int i; + void *dest, *src; + + /* determine size of telemetry and implementation types */ + sizeOfTmType = dataPoolSize[id]; + + sizeOfImplType = 4; /* NOTE: all our DP variables are implemented with a size of 4 */ + + if (tgtsize != sizeOfTmType) + { + x_printf("PASTE >> Pool ID: %d; arg size should be: %d, is %d caller: %lx\n", + id, sizeOfTmType, tgtsize, (unsigned long int)__builtin_return_address(0)); + return; + } + + /* Copy data item from a location in the telemetry packet (where it + * is stored according to its telemetry type) to the data pool (where + * it is stored according to its implementation type) + */ + for (i=0; i < dataPoolMult[id]; i++) + { +#if (__sparc__) + dest = (void *)(((unsigned long int) dataPoolAddr[id]) + + (sizeOfImplType - sizeOfTmType) + i * sizeOfImplType); + src = (void *)(((unsigned long int) sourceAddr) + i * sizeOfTmType); +#else + dest = (void *)((unsigned long int) dataPoolAddr[id] + i * sizeOfImplType); + src = (void *)((unsigned long int) sourceAddr + i * sizeOfTmType); +#endif /* __sparc__ */ + + memcpy(dest, src, sizeOfTmType); /* RO last minute change from ImplType to TmType */ + } + + return; +} +#endif + +/* paste only a single element from a parameter array */ +void CrIaPasteArrayItem(unsigned int id, const void * sourceAddr, unsigned int arrayElement) +{ + int sizeOfTmType, sizeOfImplType; + void *dest; + + /* determine size of telemetry and implementation types */ + sizeOfTmType = dataPoolSize[id]; + + sizeOfImplType = 4; /* NOTE: all our DP variables are implemented with a size of 4 */ + +#if (__sparc__) + dest = (void *)(((unsigned long int) dataPoolAddr[id]) + + (sizeOfImplType - sizeOfTmType) + arrayElement*sizeOfImplType); +#else + dest = (void *)(((unsigned long int) dataPoolAddr[id]) + + arrayElement*sizeOfImplType); +#endif /* __sparc__ */ + + memcpy(dest, sourceAddr, sizeOfTmType); /* RO last minute change from ImplType to TmType */ + + return; +} + +#ifndef ISOLATED +void CrFwUpdateDataPool(FwSmDesc_t inManagerSem, + FwSmDesc_t inManagerGrdObc, + FwSmDesc_t outManager1, + FwSmDesc_t outManager2, + FwSmDesc_t outManager3, + FwSmDesc_t localInStreamSem, + FwSmDesc_t localInStreamObc, + FwSmDesc_t localInStreamGrd, + FwSmDesc_t localOutStreamSem, + FwSmDesc_t localOutStreamObc, + FwSmDesc_t localOutStreamGrd) +{ + unsigned char temp_uchar; + char temp_char; + unsigned short temp_ushort; + short temp_short; + unsigned int temp_uint; + int temp_int; + + unsigned short sm_state, esm_state; + unsigned short pr_state; + unsigned int sm_state_cnt; + unsigned int pr_state_cnt; + FwSmDesc_t smDescSemOper; + + (void) temp_uchar; + (void) temp_char; + (void) temp_ushort; + (void) temp_short; + (void) temp_uint; + (void) temp_int; + + /****************************************/ + /* update all items from DataPoolCordet */ + /****************************************/ + + /* InFactory */ + + temp_uchar = CrFwInFactoryGetNOfAllocatedInRep(); + CrIaPaste(NOFALLOCATEDINREP_ID, &temp_uchar); + + temp_uchar = CrFwInFactoryGetMaxNOfInRep(); + CrIaPaste(MAXNOFINREP_ID, &temp_uchar); + + temp_uchar = CrFwInFactoryGetNOfAllocatedInCmd(); + CrIaPaste(NOFALLOCATEDINCMD_ID, &temp_uchar); + + temp_uchar = CrFwInFactoryGetMaxNOfInCmd(); + CrIaPaste(MAXNOFINCMD_ID, &temp_uchar); + + /* InManager SEM */ + + temp_uchar = CrFwInManagerGetNOfPendingInCmp(inManagerSem); + CrIaPaste(SEM_NOFPENDINGINCMP_ID, &temp_uchar); + /* DEBUGP("\n\n\nCrFwInManagerGetNOfPendingInCmp(inManagerSem) = %d\n", temp_uchar); */ + + temp_uchar = CrFwInManagerGetPCRLSize(inManagerSem); + CrIaPaste(SEM_PCRLSIZE_ID, &temp_uchar); + + temp_uchar = CrFwInManagerGetNOfLoadedInCmp(inManagerSem); + CrIaPaste(SEM_NOFLOADEDINCMP_ID, &temp_uchar); + /* DEBUGP("CrFwInManagerGetNOfLoadedInCmp(inManagerSem) = %d\n", temp_uchar); */ + + /* InManager GRD/OBC */ + + temp_uchar = CrFwInManagerGetNOfPendingInCmp(inManagerGrdObc); + CrIaPaste(GRDOBC_NOFPENDINGINCMP_ID, &temp_uchar); + + temp_uchar = CrFwInManagerGetPCRLSize(inManagerGrdObc); + CrIaPaste(GRDOBC_PCRLSIZE_ID, &temp_uchar); + + /* OutFactory */ + + temp_uchar = CrFwOutFactoryGetNOfAllocatedOutCmp(); + CrIaPaste(NOFALLOCATEDOUTCMP_ID, &temp_uchar); + + temp_uchar = CrFwOutFactoryGetMaxNOfOutCmp(); + CrIaPaste(MAXNOFOUTCMP_ID, &temp_uchar); + + temp_ushort = (unsigned short)(CrFwOutFactoryGetNOfInstanceId() & 0xffff); + CrIaPaste(NOFINSTANCEID_ID, &temp_ushort); + + + /* Out Manager 1 */ + + temp_uchar = CrFwOutManagerGetNOfPendingOutCmp(outManager1); + CrIaPaste(OUTMG1_NOFPENDINGOUTCMP_ID, &temp_uchar); + + temp_uchar = CrFwOutManagerGetPOCLSize(outManager1); + CrIaPaste(OUTMG1_POCLSIZE_ID, &temp_uchar); + + temp_ushort = CrFwOutManagerGetNOfLoadedOutCmp(outManager1); + CrIaPaste(OUTMG1_NOFLOADEDOUTCMP_ID, &temp_ushort); + + /* Out Manager 2 */ + + temp_uchar = CrFwOutManagerGetNOfPendingOutCmp(outManager2); + CrIaPaste(OUTMG2_NOFPENDINGOUTCMP_ID, &temp_uchar); + + temp_uchar = CrFwOutManagerGetPOCLSize(outManager2); + CrIaPaste(OUTMG2_POCLSIZE_ID, &temp_uchar); + + temp_ushort = CrFwOutManagerGetNOfLoadedOutCmp(outManager2); + CrIaPaste(OUTMG2_NOFLOADEDOUTCMP_ID, &temp_ushort); + + /* Out Manager 3 */ + + temp_uchar = CrFwOutManagerGetNOfPendingOutCmp(outManager3); + CrIaPaste(OUTMG3_NOFPENDINGOUTCMP_ID, &temp_uchar); + + temp_uchar = CrFwOutManagerGetPOCLSize(outManager3); + CrIaPaste(OUTMG3_POCLSIZE_ID, &temp_uchar); + + temp_ushort = CrFwOutManagerGetNOfLoadedOutCmp(outManager3); + CrIaPaste(OUTMG3_NOFLOADEDOUTCMP_ID, &temp_ushort); + + /* InStream SEM */ + + temp_uint = CrFwInStreamGetSeqCnt(localInStreamSem, 0); /* group = 0, PCAT = 1 */ + CrIaPaste(INSEM_SEQCNT_ID, &temp_uint); + /* DEBUGP("CrFwInStreamGetSeqCnt(localInStreamSem, 0) = %d\n", temp_uint); */ + + temp_ushort = CrFwInStreamGetNOfPendingPckts(localInStreamSem); + CrIaPaste(INSEM_NOFPENDINGPCKTS_ID, &temp_ushort); + /* DEBUGP("CrFwInStreamGetNOfPendingPckts(localInStreamSem) = %d\n", temp_ushort); */ + + temp_uchar = CrFwInStreamGetNOfGroups(localInStreamSem); + CrIaPaste(INSEM_NOFGROUPS_ID, &temp_uchar); + + temp_uchar = CrFwInStreamGetPcktQueueSize(localInStreamSem); + CrIaPaste(INSEM_PCKTQUEUESIZE_ID, &temp_uchar); + + /* have to be set asynchron */ + /*temp_uchar = CrFwInRepGetSrc(localInStreamSem);*/ /* CrFwInCmdGetSrc(localInStreamSem) not used, no InCmd from SEM */ + /*CrIaPaste(INSEM_SRC_ID, &temp_uchar);*/ + + /* InStream OBC */ + + temp_uchar = CrFwInStreamGetNOfPendingPckts(localInStreamObc); + CrIaPaste(INOBC_NOFPENDINGPCKTS_ID, &temp_uchar); + + temp_uchar = CrFwInStreamGetNOfGroups(localInStreamObc); + CrIaPaste(INOBC_NOFGROUPS_ID, &temp_uchar); + + temp_uchar = CrFwInStreamGetPcktQueueSize(localInStreamObc); + CrIaPaste(INOBC_PCKTQUEUESIZE_ID, &temp_uchar); + + /* have to be set asynchron */ + /*temp_uchar = CrFwInCmdGetSrc(localInStreamObc);*/ /* CrFwInRepGetSrc(localInStreamObc) not used, no InRep from OBC */ + /*CrIaPaste(INOBC_SRC_ID, &temp_uchar);*/ + + /* InStream GRD */ + + temp_uchar = CrFwInStreamGetNOfPendingPckts(localInStreamGrd); + CrIaPaste(INGRD_NOFPENDINGPCKTS_ID, &temp_uchar); + /* DEBUGP("CrFwInStreamGetNOfPendingPckts(localInStreamGrd) = %d\n\n\n", temp_uchar);*/ + + temp_uchar = CrFwInStreamGetNOfGroups(localInStreamGrd); + CrIaPaste(INGRD_NOFGROUPS_ID, &temp_uchar); + + temp_uchar = CrFwInStreamGetPcktQueueSize(localInStreamGrd); + CrIaPaste(INGRD_PCKTQUEUESIZE_ID, &temp_uchar); + + /* have to be set asynchron */ + /*temp_uchar = CrFwInCmdGetSrc(localInStreamGrd);*/ /* CrFwInRepGetSrc(localInStreamGrd) not used, no InRep from GRD */ + /*CrIaPaste(INGRD_SRC_ID, &temp_uchar);*/ + + /* OutStream SEM */ + + temp_uchar = CrFwOutStreamGetDest(localOutStreamSem); + CrIaPaste(OUTSEM_DEST_ID, &temp_uchar); + + temp_uint = CrFwOutStreamGetSeqCnt(localOutStreamSem, 0); /* group = 0, PCAT = 1 */ + CrIaPaste(OUTSEM_SEQCNT_ID, &temp_uint); + + temp_uchar = CrFwOutStreamGetNOfPendingPckts(localOutStreamSem); + CrIaPaste(OUTSEM_NOFPENDINGPCKTS_ID, &temp_uchar); + + temp_uchar = CrFwOutStreamGetNOfGroups(localOutStreamSem); + CrIaPaste(OUTSEM_NOFGROUPS_ID, &temp_uchar); + + temp_uchar = CrFwOutStreamGetPcktQueueSize(localOutStreamSem); + CrIaPaste(OUTSEM_PCKTQUEUESIZE_ID, &temp_uchar); + + /* OutStream OBC */ + + temp_uchar = CrFwOutStreamGetDest(localOutStreamObc); + CrIaPaste(OUTOBC_DEST_ID, &temp_uchar); + + temp_uint = CrFwOutStreamGetSeqCnt(localOutStreamObc, 0); /* group = 0, PCAT = 1 */ + CrIaPaste(OUTOBC_SEQCNT_GROUP0_ID, &temp_uint); + + temp_uint = CrFwOutStreamGetSeqCnt(localOutStreamObc, 1); /* group = 1, PCAT = 2 */ + CrIaPaste(OUTOBC_SEQCNT_GROUP1_ID, &temp_uint); + + temp_uchar = CrFwOutStreamGetNOfPendingPckts(localOutStreamObc); + CrIaPaste(OUTOBC_NOFPENDINGPCKTS_ID, &temp_uchar); + + temp_uchar = CrFwOutStreamGetNOfGroups(localOutStreamObc); + CrIaPaste(OUTOBC_NOFGROUPS_ID, &temp_uchar); + + temp_uchar = CrFwOutStreamGetPcktQueueSize(localOutStreamObc); + CrIaPaste(OUTOBC_PCKTQUEUESIZE_ID, &temp_uchar); + + /* OutStream GRD */ + + temp_uchar = CrFwOutStreamGetDest(localOutStreamGrd); + CrIaPaste(OUTGRD_DEST_ID, &temp_uchar); + + temp_uint = CrFwOutStreamGetSeqCnt(localOutStreamGrd, 0); /* group = 0, PCAT = 1 */ + CrIaPaste(OUTGRD_SEQCNT_GROUP0_ID, &temp_uint); + + temp_uint = CrFwOutStreamGetSeqCnt(localOutStreamGrd, 1); /* group = 1, PCAT = 2 */ + CrIaPaste(OUTGRD_SEQCNT_GROUP1_ID, &temp_uint); + + temp_uint = CrFwOutStreamGetSeqCnt(localOutStreamGrd, 2); /* group = 2, PCAT = 3 */ + CrIaPaste(OUTGRD_SEQCNT_GROUP2_ID, &temp_uint); + + temp_uchar = CrFwOutStreamGetNOfPendingPckts(localOutStreamGrd); + CrIaPaste(OUTGRD_NOFPENDINGPCKTS_ID, &temp_uchar); + + temp_uchar = CrFwOutStreamGetNOfGroups(localOutStreamGrd); + CrIaPaste(OUTGRD_NOFGROUPS_ID, &temp_uchar); + + temp_uchar = CrFwOutStreamGetPcktQueueSize(localOutStreamGrd); + CrIaPaste(OUTGRD_PCKTQUEUESIZE_ID, &temp_uchar); + + /****************************************/ + /* update all SM states */ + /****************************************/ + + sm_state = FwSmGetCurState(smDescIasw); + CrIaPaste(IASWSTATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescIasw); + CrIaPaste(IASWSTATECNT_ID, &sm_state_cnt); + sm_state_cnt = FwSmGetExecCnt(smDescIasw); + CrIaPaste(IASWCYCLECNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescSem); + CrIaPaste(SEMSTATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescSem); + CrIaPaste(SEMSTATECNT_ID, &sm_state_cnt); + + esm_state = FwSmGetCurStateEmb(smDescSem); + CrIaPaste(SEMOPERSTATE_ID, &esm_state); + /* Get the SEM Oper SM which is embedded in the current state of the SEM SM. + * This function returns either a SM Description (if there is a SM embedded + * in the current state of the SEM SM) or NULL (if there is no SM embedded + * in the current state of the SEM SM). */ + smDescSemOper = FwSmGetEmbSmCur(smDescSem); + if (smDescSemOper != NULL) + sm_state_cnt = FwSmGetStateExecCnt(smDescSemOper); + else + sm_state_cnt = 0; + CrIaPaste(SEMOPERSTATECNT_ID, &sm_state_cnt); + + /* FdCheck */ + sm_state = FwSmGetCurState(smDescFdTelescopeTempMonitorCheck); + CrIaPaste(FDCHECKTTMSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdIncorrectSDSCntrCheck); + CrIaPaste(FDCHECKSDSCSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdSemCommErrCheck); + CrIaPaste(FDCHECKCOMERRSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdSemModeTimeOutCheck); + CrIaPaste(FDCHECKTIMEOUTSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdSemSafeModeCheck); + CrIaPaste(FDCHECKSAFEMODESTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdSemAliveCheck); + CrIaPaste(FDCHECKALIVESTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdSemAnomalyEventCheck); + CrIaPaste(FDCHECKSEMANOEVTSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdSemLimitCheck); + CrIaPaste(FDCHECKSEMLIMITSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdDpuHousekeepingCheck); + CrIaPaste(FDCHECKDPUHKSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdCentroidConsistencyCheck); + CrIaPaste(FDCHECKCENTCONSSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdResourceCheck); + CrIaPaste(FDCHECKRESSTATE_ID, &sm_state); + + sm_state = FwSmGetCurState(smDescFdSemModeConsistencyCheck); + CrIaPaste(FDCHECKSEMCONS_ID, &sm_state); + + /* SDU */ + sm_state = FwSmGetCurState(smDescSdu2); + CrIaPaste(SDU2STATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescSdu2); + CrIaPaste(SDU2STATECNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescSdu4); + CrIaPaste(SDU4STATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescSdu4); + CrIaPaste(SDU4STATECNT_ID, &sm_state_cnt); + + /* SDB */ + sm_state = FwSmGetCurState(smDescSdb); + CrIaPaste(SDBSTATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescSdb); + CrIaPaste(SDBSTATECNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoCent0); + CrIaPaste(ALGOCENT0STATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoCent0); + CrIaPaste(ALGOCENT0CNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoCent1); + CrIaPaste(ALGOCENT1STATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoCent1); + CrIaPaste(ALGOCENT1CNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoAcq1); + CrIaPaste(ALGOACQ1STATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoAcq1); + CrIaPaste(ALGOACQ1CNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoCmpr); + CrIaPaste(ALGOCCSTATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoCmpr); + CrIaPaste(ALGOCCCNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoTtc1); + CrIaPaste(ALGOTTC1STATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoTtc1); + CrIaPaste(ALGOTTC1CNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoTtc2); + CrIaPaste(ALGOTTC2STATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoTtc2); + CrIaPaste(ALGOTTC2CNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoSaaEval); + CrIaPaste(ALGOSAAEVALSTATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoSaaEval); + CrIaPaste(ALGOSAAEVALCNT_ID, &sm_state_cnt); + + sm_state = FwSmGetCurState(smDescAlgoSdsEval); + CrIaPaste(ALGOSDSEVALSTATE_ID, &sm_state); + sm_state_cnt = FwSmGetStateExecCnt(smDescAlgoSdsEval); + CrIaPaste(ALGOSDSEVALCNT_ID, &sm_state_cnt); + + /****************************************/ + /* update all PR states */ + /****************************************/ + + /* 1 - SAVE_IMG_PR */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescSaveImages) & 0xffff); + CrIaPaste(SAVEIMAGESNODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescSaveImages); + CrIaPaste(SAVEIMAGESCNT_ID, &pr_state_cnt); + + /* 2 - ACQ_FULL_DROP */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescAcqFullDrop) & 0xffff); + CrIaPaste(ACQFULLDROPNODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescAcqFullDrop); + CrIaPaste(ACQFULLDROPCNT_ID, &pr_state_cnt); + + /* 3 - CAL_FULL_SNAP */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescCalFullSnap) & 0xffff); + CrIaPaste(CALFULLSNAPNODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescCalFullSnap); + CrIaPaste(CALFULLSNAPCNT_ID, &pr_state_cnt); + + /* 4 - FBF_LOAD_PR */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescFbfLoad) & 0xffff); + CrIaPaste(FBFLOADNODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescFbfLoad); + CrIaPaste(FBFLOADCNT_ID, &pr_state_cnt); + + /* 5 - FBF_SAVE_PR */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescFbfSave) & 0xffff); + CrIaPaste(FBFSAVENODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescFbfSave); + CrIaPaste(FBFSAVECNT_ID, &pr_state_cnt); + + /* 6 - SCI_STACK_PR */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescSciStack) & 0xffff); + CrIaPaste(SCIWINNODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescFbfSave); + CrIaPaste(SCIWINCNT_ID, &pr_state_cnt); + + /* 7 - FBF_TO_GND_PR */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescTransferFbfToGround) & 0xffff); + CrIaPaste(TRANSFBFTOGRNDNODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescTransferFbfToGround); + CrIaPaste(TRANSFBFTOGRNDCNT_ID, &pr_state_cnt); + + /* 8 - NOM_SCI_PR */ + pr_state = (unsigned short) (FwPrGetCurNode(prDescNomSci) & 0xffff); + CrIaPaste(NOMSCINODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescNomSci); + CrIaPaste(NOMSCICNT_ID, &pr_state_cnt); + + /* 9 - CONFIG_SDB_PR */ + /* NOTE: update of the state is done in CrIaServ198ProcStartProgressAction() */ + + pr_state = (unsigned short) (FwPrGetCurNode(prDescPrepSci) & 0xffff); + CrIaPaste(PREPSCIENCENODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescPrepSci); + CrIaPaste(PREPSCIENCECNT_ID, &pr_state_cnt); + + pr_state = (unsigned short) (FwPrGetCurNode(prDescCtrldSwitchOffIasw) & 0xffff); + CrIaPaste(CONTROLLEDSWITCHOFFNODE_ID, &pr_state); + pr_state_cnt = FwPrGetNodeExecCnt(prDescCtrldSwitchOffIasw); + CrIaPaste(CONTROLLEDSWITCHOFFCNT_ID, &pr_state_cnt); + + return; +} +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CrIa/src/CrIaDataPool.h b/CrIa/src/CrIaDataPool.h new file mode 100644 index 0000000000000000000000000000000000000000..0e5cd2cb2b072e29a0f462b12d3ee46669341d0e --- /dev/null +++ b/CrIa/src/CrIaDataPool.h @@ -0,0 +1,1316 @@ +/** +* @file +* Interface for accessing data pool items. +* +* A data pool is created by three structures encapsulating data related +* to CORDET Framework, IASW and IBSW. +* +* These data items can be accessed directly by accessing structure items. +* Use in application code these declarations: +* +* \li \c <code>extern DataPoolCordet dpCordet;</code> +* \li \c <code>extern DataPoolIasw dpIasw;</code> +* \li \c <code>extern DataPoolIbsw dpIbsw;</code> +* +* The data pool items can be also accessed by provided functions. These function +* allows reading and modifying the data pool items by an unique identifier. +* +* For implementation reasons, the type of all items in the data pool is set +* such that the size of the data item is a multiple of 4 bytes. +* Thus, each data item has a "telemetry type" (the type of the data item as +* it appears in telemetry) and an "implementation type" (the type of the data +* item as it is implemented in the data pool). The latter has a size which is +* a multiple of 4 bytes. The Data Pool Component knows about the size of +* the telemetry types which is stored in private array "dataPoolSize". +* +* Data items in the data pool may be either of primitive type or of array type. +* To each data item a multiplicity is associated. +* If the multiplicity is equal to 1, then the data item is of primitive type. +* If the multiplicity is greater than 1, then the data type is of array type +* and the multiplicity is the size of the array. +* The multplicity information is stored in private array "dataPoolMult". +* +* The definition of the data pool in this header file is derived from the +* IFSW Configuration File. +* The IFSW Configuration File defines constants in addition to data items. +* The constants are implemented as <code>#define</code> constants. +* +* @note This code was generated. +* @authors V. Cechticky and A. Pasetti +* @copyright P&P Software GmbH, 2015, All Rights Reserved +*/ + +#ifndef CRIADATAPOOL_H_ +#define CRIADATAPOOL_H_ + +#ifndef ISOLATED +/* Includes */ +#include <CrFwConstants.h> +#endif + +/* + NOTE: the __BUILD_ID is a defsym provided to the linker + + Its format is: 0xGGGGMMCC, where + GGGG is the git-inspired buildnumber + MM is the major version of the SW, + CC the compression entity version + + MMCC is what we put in the CE as "Version" + */ +#if (__sparc__) +extern unsigned char __BUILD_ID; + +#define BUILD ((unsigned long int)&__BUILD_ID) +#define VERSION ((unsigned short)(0xffff & (unsigned long int)&__BUILD_ID)) +#else +#define BUILD BUILD_ID +#define VERSION ((unsigned short)(0xffff & BUILD_ID)) +#endif + + +#define NMB_LIMIT_CHECK_MAX 50 + +/** Definition of data pool constants */ +#define DP_ID_MAX 1005 +#define SDB_SIZE 33554416 +#define SID_MAX 50 +#define RDL_SIZE 10 +#define RD_MAX_ITEMS 250 +#define RD_MAX_SIZE 1024 +#define N_DEBUG_VAR 20 +#define VALID_RAM_ADDR 1073741824 +#define N_EVT_ID 60 +#define S13_MIN_BLOCK_SIZE 200 +#define N_CENT_ALGO 2 +#define CENT_EXEC_PER 0 +#define N_ACQ_ALGO 1 +#define ACQ_EXEC_PHASE 0 +#define ACQ_EXEC_PER -1 +#define N_TTC_ALGO 2 +#define SEM_EVT_STORE_SIZE 32000 +#define HBSEM_MON_PER 160 +#define HBSEM_MON_LIM 6 +#define ERR_LOG_N1 64 +#define ERR_LOG_N2 12 +#define ERR_LOG_N3 10 +#define MAX_SIZE_SMALL_PCKT 128 +#define N_PCKT_SMALL 67 +#define N_PCKT_LARGE 220 +#define FBF_NFILES 250 +#define FBF_SIZE 4 +#define DPU_OBC_LINK_CAPACITY 2048 +#define N_RT_CONT 5 +#define RT_CONT1_ID 1 +#define RT_CONT2_ID 2 +#define RT_CONT3_ID 3 +#define RT_CONT4_ID 4 +#define RT_CONT5_ID 5 +#define SRC_PACKET_MIN_SIZE 12 +#define MAXNROFSTARS 60 +#define SPLINE_SEGMENTS 28 +#define BITOFFSET_SIZE 96 +#define MAX_DUMP_SIZE 996 /* PnP TM/TC ICD 001 i3.0 */ +#define ADS_PARAM_OFFSET 212010000U +#define FID_MAX 13 +#define MAX_ID_ALGO 11 +#define MAX_ID_PROC 9 + +#define FEE_SCRIPTS 12 /* SEM ICD 2.4 */ +#define RF100KHZ 100 +#define RF230KHZ 230 + + +extern struct DataPoolCordet dpCordet; +extern struct DataPoolIasw dpIasw; +extern struct DataPoolIbsw dpIbsw; + +extern unsigned int useMaxAcquisitionNum; /* Mantis 2168 */ + + +/** The structure holding data pool variables and parameter items for CORDET. */ +struct DataPoolCordet { + unsigned int AppErrCode; + unsigned int NofAllocatedInRep; + unsigned int MaxNOfInRep; + unsigned int NofAllocatedInCmd; + unsigned int MaxNOfInCmd; + unsigned int Sem_NOfPendingInCmp; + unsigned int Sem_PCRLSize; + unsigned int Sem_NOfLoadedInCmp; + unsigned int GrdObc_NOfPendingInCmp; + unsigned int GrdObc_PCRLSize; + unsigned int NOfAllocatedOutCmp; + unsigned int MaxNOfOutCmp; + unsigned int NOfInstanceId; + unsigned int OutMg1_NOfPendingOutCmp; + unsigned int OutMg1_POCLSize; + unsigned int OutMg1_NOfLoadedOutCmp; + unsigned int OutMg2_NOfPendingOutCmp; + unsigned int OutMg2_POCLSize; + unsigned int OutMg2_NOfLoadedOutCmp; + unsigned int OutMg3_NOfPendingOutCmp; + unsigned int OutMg3_POCLSize; + unsigned int OutMg3_NOfLoadedOutCmp; + unsigned int InSem_SeqCnt; + unsigned int InSem_NOfPendingPckts; + unsigned int InSem_NOfGroups; + unsigned int InSem_PcktQueueSize; + unsigned int InSem_Src; + unsigned int InObc_NOfPendingPckts; + unsigned int InObc_NOfGroups; + unsigned int InObc_PcktQueueSize; + unsigned int InObc_Src; + unsigned int InGrd_NOfPendingPckts; + unsigned int InGrd_NOfGroups; + unsigned int InGrd_PcktQueueSize; + unsigned int InGrd_Src; + unsigned int OutSem_Dest; + unsigned int OutSem_SeqCnt; + unsigned int OutSem_NOfPendingPckts; + unsigned int OutSem_NOfGroups; + unsigned int OutSem_PcktQueueSize; + unsigned int OutObc_Dest; + unsigned int OutObc_SeqCnt_Group0; + unsigned int OutObc_SeqCnt_Group1; + unsigned int OutObc_NOfPendingPckts; + unsigned int OutObc_NOfGroups; + unsigned int OutObc_PcktQueueSize; + unsigned int OutGrd_Dest; + unsigned int OutGrd_SeqCnt_Group0; + unsigned int OutGrd_SeqCnt_Group1; + unsigned int OutGrd_SeqCnt_Group2; + unsigned int OutGrd_NOfPendingPckts; + unsigned int OutGrd_NOfGroups; + unsigned int OutGrd_PcktQueueSize; +} ; + +/** The structure holding data pool variables and parameter items for IASW. */ +struct DataPoolIasw { + unsigned int buildNumber; + unsigned int sibNFull; + unsigned int cibNFull; + unsigned int gibNFull; + unsigned int sibNWin; + unsigned int cibNWin; + unsigned int gibNWin; + unsigned int sibSizeFull; + unsigned int cibSizeFull; + unsigned int gibSizeFull; + unsigned int sibSizeWin; + unsigned int cibSizeWin; + unsigned int gibSizeWin; + unsigned int sibIn; + unsigned int sibOut; + unsigned int cibIn; + unsigned int gibIn; + unsigned int gibOut; + int sdbState; + unsigned int sdbStateCnt; + int OffsetX; + int OffsetY; + int TargetLocationX; + int TargetLocationY; + unsigned int IntegStartTimeCrs; + unsigned int IntegStartTimeFine; + unsigned int IntegEndTimeCrs; + unsigned int IntegEndTimeFine; + unsigned int DataCadence; + int ValidityStatus; + unsigned int NOfTcAcc; + unsigned int NOfAccFailedTc; + unsigned int SeqCntLastAccTcFromObc; + unsigned int SeqCntLastAccTcFromGrd; + unsigned int SeqCntLastAccFailTc; + unsigned int NOfStartFailedTc; + unsigned int SeqCntLastStartFailTc; + unsigned int NOfTcTerm; + unsigned int NOfTermFailedTc; + unsigned int SeqCntLastTermFailTc; + unsigned int RdlSidList[10]; + int isRdlFree[10]; + unsigned int RdlCycCntList[10]; + unsigned int RdlPeriodList[10]; + int RdlEnabledList[10]; + unsigned int RdlDestList[10]; + unsigned int RdlDataItemList_0[250]; + unsigned int RdlDataItemList_1[250]; + unsigned int RdlDataItemList_2[250]; + unsigned int RdlDataItemList_3[250]; + unsigned int RdlDataItemList_4[250]; + unsigned int RdlDataItemList_5[250]; + unsigned int RdlDataItemList_6[250]; + unsigned int RdlDataItemList_7[250]; + unsigned int RdlDataItemList_8[250]; + unsigned int RdlDataItemList_9[250]; + unsigned int DEBUG_VAR[20]; + unsigned int DEBUG_VAR_ADDR[20]; + unsigned int EVTFILTERDEF; + unsigned int evtEnabledList[60]; + unsigned int lastPatchedAddr; + unsigned int lastDumpAddr; + int sdu2State; + int sdu4State; + unsigned int sdu2StateCnt; + unsigned int sdu4StateCnt; + unsigned int sdu2BlockCnt; + unsigned int sdu4BlockCnt; + unsigned int sdu2RemSize; + unsigned int sdu4RemSize; + unsigned int sdu2DownTransferSize; + unsigned int sdu4DownTransferSize; + unsigned int sdsCounter; + int FdGlbEnable; + int RpGlbEnable; + int FdCheckTTMState; + int FdCheckTTMIntEn; + int FdCheckTTMExtEn; + int RpTTMIntEn; + int RpTTMExtEn; + unsigned int FdCheckTTMCnt; + unsigned int FdCheckTTMSpCnt; + unsigned int FdCheckTTMCntThr; + float TTC_LL; + float TTC_UL; + float TTM_LIM; + int FdCheckSDSCState; + int FdCheckSDSCIntEn; + int FdCheckSDSCExtEn; + int RpSDSCIntEn; + int RpSDSCExtEn; + unsigned int FdCheckSDSCCnt; + unsigned int FdCheckSDSCSpCnt; + unsigned int FdCheckSDSCCntThr; + int FdCheckComErrState; + int FdCheckComErrIntEn; + int FdCheckComErrExtEn; + int RpComErrIntEn; + int RpComErrExtEn; + unsigned int FdCheckComErrCnt; + unsigned int FdCheckComErrSpCnt; + unsigned int FdCheckComErrCntThr; + int FdCheckTimeOutState; + int FdCheckTimeOutIntEn; + int FdCheckTimeOutExtEn; + int RpTimeOutIntEn; + int RpTimeOutExtEn; + unsigned int FdCheckTimeOutCnt; + unsigned int FdCheckTimeOutSpCnt; + unsigned int FdCheckTimeOutCntThr; + unsigned int SEM_TO_POWERON; + unsigned int SEM_TO_SAFE; + unsigned int SEM_TO_STAB; + unsigned int SEM_TO_TEMP; + unsigned int SEM_TO_CCD; + unsigned int SEM_TO_DIAG; + unsigned int SEM_TO_STANDBY; + int FdCheckSafeModeState; + int FdCheckSafeModeIntEn; + int FdCheckSafeModeExtEn; + int RpSafeModeIntEn; + int RpSafeModeExtEn; + unsigned int FdCheckSafeModeCnt; + unsigned int FdCheckSafeModeSpCnt; + unsigned int FdCheckSafeModeCntThr; + int FdCheckAliveState; + int FdCheckAliveIntEn; + int FdCheckAliveExtEn; + int RpAliveIntEn; + int RpAliveExtEn; + unsigned int FdCheckAliveCnt; + unsigned int FdCheckAliveSpCnt; + unsigned int FdCheckAliveCntThr; + unsigned int SEM_HK_DEF_PER; + unsigned int SEMALIVE_DELAYEDSEMHK; + int FdCheckSemAnoEvtState; + int FdCheckSemAnoEvtIntEn; + int FdCheckSemAnoEvtExtEn; + int RpSemAnoEvtIntEn; + int RpSemAnoEvtExtEn; + unsigned int FdCheckSemAnoEvtCnt; + unsigned int FdCheckSemAnoEvtSpCnt; + unsigned int FdCheckSemAnoEvtCntThr; + int semAnoEvtResp_1; + int semAnoEvtResp_2; + int semAnoEvtResp_3; + int semAnoEvtResp_4; + int semAnoEvtResp_5; + int semAnoEvtResp_6; + int semAnoEvtResp_7; + int semAnoEvtResp_8; + int semAnoEvtResp_9; + int semAnoEvtResp_10; + int semAnoEvtResp_11; + int semAnoEvtResp_12; + int semAnoEvtResp_13; + int semAnoEvtResp_14; + int semAnoEvtResp_15; + int semAnoEvtResp_16; + int semAnoEvtResp_17; + int semAnoEvtResp_18; + int semAnoEvtResp_19; + int semAnoEvtResp_20; + int semAnoEvtResp_21; + int semAnoEvtResp_22; + int semAnoEvtResp_23; + int semAnoEvtResp_24; + int semAnoEvtResp_25; + int semAnoEvtResp_26; + int semAnoEvtResp_27; + int semAnoEvtResp_28; + int semAnoEvtResp_29; + int FdCheckSemLimitState; + int FdCheckSemLimitIntEn; + int FdCheckSemLimitExtEn; + int RpSemLimitIntEn; + int RpSemLimitExtEn; + unsigned int FdCheckSemLimitCnt; + unsigned int FdCheckSemLimitSpCnt; + unsigned int FdCheckSemLimitCntThr; + unsigned int SEM_LIM_DEL_T; + int FdCheckDpuHkState; + int FdCheckDpuHkIntEn; + int FdCheckDpuHkExtEn; + int RpDpuHkIntEn; + int RpDpuHkExtEn; + unsigned int FdCheckDpuHkCnt; + unsigned int FdCheckDpuHkSpCnt; + unsigned int FdCheckDpuHkCntThr; + int FdCheckCentConsState; + int FdCheckCentConsIntEn; + int FdCheckCentConsExtEn; + int RpCentConsIntEn; + int RpCentConsExtEn; + unsigned int FdCheckCentConsCnt; + unsigned int FdCheckCentConsSpCnt; + unsigned int FdCheckCentConsCntThr; + int FdCheckResState; + int FdCheckResIntEn; + int FdCheckResExtEn; + int RpResIntEn; + int RpResExtEn; + unsigned int FdCheckResCnt; + unsigned int FdCheckResSpCnt; + unsigned int FdCheckResCntThr; + float CPU1_USAGE_MAX; + float MEM_USAGE_MAX; + int FdCheckSemCons; + int FdCheckSemConsIntEn; + int FdCheckSemConsExtEn; + int RpSemConsIntEn; + int RpSemConsExtEn; + unsigned int FdCheckSemConsCnt; + unsigned int FdCheckSemConsSpCnt; + unsigned int FdCheckSemConsCntThr; + int semState; + int semOperState; + unsigned int semStateCnt; + unsigned int semOperStateCnt; + unsigned int imageCycleCnt; + unsigned int acqImageCnt; + int sciSubMode; + int LastSemPckt; + unsigned int SEM_ON_CODE; + unsigned int SEM_OFF_CODE; + unsigned int SEM_INIT_T1; + unsigned int SEM_INIT_T2; + unsigned int SEM_OPER_T1; + unsigned int SEM_SHUTDOWN_T1; + unsigned int SEM_SHUTDOWN_T11; + unsigned int SEM_SHUTDOWN_T12; + unsigned int SEM_SHUTDOWN_T2; + int iaswState; + unsigned int iaswStateCnt; + unsigned int iaswCycleCnt; + int prepScienceNode; + unsigned int prepScienceCnt; + int controlledSwitchOffNode; + unsigned int controlledSwitchOffCnt; + unsigned int CTRLD_SWITCH_OFF_T1; + int algoCent0State; + unsigned int algoCent0Cnt; + int algoCent0Enabled; + int algoCent1State; + unsigned int algoCent1Cnt; + int algoCent1Enabled; + unsigned int CENT_EXEC_PHASE; + int algoAcq1State; + unsigned int algoAcq1Cnt; + int algoAcq1Enabled; + unsigned int ACQ_PH; + int algoCcState; + unsigned int algoCcCnt; + int algoCcEnabled; + unsigned int STCK_ORDER; + int algoTTC1State; + unsigned int algoTTC1Cnt; + int algoTTC1Enabled; + unsigned int TTC1_EXEC_PHASE; + int TTC1_EXEC_PER; + float TTC1_LL_FRT; + float TTC1_LL_AFT; + float TTC1_UL_FRT; + float TTC1_UL_AFT; + float ttc1AvTempAft; + float ttc1AvTempFrt; + int algoTTC2State; + unsigned int algoTTC2Cnt; + int algoTTC2Enabled; + int TTC2_EXEC_PER; + float TTC2_REF_TEMP; + float TTC2_OFFSETA; + float TTC2_OFFSETF; + float intTimeAft; + float onTimeAft; + float intTimeFront; + float onTimeFront; + float TTC2_PA; + float TTC2_DA; + float TTC2_IA; + float TTC2_PF; + float TTC2_DF; + float TTC2_IF; + int algoSaaEvalState; + unsigned int algoSaaEvalCnt; + int algoSaaEvalEnabled; + unsigned int SAA_EXEC_PHASE; + int SAA_EXEC_PER; + int isSaaActive; + unsigned int saaCounter; + unsigned int pInitSaaCounter; + int algoSdsEvalState; + unsigned int algoSdsEvalCnt; + int algoSdsEvalEnabled; + unsigned int SDS_EXEC_PHASE; + int SDS_EXEC_PER; + int isSdsActive; + int SDS_FORCED; + int SDS_INHIBITED; + int EARTH_OCCULT_ACTIVE; + unsigned int HEARTBEAT_D1; + unsigned int HEARTBEAT_D2; + int HbSem; + unsigned int starMap[276]; + unsigned int observationId; + int centValProcOutput; + float CENT_OFFSET_LIM; + float CENT_FROZEN_LIM; + int SEM_SERV1_1_FORWARD; + int SEM_SERV1_2_FORWARD; + int SEM_SERV1_7_FORWARD; + int SEM_SERV1_8_FORWARD; + int SEM_SERV3_1_FORWARD; + int SEM_SERV3_2_FORWARD; + unsigned int SEM_HK_TS_DEF_CRS; + unsigned int SEM_HK_TS_DEF_FINE; + unsigned int SEM_HK_TS_EXT_CRS; + unsigned int SEM_HK_TS_EXT_FINE; + int STAT_MODE; + unsigned int STAT_FLAGS; + int STAT_LAST_SPW_ERR; + unsigned int STAT_LAST_ERR_ID; + unsigned int STAT_LAST_ERR_FREQ; + unsigned int STAT_NUM_CMD_RECEIVED; + unsigned int STAT_NUM_CMD_EXECUTED; + unsigned int STAT_NUM_DATA_SENT; + unsigned int STAT_SCU_PROC_DUTY_CL; + unsigned int STAT_SCU_NUM_AHB_ERR; + unsigned int STAT_SCU_NUM_AHB_CERR; + unsigned int STAT_SCU_NUM_LUP_ERR; + float TEMP_SEM_SCU; + float TEMP_SEM_PCU; + float VOLT_SCU_P3_4; + float VOLT_SCU_P5; + float TEMP_FEE_CCD; + float TEMP_FEE_STRAP; + float TEMP_FEE_ADC; + float TEMP_FEE_BIAS; + float TEMP_FEE_DEB; + float VOLT_FEE_VOD; + float VOLT_FEE_VRD; + float VOLT_FEE_VOG; + float VOLT_FEE_VSS; + float VOLT_FEE_CCD; + float VOLT_FEE_CLK; + float VOLT_FEE_ANA_P5; + float VOLT_FEE_ANA_N5; + float VOLT_FEE_ANA_P3_3; + float CURR_FEE_CLK_BUF; + float VOLT_SCU_FPGA_P1_5; + float CURR_SCU_P3_4; + unsigned int STAT_NUM_SPW_ERR_CRE; + unsigned int STAT_NUM_SPW_ERR_ESC; + unsigned int STAT_NUM_SPW_ERR_DISC; + unsigned int STAT_NUM_SPW_ERR_PAR; + unsigned int STAT_NUM_SPW_ERR_WRSY; + unsigned int STAT_NUM_SPW_ERR_INVA; + unsigned int STAT_NUM_SPW_ERR_EOP; + unsigned int STAT_NUM_SPW_ERR_RXAH; + unsigned int STAT_NUM_SPW_ERR_TXAH; + unsigned int STAT_NUM_SPW_ERR_TXBL; + unsigned int STAT_NUM_SPW_ERR_TXLE; + unsigned int STAT_NUM_SP_ERR_RX; + unsigned int STAT_NUM_SP_ERR_TX; + unsigned int STAT_HEAT_PWM_FPA_CCD; + unsigned int STAT_HEAT_PWM_FEE_STR; + unsigned int STAT_HEAT_PWM_FEE_ANA; + unsigned int STAT_HEAT_PWM_SPARE; + unsigned int STAT_HEAT_PWM_FLAGS; + unsigned int STAT_OBTIME_SYNC_DELTA; + float TEMP_SEM_SCU_LW; + float TEMP_SEM_PCU_LW; + float VOLT_SCU_P3_4_LW; + float VOLT_SCU_P5_LW; + float TEMP_FEE_CCD_LW; + float TEMP_FEE_STRAP_LW; + float TEMP_FEE_ADC_LW; + float TEMP_FEE_BIAS_LW; + float TEMP_FEE_DEB_LW; + float VOLT_FEE_VOD_LW; + float VOLT_FEE_VRD_LW; + float VOLT_FEE_VOG_LW; + float VOLT_FEE_VSS_LW; + float VOLT_FEE_CCD_LW; + float VOLT_FEE_CLK_LW; + float VOLT_FEE_ANA_P5_LW; + float VOLT_FEE_ANA_N5_LW; + float VOLT_FEE_ANA_P3_3_LW; + float CURR_FEE_CLK_BUF_LW; + float VOLT_SCU_FPGA_P1_5_LW; + float CURR_SCU_P3_4_LW; + float TEMP_SEM_SCU_UW; + float TEMP_SEM_PCU_UW; + float VOLT_SCU_P3_4_UW; + float VOLT_SCU_P5_UW; + float TEMP_FEE_CCD_UW; + float TEMP_FEE_STRAP_UW; + float TEMP_FEE_ADC_UW; + float TEMP_FEE_BIAS_UW; + float TEMP_FEE_DEB_UW; + float VOLT_FEE_VOD_UW; + float VOLT_FEE_VRD_UW; + float VOLT_FEE_VOG_UW; + float VOLT_FEE_VSS_UW; + float VOLT_FEE_CCD_UW; + float VOLT_FEE_CLK_UW; + float VOLT_FEE_ANA_P5_UW; + float VOLT_FEE_ANA_N5_UW; + float VOLT_FEE_ANA_P3_3_UW; + float CURR_FEE_CLK_BUF_UW; + float VOLT_SCU_FPGA_P1_5_UW; + float CURR_SCU_P3_4_UW; + float TEMP_SEM_SCU_LA; + float TEMP_SEM_PCU_LA; + float VOLT_SCU_P3_4_LA; + float VOLT_SCU_P5_LA; + float TEMP_FEE_CCD_LA; + float TEMP_FEE_STRAP_LA; + float TEMP_FEE_ADC_LA; + float TEMP_FEE_BIAS_LA; + float TEMP_FEE_DEB_LA; + float VOLT_FEE_VOD_LA; + float VOLT_FEE_VRD_LA; + float VOLT_FEE_VOG_LA; + float VOLT_FEE_VSS_LA; + float VOLT_FEE_CCD_LA; + float VOLT_FEE_CLK_LA; + float VOLT_FEE_ANA_P5_LA; + float VOLT_FEE_ANA_N5_LA; + float VOLT_FEE_ANA_P3_3_LA; + float CURR_FEE_CLK_BUF_LA; + float VOLT_SCU_FPGA_P1_5_LA; + float CURR_SCU_P3_4_LA; + float TEMP_SEM_SCU_UA; + float TEMP_SEM_PCU_UA; + float VOLT_SCU_P3_4_UA; + float VOLT_SCU_P5_UA; + float TEMP_FEE_CCD_UA; + float TEMP_FEE_STRAP_UA; + float TEMP_FEE_ADC_UA; + float TEMP_FEE_BIAS_UA; + float TEMP_FEE_DEB_UA; + float VOLT_FEE_VOD_UA; + float VOLT_FEE_VRD_UA; + float VOLT_FEE_VOG_UA; + float VOLT_FEE_VSS_UA; + float VOLT_FEE_CCD_UA; + float VOLT_FEE_CLK_UA; + float VOLT_FEE_ANA_P5_UA; + float VOLT_FEE_ANA_N5_UA; + float VOLT_FEE_ANA_P3_3_UA; + float CURR_FEE_CLK_BUF_UA; + float VOLT_SCU_FPGA_P1_5_UA; + float CURR_SCU_P3_4_UA; + unsigned int semEvtCounter; + int SEM_SERV5_1_FORWARD; + int SEM_SERV5_2_FORWARD; + int SEM_SERV5_3_FORWARD; + int SEM_SERV5_4_FORWARD; + unsigned int pExpTime; + unsigned int pImageRep; + unsigned int pAcqNum; + int pDataOs; + int pCcdRdMode; + unsigned int pWinPosX; + unsigned int pWinPosY; + unsigned int pWinSizeX; + unsigned int pWinSizeY; + int pDtAcqSrc; + int pTempCtrlTarget; + float pVoltFeeVod; + float pVoltFeeVrd; + float pVoltFeeVss; + float pHeatTempFpaCCd; + float pHeatTempFeeStrap; + float pHeatTempFeeAnach; + float pHeatTempSpare; + int pStepEnDiagCcd; + int pStepEnDiagFee; + int pStepEnDiagTemp; + int pStepEnDiagAna; + int pStepEnDiagExpos; + int pStepDebDiagCcd; + int pStepDebDiagFee; + int pStepDebDiagTemp; + int pStepDebDiagAna; + int pStepDebDiagExpos; + int SEM_SERV220_6_FORWARD; + int SEM_SERV220_12_FORWARD; + int SEM_SERV222_6_FORWARD; + int saveImagesNode; + unsigned int saveImagesCnt; + int SaveImages_pSaveTarget; + unsigned int SaveImages_pFbfInit; + unsigned int SaveImages_pFbfEnd; + int acqFullDropNode; + unsigned int acqFullDropCnt; + unsigned int AcqFullDrop_pExpTime; + unsigned int AcqFullDrop_pImageRep; + unsigned int acqFullDropT1; + unsigned int acqFullDropT2; + int calFullSnapNode; + unsigned int calFullSnapCnt; + unsigned int CalFullSnap_pExpTime; + unsigned int CalFullSnap_pImageRep; + unsigned int CalFullSnap_pNmbImages; + int CalFullSnap_pCentSel; + unsigned int calFullSnapT1; + unsigned int calFullSnapT2; + int SciWinNode; + unsigned int SciWinCnt; + unsigned int SciWin_pNmbImages; + int SciWin_pCcdRdMode; + unsigned int SciWin_pExpTime; + unsigned int SciWin_pImageRep; + unsigned int SciWin_pWinPosX; + unsigned int SciWin_pWinPosY; + unsigned int SciWin_pWinSizeX; + unsigned int SciWin_pWinSizeY; + int SciWin_pCentSel; + unsigned int sciWinT1; + unsigned int sciWinT2; + int fbfLoadNode; + unsigned int fbfLoadCnt; + int fbfSaveNode; + unsigned int fbfSaveCnt; + unsigned int FbfLoad_pFbfId; + unsigned int FbfLoad_pFbfNBlocks; + unsigned int FbfLoad_pFbfRamAreaId; + unsigned int FbfLoad_pFbfRamAddr; + unsigned int FbfSave_pFbfId; + unsigned int FbfSave_pFbfNBlocks; + unsigned int FbfSave_pFbfRamAreaId; + unsigned int FbfSave_pFbfRamAddr; + unsigned int fbfLoadBlockCounter; + unsigned int fbfSaveBlockCounter; + int transFbfToGrndNode; + unsigned int transFbfToGrndCnt; + unsigned int TransFbfToGrnd_pNmbFbf; + unsigned int TransFbfToGrnd_pFbfInit; + unsigned int TransFbfToGrnd_pFbfSize; + int nomSciNode; + unsigned int nomSciCnt; + int NomSci_pAcqFlag; + int NomSci_pCal1Flag; + int NomSci_pSciFlag; + int NomSci_pCal2Flag; + unsigned int NomSci_pCibNFull; + unsigned int NomSci_pCibSizeFull; + unsigned int NomSci_pSibNFull; + unsigned int NomSci_pSibSizeFull; + unsigned int NomSci_pGibNFull; + unsigned int NomSci_pGibSizeFull; + unsigned int NomSci_pSibNWin; + unsigned int NomSci_pSibSizeWin; + unsigned int NomSci_pCibNWin; + unsigned int NomSci_pCibSizeWin; + unsigned int NomSci_pGibNWin; + unsigned int NomSci_pGibSizeWin; + unsigned int NomSci_pExpTimeAcq; + unsigned int NomSci_pImageRepAcq; + unsigned int NomSci_pExpTimeCal1; + unsigned int NomSci_pImageRepCal1; + unsigned int NomSci_pNmbImagesCal1; + int NomSci_pCentSelCal1; + unsigned int NomSci_pNmbImagesSci; + int NomSci_pCcdRdModeSci; + unsigned int NomSci_pExpTimeSci; + unsigned int NomSci_pImageRepSci; + unsigned int NomSci_pWinPosXSci; + unsigned int NomSci_pWinPosYSci; + unsigned int NomSci_pWinSizeXSci; + unsigned int NomSci_pWinSizeYSci; + int NomSci_pCentSelSci; + unsigned int NomSci_pExpTimeCal2; + unsigned int NomSci_pImageRepCal2; + unsigned int NomSci_pNmbImagesCal2; + int NomSci_pCentSelCal2; + int NomSci_pSaveTarget; + unsigned int NomSci_pFbfInit; + unsigned int NomSci_pFbfEnd; + unsigned int NomSci_pStckOrderCal1; + unsigned int NomSci_pStckOrderSci; + unsigned int NomSci_pStckOrderCal2; + int ConfigSdb_pSdbCmd; + unsigned int ConfigSdb_pCibNFull; + unsigned int ConfigSdb_pCibSizeFull; + unsigned int ConfigSdb_pSibNFull; + unsigned int ConfigSdb_pSibSizeFull; + unsigned int ConfigSdb_pGibNFull; + unsigned int ConfigSdb_pGibSizeFull; + unsigned int ConfigSdb_pSibNWin; + unsigned int ConfigSdb_pSibSizeWin; + unsigned int ConfigSdb_pCibNWin; + unsigned int ConfigSdb_pCibSizeWin; + unsigned int ConfigSdb_pGibNWin; + unsigned int ConfigSdb_pGibSizeWin; + float ADC_P3V3; + float ADC_P5V; + float ADC_P1V8; + float ADC_P2V5; + float ADC_N5V; + float ADC_PGND; + float ADC_TEMPOH1A; + float ADC_TEMP1; + float ADC_TEMPOH2A; + float ADC_TEMPOH1B; + float ADC_TEMPOH3A; + float ADC_TEMPOH2B; + float ADC_TEMPOH4A; + float ADC_TEMPOH3B; + float ADC_TEMPOH4B; + float SEM_P15V; + float SEM_P30V; + float SEM_P5V0; + float SEM_P7V0; + float SEM_N5V0; + int ADC_P3V3_RAW; + int ADC_P5V_RAW; + int ADC_P1V8_RAW; + int ADC_P2V5_RAW; + int ADC_N5V_RAW; + int ADC_PGND_RAW; + int ADC_TEMPOH1A_RAW; + int ADC_TEMP1_RAW; + int ADC_TEMPOH2A_RAW; + int ADC_TEMPOH1B_RAW; + int ADC_TEMPOH3A_RAW; + int ADC_TEMPOH2B_RAW; + int ADC_TEMPOH4A_RAW; + int ADC_TEMPOH3B_RAW; + int ADC_TEMPOH4B_RAW; + int SEM_P15V_RAW; + int SEM_P30V_RAW; + int SEM_P5V0_RAW; + int SEM_P7V0_RAW; + int SEM_N5V0_RAW; + float ADC_P3V3_U; + float ADC_P5V_U; + float ADC_P1V8_U; + float ADC_P2V5_U; + float ADC_N5V_L; + float ADC_PGND_U; + float ADC_PGND_L; + float ADC_TEMPOH1A_U; + float ADC_TEMP1_U; + float ADC_TEMPOH2A_U; + float ADC_TEMPOH1B_U; + float ADC_TEMPOH3A_U; + float ADC_TEMPOH2B_U; + float ADC_TEMPOH4A_U; + float ADC_TEMPOH3B_U; + float ADC_TEMPOH4B_U; + float SEM_P15V_U; + float SEM_P30V_U; + float SEM_P5V0_U; + float SEM_P7V0_U; + float SEM_N5V0_L; + unsigned int HbSemPassword; + unsigned int HbSemCounter; + unsigned int MAX_SEM_PCKT_CYC; + unsigned int SemPwrOnTimestamp; + unsigned int SemPwrOffTimestamp; + unsigned int IASW_EVT_CTR; + unsigned int Sram1ScrCurrAddr; + unsigned int Sram2ScrCurrAddr; + unsigned int Sram1ScrLength; + unsigned int Sram2ScrLength; + unsigned int EdacSingleRepaired; + unsigned int EdacSingleFaults; + unsigned int EdacLastSingleFail; + int Cpu2ProcStatus; + int TaAlgoId; + unsigned int TAACQALGOID; + unsigned int TASPARE32; + unsigned int TaTimingPar1; + unsigned int TaTimingPar2; + unsigned int TaDistanceThrd; + unsigned int TaIterations; + unsigned int TaRebinningFact; + unsigned int TaDetectionThrd; + unsigned int TaSeReducedExtr; + unsigned int TaSeReducedRadius; + unsigned int TaSeTolerance; + unsigned int TaMvaTolerance; + unsigned int TaAmaTolerance; + unsigned int TAPOINTUNCERT; + unsigned int TATARGETSIG; + unsigned int TANROFSTARS; + float TaMaxSigFract; + float TaBias; + float TaDark; + float TaSkyBg; + unsigned int COGBITS; + float CENT_MULT_X; + float CENT_MULT_Y; + float CENT_OFFSET_X; + float CENT_OFFSET_Y; + unsigned int CENT_MEDIANFILTER; + unsigned int CENT_DIM_X; + unsigned int CENT_DIM_Y; + int CENT_CHECKS; + unsigned int CEN_SIGMALIMIT; + unsigned int CEN_SIGNALLIMIT; + unsigned int CEN_MEDIAN_THRD; + float OPT_AXIS_X; + float OPT_AXIS_Y; + int DIST_CORR; + unsigned int pStckOrderSci; + unsigned int pWinSizeXSci; + unsigned int pWinSizeYSci; + int SdpImageAptShape; + unsigned int SdpImageAptX; + unsigned int SdpImageAptY; + int SdpImgttAptShape; + unsigned int SdpImgttAptX; + unsigned int SdpImgttAptY; + unsigned int SdpImgttStckOrder; + unsigned int SdpLosStckOrder; + unsigned int SdpLblkStckOrder; + unsigned int SdpLdkStckOrder; + unsigned int SdpRdkStckOrder; + unsigned int SdpRblkStckOrder; + unsigned int SdpTosStckOrder; + unsigned int SdpTdkStckOrder; + int SdpImgttStrat; + float Sdp3StatAmpl; + int SdpPhotStrat; + unsigned int SdpPhotRcent; + unsigned int SdpPhotRann1; + unsigned int SdpPhotRann2; + unsigned int SdpCrc; + unsigned int CCPRODUCT; + unsigned int CCSTEP; + unsigned int XIB_FAILURES; + unsigned int FEE_SIDE_A[FEE_SCRIPTS]; + unsigned int FEE_SIDE_B[FEE_SCRIPTS]; + unsigned int NLCBORDERS[28]; + float NLCCOEFF_A[28]; + float NLCCOEFF_B[28]; + float NLCCOEFF_C[28]; + float NLCCOEFF_D[28]; + unsigned int SdpGlobalBias; + int BiasOrigin; + float SdpGlobalGain; + unsigned int SdpWinImageCeKey; + unsigned int SdpWinImgttCeKey; + unsigned int SdpWinHdrCeKey; + unsigned int SdpWinMLOSCeKey; + unsigned int SdpWinMLBLKCeKey; + unsigned int SdpWinMLDKCeKey; + unsigned int SdpWinMRDKCeKey; + unsigned int SdpWinMRBLKCeKey; + unsigned int SdpWinMTOSCeKey; + unsigned int SdpWinMTDKCeKey; + unsigned int SdpFullImgCeKey; + unsigned int SdpFullHdrCeKey; + unsigned int CE_Timetag_crs; + unsigned int CE_Timetag_fine; + unsigned int CE_Counter; + unsigned int CE_Version; + unsigned int CE_Integrity; + unsigned int CE_SemWindowPosX; + unsigned int CE_SemWindowPosY; + unsigned int CE_SemWindowSizeX; + unsigned int CE_SemWindowSizeY; + unsigned int SPILL_CTR; + unsigned int RZIP_ITER1; + unsigned int RZIP_ITER2; + unsigned int RZIP_ITER3; + unsigned int RZIP_ITER4; + unsigned int SdpLdkColMask; + unsigned int SdpRdkColMask; + unsigned int GIBTOTRANSFER; + unsigned int TRANSFERMODE; + unsigned int S2TOTRANSFERSIZE; + unsigned int S4TOTRANSFERSIZE; + unsigned int TransferComplete; + unsigned int NLCBORDERS_2[28]; + float NLCCOEFF_A_2[28]; + float NLCCOEFF_B_2[28]; + float NLCCOEFF_C_2[28]; + unsigned int RF100[12]; + unsigned int RF230[12]; + float distc1; + float distc2; + float distc3; + unsigned int SPARE_UI_0; + unsigned int SPARE_UI_1; + unsigned int SPARE_UI_2; + unsigned int SPARE_UI_3; + unsigned int SPARE_UI_4; + unsigned int SPARE_UI_5; + unsigned int SPARE_UI_6; + unsigned int SPARE_UI_7; + unsigned int SPARE_UI_8; + unsigned int SPARE_UI_9; + unsigned int SPARE_UI_10; + unsigned int SPARE_UI_11; + unsigned int SPARE_UI_12; + unsigned int SPARE_UI_13; + unsigned int SPARE_UI_14; + unsigned int SPARE_UI_15; + float SPARE_F_0; + float SPARE_F_1; + float SPARE_F_2; + float SPARE_F_3; + float SPARE_F_4; + float SPARE_F_5; + float SPARE_F_6; + float SPARE_F_7; + float SPARE_F_8; + float SPARE_F_9; + float SPARE_F_10; + float SPARE_F_11; + float SPARE_F_12; + float SPARE_F_13; + float SPARE_F_14; + float SPARE_F_15; +} ; + +/** The structure holding data pool variables and parameter items for IBSW. */ +struct DataPoolIbsw { + int isWatchdogEnabled; + int isSynchronized; + int missedMsgCnt; + int missedPulseCnt; + unsigned int milFrameDelay; + int EL1_CHIP; + int EL2_CHIP; + unsigned int EL1_ADDR; + unsigned int EL2_ADDR; + int ERR_LOG_ENB; + int isErrLogValid; + unsigned int nOfErrLogEntries; + unsigned int FBF_BLCK_WR_DUR; + unsigned int FBF_BLCK_RD_DUR; + int isFbfOpen[250]; + int isFbfValid[250]; + int FBF_ENB[250]; + int FBF_CHIP[250]; + unsigned int FBF_ADDR[250]; + unsigned int fbfNBlocks[250]; + float THR_MA_A_1; + float THR_MA_A_2; + float THR_MA_A_3; + float THR_MA_A_4; + float THR_MA_A_5; + float wcet_1; + float wcet_2; + float wcet_3; + float wcet_4; + float wcet_5; + float wcetAver_1; + float wcetAver_2; + float wcetAver_3; + float wcetAver_4; + float wcetAver_5; + float wcetMax_1; + float wcetMax_2; + float wcetMax_3; + float wcetMax_4; + float wcetMax_5; + unsigned int nOfNotif_1; + unsigned int nOfNotif_2; + unsigned int nOfNotif_3; + unsigned int nOfNotif_4; + unsigned int nOfNotif_5; + unsigned int nofFuncExec_1; + unsigned int nofFuncExec_2; + unsigned int nofFuncExec_3; + unsigned int nofFuncExec_4; + unsigned int nofFuncExec_5; + unsigned int wcetTimeStampFine_1; + unsigned int wcetTimeStampFine_2; + unsigned int wcetTimeStampFine_3; + unsigned int wcetTimeStampFine_4; + unsigned int wcetTimeStampFine_5; + unsigned int wcetTimeStampCoarse_1; + unsigned int wcetTimeStampCoarse_2; + unsigned int wcetTimeStampCoarse_3; + unsigned int wcetTimeStampCoarse_4; + unsigned int wcetTimeStampCoarse_5; + unsigned int flashContStepCnt; + float OTA_TM1A_NOM; + float OTA_TM1A_RED; + float OTA_TM1B_NOM; + float OTA_TM1B_RED; + float OTA_TM2A_NOM; + float OTA_TM2A_RED; + float OTA_TM2B_NOM; + float OTA_TM2B_RED; + float OTA_TM3A_NOM; + float OTA_TM3A_RED; + float OTA_TM3B_NOM; + float OTA_TM3B_RED; + float OTA_TM4A_NOM; + float OTA_TM4A_RED; + float OTA_TM4B_NOM; + float OTA_TM4B_RED; + unsigned int Core0Load; + unsigned int Core1Load; + unsigned int InterruptRate; + unsigned int CyclicalActivitiesCtr; + unsigned int Uptime; + unsigned int SemTick; + unsigned int BAD_COPY_ID; + unsigned int BAD_PASTE_ID; + unsigned int ObcInputBufferPackets; + unsigned int GrndInputBufferPackets; + unsigned int MilBusBytesIn; + unsigned int MilBusBytesOut; + unsigned int MilBusDroppedBytes; + unsigned int IRL1; + unsigned int IRL1_AHBSTAT; + unsigned int IRL1_GRGPIO_6; + unsigned int IRL1_GRTIMER; + unsigned int IRL1_GPTIMER_0; + unsigned int IRL1_GPTIMER_1; + unsigned int IRL1_GPTIMER_2; + unsigned int IRL1_GPTIMER_3; + unsigned int IRL1_IRQMP; + unsigned int IRL1_B1553BRM; + unsigned int IRL2; + unsigned int IRL2_GRSPW2_0; + unsigned int IRL2_GRSPW2_1; + int SemRoute; + unsigned int SpW0BytesIn; + unsigned int SpW0BytesOut; + unsigned int SpW1BytesIn; + unsigned int SpW1BytesOut; + unsigned int Spw0TxDescAvail; + unsigned int Spw0RxPcktAvail; + unsigned int Spw1TxDescAvail; + unsigned int Spw1RxPcktAvail; + unsigned int MilCucCoarseTime; + unsigned int MilCucFineTime; + unsigned int CucCoarseTime; + unsigned int CucFineTime; + unsigned int EdacDoubleFaults; + unsigned int EdacDoubleFAddr; + unsigned int HEARTBEAT_ENABLED; + unsigned int S1AllocDbs; + unsigned int S1AllocSw; + unsigned int S1AllocHeap; + unsigned int S1AllocFlash; + unsigned int S1AllocAux; + unsigned int S1AllocRes; + unsigned int S1AllocSwap; + unsigned int S2AllocSciHeap; + unsigned int FPGA_Version; + unsigned int FPGA_DPU_Status; + unsigned int FPGA_DPU_Address; + unsigned int FPGA_RESET_Status; + unsigned int FPGA_SEM_Status; + unsigned int FPGA_Oper_Heater_Status; +} ; + + +#define CC_PROLOGUE 0x0000 +#define CC_HEADERS 0x1000 +#define CC_STACKED 0x2000 +#define CC_IMAGETTES 0x3000 +#define CC_MRGLOS 0x4000 +#define CC_MRGLDK 0x5000 +#define CC_MRGLBLK 0x6000 +#define CC_MRGRDK 0x7000 +#define CC_MRGRBLK 0x8000 +#define CC_MRGTDK 0x9000 +#define CC_MRGTOS 0xA000 +#define CC_MIDPART 0xB000 +#define CC_COLLECT 0xC000 +#define CC_FINISHED 0xF000 + +#define CC_COMPR_STARTED 0x0C00 +#define CC_PRODUCT_DISABLE 0x0C10 +#define CC_PRODUCT_HEADERS 0x0C11 +#define CC_PRODUCT_STACKED 0x0C12 +#define CC_PRODUCT_IMAGETTES 0x0C13 +#define CC_PRODUCT_MRGLOS 0x0C14 +#define CC_PRODUCT_MRGLDK 0x0C15 +#define CC_PRODUCT_MRGLBLK 0x0C16 +#define CC_PRODUCT_MRGRDK 0x0C17 +#define CC_PRODUCT_MRGRBLK 0x0C18 +#define CC_PRODUCT_MRGTDK 0x0C19 +#define CC_PRODUCT_MRGTOS 0x0C1A +#define CC_PREPROC_NONE 0x0C20 +#define CC_PREPROC_NLC 0x0C21 +#define CC_PREPROC_NLCPHOT 0x0C22 +#define CC_PREPROC_PHOT 0x0C23 +#define CC_PREPROC_NLC2 0x0C24 +#define CC_LOSSY1_NONE 0x0C30 +#define CC_LOSSY1_COADD 0x0C31 +#define CC_LOSSY1_MEAN 0x0C32 +#define CC_LOSSY1_GMEAN 0x0C33 +#define CC_LOSSY1_GCOADD 0x0C34 +#define CC_LOSSY2_NONE 0x0C40 +#define CC_LOSSY2_3STAT 0x0C41 +#define CC_LOSSY2_3STATUI_ROW 0x0C42 +#define CC_LOSSY2_3STATUI_COL 0x0C43 +#define CC_LOSSY2_3STATUI 0x0C44 +#define CC_LOSSY2_4STAT 0x0C45 +#define CC_LOSSY2_CIRCMASK 0x0C46 +#define CC_LOSSY2_CIRCEXTRACT 0x0C47 +#define CC_DECORR_NONE 0x0C50 +#define CC_DECORR_DIFF 0x0C51 +#define CC_DECORR_KEYFR 0x0C52 +#define CC_DECORR_IWT1 0x0C53 +#define CC_DECORR_IWT2 0x0C54 +#define CC_LLC_NONE 0x0C60 +#define CC_LLC_RZIP 0x0C61 +#define CC_LLC_ARI1 0x0C62 +#define CC_LLC_PACK16 0x0C63 +#define CC_LOSSY3_NONE 0x0C70 +#define CC_LOSSY3_ROUND1 0x0C71 +#define CC_LOSSY3_ROUND2 0x0C72 +#define CC_LOSSY3_ROUND3 0x0C73 +#define CC_LOSSY3_ROUND4 0x0C74 +#define CC_LOSSY3_ROUND5 0x0C75 +#define CC_LOSSY3_ROUND6 0x0C76 + +#define DTSIZE_FROM_HEADER 0xffffffff + +#define FPM_SIDE_A 0 /* nominal */ +#define FPM_SIDE_B 1 /* redundant */ + +unsigned char GetFpmSide (unsigned char id); + +unsigned char GetRf (unsigned char id); + +/* access needed e.g. in IfswUtilities */ +unsigned int GetDataPoolMult (unsigned int id); + +unsigned int GetDataPoolSize (unsigned int id); + +#ifdef PC_TARGET +extern struct DataPoolCordet dpCordetInit; +extern struct DataPoolIasw dpIaswInit; +extern struct DataPoolIbsw dpIbswInit; + +void InitDataPool(); + +void initDpAddresses(struct DataPoolCordet *pdpCordet, struct DataPoolIasw *pdpIasw, struct DataPoolIbsw *pdpIbsw); +#endif /* PC_TARGET */ + +#if (__sparc__) + +#define CrIaCopy(id, addr_ptr) CrIa_Copy(id, addr_ptr, sizeof(*addr_ptr)) +#define CrIaPaste(id, addr_ptr) CrIa_Paste(id, addr_ptr, sizeof(*addr_ptr)) + +/** + * Copy a value of the data pool item addressed by the identifier to a target variable. + * The copy interface is only intended for use by "Housekeeping Data Reporting Service". + * It is responsibility of a caller to ensure that: + * - identifier of the data pool item exists + * - target variable has a type corresponding to the telemetry type of the data item being copied. + * @param id the data pool item identifier + * @param targetAddr the address of the target variable + */ + +void CrIa_Copy(unsigned int id, void * targetAddr, int tgtsize); + +/** + * Paste a source variable value to the data pool item addressed by the identifier. + * The paste interface is only intended for use by "Housekeeping Data Reporting Service". + * It is responsibility of a caller to ensure that: + * - identifier of the data pool item exists + * - source variable has a type corresponding to the telemetry type of the data item being paste. + * @param id the data pool item identifier + * @param sourceAddr the address of the source variable + */ + +void CrIa_Paste(unsigned int id, void * targetAddr, int tgtsize); + +#else + +#define CrIaCopy(id, addr_ptr) CrIa_Copy_PC(id, addr_ptr, sizeof(*addr_ptr)) +#define CrIaPaste(id, addr_ptr) CrIa_Paste_PC(id, addr_ptr, sizeof(*addr_ptr)) + +void CrIa_Copy_PC(unsigned int id, void * targetAddr, int tgtsize); + +void CrIa_Paste_PC(unsigned int id, void * targetAddr, int tgtsize); + +#endif + + +void CrIaCopyPcPckt(unsigned int id, void * targetAddr); + +void CrIaCopyArrayItem(unsigned int id, void * targetAddr, unsigned int arrayElement); +void CrIaCopyArrayItemPcPckt(unsigned int id, void * targetAddr, unsigned int arrayElement); + +/** + * Paste an array item value to the data pool item addressed by the identifier. + * The paste interface is only intended for use by "Housekeeping Data Reporting Service". + * It is responsibility of a caller to ensure that: + * - identifier of the data pool item exists + * - source variable has a type corresponding to the telemetry type of the data item being paste. + * - the number of array elements is not exceeded + * @param id the data pool item identifier + * @param sourceAddr the address of the source array + * @param arrayElement the array element index, the first has value 0 + */ +void CrIaPasteArrayItem(unsigned int id, const void * sourceAddr, unsigned int arrayElement); + + +#ifndef ISOLATED +/** + * Update values in the data pool. This function is called at the beginning of every cycle, + * so that the data pool elements are the current ones. + * - all items from the DataPoolCordet are updated + * - there are items which cannot be updated this way, because they are asynchronous (e.g. CPU load) + * - items from other sections are TBC + */ +void CrFwUpdateDataPool(FwSmDesc_t inManagerSem, + FwSmDesc_t inManagerGrdObc, + FwSmDesc_t outManager1, + FwSmDesc_t outManager2, + FwSmDesc_t outManager3, + FwSmDesc_t inStreamSem, + FwSmDesc_t inStreamObc, + FwSmDesc_t inStreamGrd, + FwSmDesc_t outStreamSem, + FwSmDesc_t outStreamObc, + FwSmDesc_t outStreamGrd); +#endif + +#endif /* CRIADATAPOOL_H_ */ diff --git a/CrIa/src/CrIaDataPoolId.h b/CrIa/src/CrIaDataPoolId.h new file mode 100644 index 0000000000000000000000000000000000000000..401f733953478eb616bcea2d7a58315ead445b2a --- /dev/null +++ b/CrIa/src/CrIaDataPoolId.h @@ -0,0 +1,1019 @@ +/** +* @file +* Identifiers of data pool items. +* +* @note This code was generated. +* @authors V. Cechticky and A. Pasetti +* @copyright P&P Software GmbH, 2015, All Rights Reserved +*/ + +#ifndef CRIADATAPOOLID_H_ +#define CRIADATAPOOLID_H_ + +#define BUILDNUMBER_ID 1 +#define APPERRCODE_ID 2 +#define NOFALLOCATEDINREP_ID 3 +#define MAXNOFINREP_ID 4 +#define NOFALLOCATEDINCMD_ID 5 +#define MAXNOFINCMD_ID 6 +#define SEM_NOFPENDINGINCMP_ID 7 +#define SEM_PCRLSIZE_ID 8 +#define SEM_NOFLOADEDINCMP_ID 9 +#define GRDOBC_NOFPENDINGINCMP_ID 10 +#define GRDOBC_PCRLSIZE_ID 11 +#define NOFALLOCATEDOUTCMP_ID 12 +#define MAXNOFOUTCMP_ID 13 +#define NOFINSTANCEID_ID 14 +#define OUTMG1_NOFPENDINGOUTCMP_ID 15 +#define OUTMG1_POCLSIZE_ID 16 +#define OUTMG1_NOFLOADEDOUTCMP_ID 17 +#define OUTMG2_NOFPENDINGOUTCMP_ID 18 +#define OUTMG2_POCLSIZE_ID 19 +#define OUTMG2_NOFLOADEDOUTCMP_ID 20 +#define OUTMG3_NOFPENDINGOUTCMP_ID 21 +#define OUTMG3_POCLSIZE_ID 22 +#define OUTMG3_NOFLOADEDOUTCMP_ID 23 +#define INSEM_SEQCNT_ID 24 +#define INSEM_NOFPENDINGPCKTS_ID 25 +#define INSEM_NOFGROUPS_ID 26 +#define INSEM_PCKTQUEUESIZE_ID 27 +#define INSEM_SRC_ID 28 +#define INOBC_NOFPENDINGPCKTS_ID 29 +#define INOBC_NOFGROUPS_ID 30 +#define INOBC_PCKTQUEUESIZE_ID 31 +#define INOBC_SRC_ID 32 +#define INGRD_NOFPENDINGPCKTS_ID 33 +#define INGRD_NOFGROUPS_ID 34 +#define INGRD_PCKTQUEUESIZE_ID 35 +#define INGRD_SRC_ID 36 +#define OUTSEM_DEST_ID 37 +#define OUTSEM_SEQCNT_ID 38 +#define OUTSEM_NOFPENDINGPCKTS_ID 39 +#define OUTSEM_NOFGROUPS_ID 40 +#define OUTSEM_PCKTQUEUESIZE_ID 41 +#define OUTOBC_DEST_ID 42 +#define OUTOBC_SEQCNT_GROUP0_ID 43 +#define OUTOBC_SEQCNT_GROUP1_ID 44 +#define OUTOBC_NOFPENDINGPCKTS_ID 45 +#define OUTOBC_NOFGROUPS_ID 46 +#define OUTOBC_PCKTQUEUESIZE_ID 47 +#define OUTGRD_DEST_ID 48 +#define OUTGRD_SEQCNT_GROUP0_ID 49 +#define OUTGRD_SEQCNT_GROUP1_ID 50 +#define OUTGRD_SEQCNT_GROUP2_ID 51 +#define OUTGRD_NOFPENDINGPCKTS_ID 52 +#define OUTGRD_NOFGROUPS_ID 53 +#define OUTGRD_PCKTQUEUESIZE_ID 54 +#define SIBNFULL_ID 55 +#define CIBNFULL_ID 56 +#define GIBNFULL_ID 57 +#define SIBNWIN_ID 58 +#define CIBNWIN_ID 59 +#define GIBNWIN_ID 60 +#define SIBSIZEFULL_ID 61 +#define CIBSIZEFULL_ID 62 +#define GIBSIZEFULL_ID 63 +#define SIBSIZEWIN_ID 64 +#define CIBSIZEWIN_ID 65 +#define GIBSIZEWIN_ID 66 +#define SIBIN_ID 67 +#define SIBOUT_ID 68 +#define CIBIN_ID 69 +#define GIBIN_ID 70 +#define GIBOUT_ID 71 +#define SDBSTATE_ID 72 +#define SDBSTATECNT_ID 73 +#define OFFSETX_ID 74 +#define OFFSETY_ID 75 +#define TARGETLOCATIONX_ID 76 +#define TARGETLOCATIONY_ID 77 +#define INTEGSTARTTIMECRS_ID 78 +#define INTEGSTARTTIMEFINE_ID 79 +#define INTEGENDTIMECRS_ID 80 +#define INTEGENDTIMEFINE_ID 81 +#define DATACADENCE_ID 82 +#define VALIDITYSTATUS_ID 83 +#define NOFTCACC_ID 84 +#define NOFACCFAILEDTC_ID 85 +#define SEQCNTLASTACCTCFROMOBC_ID 86 +#define SEQCNTLASTACCTCFROMGRD_ID 87 +#define SEQCNTLASTACCFAILTC_ID 88 +#define NOFSTARTFAILEDTC_ID 89 +#define SEQCNTLASTSTARTFAILTC_ID 90 +#define NOFTCTERM_ID 91 +#define NOFTERMFAILEDTC_ID 92 +#define SEQCNTLASTTERMFAILTC_ID 93 +#define RDLSIDLIST_ID 94 +#define ISRDLFREE_ID 95 +#define RDLCYCCNTLIST_ID 96 +#define RDLPERIODLIST_ID 97 +#define RDLENABLEDLIST_ID 98 +#define RDLDESTLIST_ID 99 +#define RDLDATAITEMLIST_0_ID 100 +#define RDLDATAITEMLIST_1_ID 101 +#define RDLDATAITEMLIST_2_ID 102 +#define RDLDATAITEMLIST_3_ID 103 +#define RDLDATAITEMLIST_4_ID 104 +#define RDLDATAITEMLIST_5_ID 105 +#define RDLDATAITEMLIST_6_ID 106 +#define RDLDATAITEMLIST_7_ID 107 +#define RDLDATAITEMLIST_8_ID 108 +#define RDLDATAITEMLIST_9_ID 109 +#define DEBUG_VAR_ID 110 +#define DEBUG_VAR_ADDR_ID 111 +#define EVTFILTERDEF_ID 112 +#define EVTENABLEDLIST_ID 113 +#define LASTPATCHEDADDR_ID 114 +#define LASTDUMPADDR_ID 115 +#define SDU2STATE_ID 116 +#define SDU4STATE_ID 117 +#define SDU2STATECNT_ID 118 +#define SDU4STATECNT_ID 119 +#define SDU2BLOCKCNT_ID 120 +#define SDU4BLOCKCNT_ID 121 +#define SDU2REMSIZE_ID 122 +#define SDU4REMSIZE_ID 123 +#define SDU2DOWNTRANSFERSIZE_ID 124 +#define SDU4DOWNTRANSFERSIZE_ID 125 +#define SDSCOUNTER_ID 126 +#define FDGLBENABLE_ID 127 +#define RPGLBENABLE_ID 128 +#define FDCHECKTTMSTATE_ID 129 +#define FDCHECKTTMINTEN_ID 130 +#define FDCHECKTTMEXTEN_ID 131 +#define RPTTMINTEN_ID 132 +#define RPTTMEXTEN_ID 133 +#define FDCHECKTTMCNT_ID 134 +#define FDCHECKTTMSPCNT_ID 135 +#define FDCHECKTTMCNTTHR_ID 136 +#define TTC_LL_ID 137 +#define TTC_UL_ID 138 +#define TTM_LIM_ID 139 +#define FDCHECKSDSCSTATE_ID 140 +#define FDCHECKSDSCINTEN_ID 141 +#define FDCHECKSDSCEXTEN_ID 142 +#define RPSDSCINTEN_ID 143 +#define RPSDSCEXTEN_ID 144 +#define FDCHECKSDSCCNT_ID 145 +#define FDCHECKSDSCSPCNT_ID 146 +#define FDCHECKSDSCCNTTHR_ID 147 +#define FDCHECKCOMERRSTATE_ID 148 +#define FDCHECKCOMERRINTEN_ID 149 +#define FDCHECKCOMERREXTEN_ID 150 +#define RPCOMERRINTEN_ID 151 +#define RPCOMERREXTEN_ID 152 +#define FDCHECKCOMERRCNT_ID 153 +#define FDCHECKCOMERRSPCNT_ID 154 +#define FDCHECKCOMERRCNTTHR_ID 155 +#define FDCHECKTIMEOUTSTATE_ID 156 +#define FDCHECKTIMEOUTINTEN_ID 157 +#define FDCHECKTIMEOUTEXTEN_ID 158 +#define RPTIMEOUTINTEN_ID 159 +#define RPTIMEOUTEXTEN_ID 160 +#define FDCHECKTIMEOUTCNT_ID 161 +#define FDCHECKTIMEOUTSPCNT_ID 162 +#define FDCHECKTIMEOUTCNTTHR_ID 163 +#define SEM_TO_POWERON_ID 164 +#define SEM_TO_SAFE_ID 165 +#define SEM_TO_STAB_ID 166 +#define SEM_TO_TEMP_ID 167 +#define SEM_TO_CCD_ID 168 +#define SEM_TO_DIAG_ID 169 +#define SEM_TO_STANDBY_ID 170 +#define FDCHECKSAFEMODESTATE_ID 171 +#define FDCHECKSAFEMODEINTEN_ID 172 +#define FDCHECKSAFEMODEEXTEN_ID 173 +#define RPSAFEMODEINTEN_ID 174 +#define RPSAFEMODEEXTEN_ID 175 +#define FDCHECKSAFEMODECNT_ID 176 +#define FDCHECKSAFEMODESPCNT_ID 177 +#define FDCHECKSAFEMODECNTTHR_ID 178 +#define FDCHECKALIVESTATE_ID 179 +#define FDCHECKALIVEINTEN_ID 180 +#define FDCHECKALIVEEXTEN_ID 181 +#define RPALIVEINTEN_ID 182 +#define RPALIVEEXTEN_ID 183 +#define FDCHECKALIVECNT_ID 184 +#define FDCHECKALIVESPCNT_ID 185 +#define FDCHECKALIVECNTTHR_ID 186 +#define SEM_HK_DEF_PER_ID 187 +#define SEMALIVE_DELAYEDSEMHK_ID 188 +#define FDCHECKSEMANOEVTSTATE_ID 189 +#define FDCHECKSEMANOEVTINTEN_ID 190 +#define FDCHECKSEMANOEVTEXTEN_ID 191 +#define RPSEMANOEVTINTEN_ID 192 +#define RPSEMANOEVTEXTEN_ID 193 +#define FDCHECKSEMANOEVTCNT_ID 194 +#define FDCHECKSEMANOEVTSPCNT_ID 195 +#define FDCHECKSEMANOEVTCNTTHR_ID 196 +#define SEMANOEVTRESP_1_ID 197 +#define SEMANOEVTRESP_2_ID 198 +#define SEMANOEVTRESP_3_ID 199 +#define SEMANOEVTRESP_4_ID 200 +#define SEMANOEVTRESP_5_ID 201 +#define SEMANOEVTRESP_6_ID 202 +#define SEMANOEVTRESP_7_ID 203 +#define SEMANOEVTRESP_8_ID 204 +#define SEMANOEVTRESP_9_ID 205 +#define SEMANOEVTRESP_10_ID 206 +#define SEMANOEVTRESP_11_ID 207 +#define SEMANOEVTRESP_12_ID 208 +#define SEMANOEVTRESP_13_ID 209 +#define SEMANOEVTRESP_14_ID 210 +#define SEMANOEVTRESP_15_ID 211 +#define SEMANOEVTRESP_16_ID 212 +#define SEMANOEVTRESP_17_ID 213 +#define SEMANOEVTRESP_18_ID 214 +#define SEMANOEVTRESP_19_ID 215 +#define SEMANOEVTRESP_20_ID 216 +#define SEMANOEVTRESP_21_ID 217 +#define SEMANOEVTRESP_22_ID 218 +#define SEMANOEVTRESP_23_ID 219 +#define SEMANOEVTRESP_24_ID 220 +#define SEMANOEVTRESP_25_ID 221 +#define SEMANOEVTRESP_26_ID 222 +#define SEMANOEVTRESP_27_ID 223 +#define SEMANOEVTRESP_28_ID 224 +#define SEMANOEVTRESP_29_ID 225 +#define FDCHECKSEMLIMITSTATE_ID 226 +#define FDCHECKSEMLIMITINTEN_ID 227 +#define FDCHECKSEMLIMITEXTEN_ID 228 +#define RPSEMLIMITINTEN_ID 229 +#define RPSEMLIMITEXTEN_ID 230 +#define FDCHECKSEMLIMITCNT_ID 231 +#define FDCHECKSEMLIMITSPCNT_ID 232 +#define FDCHECKSEMLIMITCNTTHR_ID 233 +#define SEM_LIM_DEL_T_ID 234 +#define FDCHECKDPUHKSTATE_ID 235 +#define FDCHECKDPUHKINTEN_ID 236 +#define FDCHECKDPUHKEXTEN_ID 237 +#define RPDPUHKINTEN_ID 238 +#define RPDPUHKEXTEN_ID 239 +#define FDCHECKDPUHKCNT_ID 240 +#define FDCHECKDPUHKSPCNT_ID 241 +#define FDCHECKDPUHKCNTTHR_ID 242 +#define FDCHECKCENTCONSSTATE_ID 243 +#define FDCHECKCENTCONSINTEN_ID 244 +#define FDCHECKCENTCONSEXTEN_ID 245 +#define RPCENTCONSINTEN_ID 246 +#define RPCENTCONSEXTEN_ID 247 +#define FDCHECKCENTCONSCNT_ID 248 +#define FDCHECKCENTCONSSPCNT_ID 249 +#define FDCHECKCENTCONSCNTTHR_ID 250 +#define FDCHECKRESSTATE_ID 251 +#define FDCHECKRESINTEN_ID 252 +#define FDCHECKRESEXTEN_ID 253 +#define RPRESINTEN_ID 254 +#define RPRESEXTEN_ID 255 +#define FDCHECKRESCNT_ID 256 +#define FDCHECKRESSPCNT_ID 257 +#define FDCHECKRESCNTTHR_ID 258 +#define CPU1_USAGE_MAX_ID 259 +#define MEM_USAGE_MAX_ID 260 +#define FDCHECKSEMCONS_ID 261 +#define FDCHECKSEMCONSINTEN_ID 262 +#define FDCHECKSEMCONSEXTEN_ID 263 +#define RPSEMCONSINTEN_ID 264 +#define RPSEMCONSEXTEN_ID 265 +#define FDCHECKSEMCONSCNT_ID 266 +#define FDCHECKSEMCONSSPCNT_ID 267 +#define FDCHECKSEMCONSCNTTHR_ID 268 +#define SEMSTATE_ID 269 +#define SEMOPERSTATE_ID 270 +#define SEMSTATECNT_ID 271 +#define SEMOPERSTATECNT_ID 272 +#define IMAGECYCLECNT_ID 273 +#define ACQIMAGECNT_ID 274 +#define SCISUBMODE_ID 275 +#define LASTSEMPCKT_ID 276 +#define SEM_ON_CODE_ID 277 +#define SEM_OFF_CODE_ID 278 +#define SEM_INIT_T1_ID 279 +#define SEM_INIT_T2_ID 280 +#define SEM_OPER_T1_ID 281 +#define SEM_SHUTDOWN_T1_ID 282 +#define SEM_SHUTDOWN_T11_ID 283 +#define SEM_SHUTDOWN_T12_ID 284 +#define SEM_SHUTDOWN_T2_ID 285 +#define IASWSTATE_ID 286 +#define IASWSTATECNT_ID 287 +#define IASWCYCLECNT_ID 288 +#define PREPSCIENCENODE_ID 289 +#define PREPSCIENCECNT_ID 290 +#define CONTROLLEDSWITCHOFFNODE_ID 291 +#define CONTROLLEDSWITCHOFFCNT_ID 292 +#define CTRLD_SWITCH_OFF_T1_ID 293 +#define ALGOCENT0STATE_ID 294 +#define ALGOCENT0CNT_ID 295 +#define ALGOCENT0ENABLED_ID 296 +#define ALGOCENT1STATE_ID 297 +#define ALGOCENT1CNT_ID 298 +#define ALGOCENT1ENABLED_ID 299 +#define CENT_EXEC_PHASE_ID 300 +#define ALGOACQ1STATE_ID 301 +#define ALGOACQ1CNT_ID 302 +#define ALGOACQ1ENABLED_ID 303 +#define ACQ_PH_ID 304 +#define ALGOCCSTATE_ID 305 +#define ALGOCCCNT_ID 306 +#define ALGOCCENABLED_ID 307 +#define STCK_ORDER_ID 308 +#define ALGOTTC1STATE_ID 309 +#define ALGOTTC1CNT_ID 310 +#define ALGOTTC1ENABLED_ID 311 +#define TTC1_EXEC_PHASE_ID 312 +#define TTC1_EXEC_PER_ID 313 +#define TTC1_LL_FRT_ID 314 +#define TTC1_LL_AFT_ID 315 +#define TTC1_UL_FRT_ID 316 +#define TTC1_UL_AFT_ID 317 +#define TTC1AVTEMPAFT_ID 318 +#define TTC1AVTEMPFRT_ID 319 +#define ALGOTTC2STATE_ID 320 +#define ALGOTTC2CNT_ID 321 +#define ALGOTTC2ENABLED_ID 322 +#define TTC2_EXEC_PER_ID 323 +#define TTC2_REF_TEMP_ID 324 +#define TTC2_OFFSETA_ID 325 +#define TTC2_OFFSETF_ID 326 +#define INTTIMEAFT_ID 327 +#define ONTIMEAFT_ID 328 +#define INTTIMEFRONT_ID 329 +#define ONTIMEFRONT_ID 330 +#define TTC2_PA_ID 331 +#define TTC2_DA_ID 332 +#define TTC2_IA_ID 333 +#define TTC2_PF_ID 334 +#define TTC2_DF_ID 335 +#define TTC2_IF_ID 336 +#define ALGOSAAEVALSTATE_ID 337 +#define ALGOSAAEVALCNT_ID 338 +#define ALGOSAAEVALENABLED_ID 339 +#define SAA_EXEC_PHASE_ID 340 +#define SAA_EXEC_PER_ID 341 +#define ISSAAACTIVE_ID 342 +#define SAACOUNTER_ID 343 +#define PINITSAACOUNTER_ID 344 +#define ALGOSDSEVALSTATE_ID 345 +#define ALGOSDSEVALCNT_ID 346 +#define ALGOSDSEVALENABLED_ID 347 +#define SDS_EXEC_PHASE_ID 348 +#define SDS_EXEC_PER_ID 349 +#define ISSDSACTIVE_ID 350 +#define SDS_FORCED_ID 351 +#define SDS_INHIBITED_ID 352 +#define EARTH_OCCULT_ACTIVE_ID 353 +#define HEARTBEAT_D1_ID 354 +#define HEARTBEAT_D2_ID 355 +#define HBSEM_ID 356 +#define STARMAP_ID 357 +#define OBSERVATIONID_ID 358 +#define CENTVALPROCOUTPUT_ID 359 +#define CENT_OFFSET_LIM_ID 360 +#define CENT_FROZEN_LIM_ID 361 +#define SEM_SERV1_1_FORWARD_ID 362 +#define SEM_SERV1_2_FORWARD_ID 363 +#define SEM_SERV1_7_FORWARD_ID 364 +#define SEM_SERV1_8_FORWARD_ID 365 +#define SEM_SERV3_1_FORWARD_ID 366 +#define SEM_SERV3_2_FORWARD_ID 367 +#define SEM_HK_TS_DEF_CRS_ID 368 +#define SEM_HK_TS_DEF_FINE_ID 369 +#define SEM_HK_TS_EXT_CRS_ID 370 +#define SEM_HK_TS_EXT_FINE_ID 371 +#define STAT_MODE_ID 372 +#define STAT_FLAGS_ID 373 +#define STAT_LAST_SPW_ERR_ID 374 +#define STAT_LAST_ERR_ID_ID 375 +#define STAT_LAST_ERR_FREQ_ID 376 +#define STAT_NUM_CMD_RECEIVED_ID 377 +#define STAT_NUM_CMD_EXECUTED_ID 378 +#define STAT_NUM_DATA_SENT_ID 379 +#define STAT_SCU_PROC_DUTY_CL_ID 380 +#define STAT_SCU_NUM_AHB_ERR_ID 381 +#define STAT_SCU_NUM_AHB_CERR_ID 382 +#define STAT_SCU_NUM_LUP_ERR_ID 383 +#define TEMP_SEM_SCU_ID 384 +#define TEMP_SEM_PCU_ID 385 +#define VOLT_SCU_P3_4_ID 386 +#define VOLT_SCU_P5_ID 387 +#define TEMP_FEE_CCD_ID 388 +#define TEMP_FEE_STRAP_ID 389 +#define TEMP_FEE_ADC_ID 390 +#define TEMP_FEE_BIAS_ID 391 +#define TEMP_FEE_DEB_ID 392 +#define VOLT_FEE_VOD_ID 393 +#define VOLT_FEE_VRD_ID 394 +#define VOLT_FEE_VOG_ID 395 +#define VOLT_FEE_VSS_ID 396 +#define VOLT_FEE_CCD_ID 397 +#define VOLT_FEE_CLK_ID 398 +#define VOLT_FEE_ANA_P5_ID 399 +#define VOLT_FEE_ANA_N5_ID 400 +#define VOLT_FEE_ANA_P3_3_ID 401 +#define CURR_FEE_CLK_BUF_ID 402 +#define VOLT_SCU_FPGA_P1_5_ID 403 +#define CURR_SCU_P3_4_ID 404 +#define STAT_NUM_SPW_ERR_CRE_ID 405 +#define STAT_NUM_SPW_ERR_ESC_ID 406 +#define STAT_NUM_SPW_ERR_DISC_ID 407 +#define STAT_NUM_SPW_ERR_PAR_ID 408 +#define STAT_NUM_SPW_ERR_WRSY_ID 409 +#define STAT_NUM_SPW_ERR_INVA_ID 410 +#define STAT_NUM_SPW_ERR_EOP_ID 411 +#define STAT_NUM_SPW_ERR_RXAH_ID 412 +#define STAT_NUM_SPW_ERR_TXAH_ID 413 +#define STAT_NUM_SPW_ERR_TXBL_ID 414 +#define STAT_NUM_SPW_ERR_TXLE_ID 415 +#define STAT_NUM_SP_ERR_RX_ID 416 +#define STAT_NUM_SP_ERR_TX_ID 417 +#define STAT_HEAT_PWM_FPA_CCD_ID 418 +#define STAT_HEAT_PWM_FEE_STR_ID 419 +#define STAT_HEAT_PWM_FEE_ANA_ID 420 +#define STAT_HEAT_PWM_SPARE_ID 421 +#define STAT_HEAT_PWM_FLAGS_ID 422 +#define STAT_OBTIME_SYNC_DELTA_ID 423 +#define TEMP_SEM_SCU_LW_ID 424 +#define TEMP_SEM_PCU_LW_ID 425 +#define VOLT_SCU_P3_4_LW_ID 426 +#define VOLT_SCU_P5_LW_ID 427 +#define TEMP_FEE_CCD_LW_ID 428 +#define TEMP_FEE_STRAP_LW_ID 429 +#define TEMP_FEE_ADC_LW_ID 430 +#define TEMP_FEE_BIAS_LW_ID 431 +#define TEMP_FEE_DEB_LW_ID 432 +#define VOLT_FEE_VOD_LW_ID 433 +#define VOLT_FEE_VRD_LW_ID 434 +#define VOLT_FEE_VOG_LW_ID 435 +#define VOLT_FEE_VSS_LW_ID 436 +#define VOLT_FEE_CCD_LW_ID 437 +#define VOLT_FEE_CLK_LW_ID 438 +#define VOLT_FEE_ANA_P5_LW_ID 439 +#define VOLT_FEE_ANA_N5_LW_ID 440 +#define VOLT_FEE_ANA_P3_3_LW_ID 441 +#define CURR_FEE_CLK_BUF_LW_ID 442 +#define VOLT_SCU_FPGA_P1_5_LW_ID 443 +#define CURR_SCU_P3_4_LW_ID 444 +#define TEMP_SEM_SCU_UW_ID 445 +#define TEMP_SEM_PCU_UW_ID 446 +#define VOLT_SCU_P3_4_UW_ID 447 +#define VOLT_SCU_P5_UW_ID 448 +#define TEMP_FEE_CCD_UW_ID 449 +#define TEMP_FEE_STRAP_UW_ID 450 +#define TEMP_FEE_ADC_UW_ID 451 +#define TEMP_FEE_BIAS_UW_ID 452 +#define TEMP_FEE_DEB_UW_ID 453 +#define VOLT_FEE_VOD_UW_ID 454 +#define VOLT_FEE_VRD_UW_ID 455 +#define VOLT_FEE_VOG_UW_ID 456 +#define VOLT_FEE_VSS_UW_ID 457 +#define VOLT_FEE_CCD_UW_ID 458 +#define VOLT_FEE_CLK_UW_ID 459 +#define VOLT_FEE_ANA_P5_UW_ID 460 +#define VOLT_FEE_ANA_N5_UW_ID 461 +#define VOLT_FEE_ANA_P3_3_UW_ID 462 +#define CURR_FEE_CLK_BUF_UW_ID 463 +#define VOLT_SCU_FPGA_P1_5_UW_ID 464 +#define CURR_SCU_P3_4_UW_ID 465 +#define TEMP_SEM_SCU_LA_ID 466 +#define TEMP_SEM_PCU_LA_ID 467 +#define VOLT_SCU_P3_4_LA_ID 468 +#define VOLT_SCU_P5_LA_ID 469 +#define TEMP_FEE_CCD_LA_ID 470 +#define TEMP_FEE_STRAP_LA_ID 471 +#define TEMP_FEE_ADC_LA_ID 472 +#define TEMP_FEE_BIAS_LA_ID 473 +#define TEMP_FEE_DEB_LA_ID 474 +#define VOLT_FEE_VOD_LA_ID 475 +#define VOLT_FEE_VRD_LA_ID 476 +#define VOLT_FEE_VOG_LA_ID 477 +#define VOLT_FEE_VSS_LA_ID 478 +#define VOLT_FEE_CCD_LA_ID 479 +#define VOLT_FEE_CLK_LA_ID 480 +#define VOLT_FEE_ANA_P5_LA_ID 481 +#define VOLT_FEE_ANA_N5_LA_ID 482 +#define VOLT_FEE_ANA_P3_3_LA_ID 483 +#define CURR_FEE_CLK_BUF_LA_ID 484 +#define VOLT_SCU_FPGA_P1_5_LA_ID 485 +#define CURR_SCU_P3_4_LA_ID 486 +#define TEMP_SEM_SCU_UA_ID 487 +#define TEMP_SEM_PCU_UA_ID 488 +#define VOLT_SCU_P3_4_UA_ID 489 +#define VOLT_SCU_P5_UA_ID 490 +#define TEMP_FEE_CCD_UA_ID 491 +#define TEMP_FEE_STRAP_UA_ID 492 +#define TEMP_FEE_ADC_UA_ID 493 +#define TEMP_FEE_BIAS_UA_ID 494 +#define TEMP_FEE_DEB_UA_ID 495 +#define VOLT_FEE_VOD_UA_ID 496 +#define VOLT_FEE_VRD_UA_ID 497 +#define VOLT_FEE_VOG_UA_ID 498 +#define VOLT_FEE_VSS_UA_ID 499 +#define VOLT_FEE_CCD_UA_ID 500 +#define VOLT_FEE_CLK_UA_ID 501 +#define VOLT_FEE_ANA_P5_UA_ID 502 +#define VOLT_FEE_ANA_N5_UA_ID 503 +#define VOLT_FEE_ANA_P3_3_UA_ID 504 +#define CURR_FEE_CLK_BUF_UA_ID 505 +#define VOLT_SCU_FPGA_P1_5_UA_ID 506 +#define CURR_SCU_P3_4_UA_ID 507 +#define SEMEVTCOUNTER_ID 508 +#define SEM_SERV5_1_FORWARD_ID 509 +#define SEM_SERV5_2_FORWARD_ID 510 +#define SEM_SERV5_3_FORWARD_ID 511 +#define SEM_SERV5_4_FORWARD_ID 512 +#define PEXPTIME_ID 513 +#define PIMAGEREP_ID 514 +#define PACQNUM_ID 515 +#define PDATAOS_ID 516 +#define PCCDRDMODE_ID 517 +#define PWINPOSX_ID 518 +#define PWINPOSY_ID 519 +#define PWINSIZEX_ID 520 +#define PWINSIZEY_ID 521 +#define PDTACQSRC_ID 522 +#define PTEMPCTRLTARGET_ID 523 +#define PVOLTFEEVOD_ID 524 +#define PVOLTFEEVRD_ID 525 +#define PVOLTFEEVSS_ID 526 +#define PHEATTEMPFPACCD_ID 527 +#define PHEATTEMPFEESTRAP_ID 528 +#define PHEATTEMPFEEANACH_ID 529 +#define PHEATTEMPSPARE_ID 530 +#define PSTEPENDIAGCCD_ID 531 +#define PSTEPENDIAGFEE_ID 532 +#define PSTEPENDIAGTEMP_ID 533 +#define PSTEPENDIAGANA_ID 534 +#define PSTEPENDIAGEXPOS_ID 535 +#define PSTEPDEBDIAGCCD_ID 536 +#define PSTEPDEBDIAGFEE_ID 537 +#define PSTEPDEBDIAGTEMP_ID 538 +#define PSTEPDEBDIAGANA_ID 539 +#define PSTEPDEBDIAGEXPOS_ID 540 +#define SEM_SERV220_6_FORWARD_ID 541 +#define SEM_SERV220_12_FORWARD_ID 542 +#define SEM_SERV222_6_FORWARD_ID 543 +#define SAVEIMAGESNODE_ID 544 +#define SAVEIMAGESCNT_ID 545 +#define SAVEIMAGES_PSAVETARGET_ID 546 +#define SAVEIMAGES_PFBFINIT_ID 547 +#define SAVEIMAGES_PFBFEND_ID 548 +#define ACQFULLDROPNODE_ID 549 +#define ACQFULLDROPCNT_ID 550 +#define ACQFULLDROP_PEXPTIME_ID 551 +#define ACQFULLDROP_PIMAGEREP_ID 552 +#define ACQFULLDROPT1_ID 553 +#define ACQFULLDROPT2_ID 554 +#define CALFULLSNAPNODE_ID 555 +#define CALFULLSNAPCNT_ID 556 +#define CALFULLSNAP_PEXPTIME_ID 557 +#define CALFULLSNAP_PIMAGEREP_ID 558 +#define CALFULLSNAP_PNMBIMAGES_ID 559 +#define CALFULLSNAP_PCENTSEL_ID 560 +#define CALFULLSNAPT1_ID 561 +#define CALFULLSNAPT2_ID 562 +#define SCIWINNODE_ID 563 +#define SCIWINCNT_ID 564 +#define SCIWIN_PNMBIMAGES_ID 565 +#define SCIWIN_PCCDRDMODE_ID 566 +#define SCIWIN_PEXPTIME_ID 567 +#define SCIWIN_PIMAGEREP_ID 568 +#define SCIWIN_PWINPOSX_ID 569 +#define SCIWIN_PWINPOSY_ID 570 +#define SCIWIN_PWINSIZEX_ID 571 +#define SCIWIN_PWINSIZEY_ID 572 +#define SCIWIN_PCENTSEL_ID 573 +#define SCIWINT1_ID 574 +#define SCIWINT2_ID 575 +#define FBFLOADNODE_ID 576 +#define FBFLOADCNT_ID 577 +#define FBFSAVENODE_ID 578 +#define FBFSAVECNT_ID 579 +#define FBFLOAD_PFBFID_ID 580 +#define FBFLOAD_PFBFNBLOCKS_ID 581 +#define FBFLOAD_PFBFRAMAREAID_ID 582 +#define FBFLOAD_PFBFRAMADDR_ID 583 +#define FBFSAVE_PFBFID_ID 584 +#define FBFSAVE_PFBFNBLOCKS_ID 585 +#define FBFSAVE_PFBFRAMAREAID_ID 586 +#define FBFSAVE_PFBFRAMADDR_ID 587 +#define FBFLOADBLOCKCOUNTER_ID 588 +#define FBFSAVEBLOCKCOUNTER_ID 589 +#define TRANSFBFTOGRNDNODE_ID 590 +#define TRANSFBFTOGRNDCNT_ID 591 +#define TRANSFBFTOGRND_PNMBFBF_ID 592 +#define TRANSFBFTOGRND_PFBFINIT_ID 593 +#define TRANSFBFTOGRND_PFBFSIZE_ID 594 +#define NOMSCINODE_ID 595 +#define NOMSCICNT_ID 596 +#define NOMSCI_PACQFLAG_ID 597 +#define NOMSCI_PCAL1FLAG_ID 598 +#define NOMSCI_PSCIFLAG_ID 599 +#define NOMSCI_PCAL2FLAG_ID 600 +#define NOMSCI_PCIBNFULL_ID 601 +#define NOMSCI_PCIBSIZEFULL_ID 602 +#define NOMSCI_PSIBNFULL_ID 603 +#define NOMSCI_PSIBSIZEFULL_ID 604 +#define NOMSCI_PGIBNFULL_ID 605 +#define NOMSCI_PGIBSIZEFULL_ID 606 +#define NOMSCI_PSIBNWIN_ID 607 +#define NOMSCI_PSIBSIZEWIN_ID 608 +#define NOMSCI_PCIBNWIN_ID 609 +#define NOMSCI_PCIBSIZEWIN_ID 610 +#define NOMSCI_PGIBNWIN_ID 611 +#define NOMSCI_PGIBSIZEWIN_ID 612 +#define NOMSCI_PEXPTIMEACQ_ID 613 +#define NOMSCI_PIMAGEREPACQ_ID 614 +#define NOMSCI_PEXPTIMECAL1_ID 615 +#define NOMSCI_PIMAGEREPCAL1_ID 616 +#define NOMSCI_PNMBIMAGESCAL1_ID 617 +#define NOMSCI_PCENTSELCAL1_ID 618 +#define NOMSCI_PNMBIMAGESSCI_ID 619 +#define NOMSCI_PCCDRDMODESCI_ID 620 +#define NOMSCI_PEXPTIMESCI_ID 621 +#define NOMSCI_PIMAGEREPSCI_ID 622 +#define NOMSCI_PWINPOSXSCI_ID 623 +#define NOMSCI_PWINPOSYSCI_ID 624 +#define NOMSCI_PWINSIZEXSCI_ID 625 +#define NOMSCI_PWINSIZEYSCI_ID 626 +#define NOMSCI_PCENTSELSCI_ID 627 +#define NOMSCI_PEXPTIMECAL2_ID 628 +#define NOMSCI_PIMAGEREPCAL2_ID 629 +#define NOMSCI_PNMBIMAGESCAL2_ID 630 +#define NOMSCI_PCENTSELCAL2_ID 631 +#define NOMSCI_PSAVETARGET_ID 632 +#define NOMSCI_PFBFINIT_ID 633 +#define NOMSCI_PFBFEND_ID 634 +#define NOMSCI_PSTCKORDERCAL1_ID 635 +#define NOMSCI_PSTCKORDERSCI_ID 636 +#define NOMSCI_PSTCKORDERCAL2_ID 637 +#define CONFIGSDB_PSDBCMD_ID 638 +#define CONFIGSDB_PCIBNFULL_ID 639 +#define CONFIGSDB_PCIBSIZEFULL_ID 640 +#define CONFIGSDB_PSIBNFULL_ID 641 +#define CONFIGSDB_PSIBSIZEFULL_ID 642 +#define CONFIGSDB_PGIBNFULL_ID 643 +#define CONFIGSDB_PGIBSIZEFULL_ID 644 +#define CONFIGSDB_PSIBNWIN_ID 645 +#define CONFIGSDB_PSIBSIZEWIN_ID 646 +#define CONFIGSDB_PCIBNWIN_ID 647 +#define CONFIGSDB_PCIBSIZEWIN_ID 648 +#define CONFIGSDB_PGIBNWIN_ID 649 +#define CONFIGSDB_PGIBSIZEWIN_ID 650 +#define ADC_P3V3_ID 651 +#define ADC_P5V_ID 652 +#define ADC_P1V8_ID 653 +#define ADC_P2V5_ID 654 +#define ADC_N5V_ID 655 +#define ADC_PGND_ID 656 +#define ADC_TEMPOH1A_ID 657 +#define ADC_TEMP1_ID 658 +#define ADC_TEMPOH2A_ID 659 +#define ADC_TEMPOH1B_ID 660 +#define ADC_TEMPOH3A_ID 661 +#define ADC_TEMPOH2B_ID 662 +#define ADC_TEMPOH4A_ID 663 +#define ADC_TEMPOH3B_ID 664 +#define ADC_TEMPOH4B_ID 665 +#define SEM_P15V_ID 666 +#define SEM_P30V_ID 667 +#define SEM_P5V0_ID 668 +#define SEM_P7V0_ID 669 +#define SEM_N5V0_ID 670 +#define ADC_P3V3_RAW_ID 671 +#define ADC_P5V_RAW_ID 672 +#define ADC_P1V8_RAW_ID 673 +#define ADC_P2V5_RAW_ID 674 +#define ADC_N5V_RAW_ID 675 +#define ADC_PGND_RAW_ID 676 +#define ADC_TEMPOH1A_RAW_ID 677 +#define ADC_TEMP1_RAW_ID 678 +#define ADC_TEMPOH2A_RAW_ID 679 +#define ADC_TEMPOH1B_RAW_ID 680 +#define ADC_TEMPOH3A_RAW_ID 681 +#define ADC_TEMPOH2B_RAW_ID 682 +#define ADC_TEMPOH4A_RAW_ID 683 +#define ADC_TEMPOH3B_RAW_ID 684 +#define ADC_TEMPOH4B_RAW_ID 685 +#define SEM_P15V_RAW_ID 686 +#define SEM_P30V_RAW_ID 687 +#define SEM_P5V0_RAW_ID 688 +#define SEM_P7V0_RAW_ID 689 +#define SEM_N5V0_RAW_ID 690 +#define ADC_P3V3_U_ID 691 +#define ADC_P5V_U_ID 692 +#define ADC_P1V8_U_ID 693 +#define ADC_P2V5_U_ID 694 +#define ADC_N5V_L_ID 695 +#define ADC_PGND_U_ID 696 +#define ADC_PGND_L_ID 697 +#define ADC_TEMPOH1A_U_ID 698 +#define ADC_TEMP1_U_ID 699 +#define ADC_TEMPOH2A_U_ID 700 +#define ADC_TEMPOH1B_U_ID 701 +#define ADC_TEMPOH3A_U_ID 702 +#define ADC_TEMPOH2B_U_ID 703 +#define ADC_TEMPOH4A_U_ID 704 +#define ADC_TEMPOH3B_U_ID 705 +#define ADC_TEMPOH4B_U_ID 706 +#define SEM_P15V_U_ID 707 +#define SEM_P30V_U_ID 708 +#define SEM_P5V0_U_ID 709 +#define SEM_P7V0_U_ID 710 +#define SEM_N5V0_L_ID 711 +#define HBSEMPASSWORD_ID 712 +#define HBSEMCOUNTER_ID 713 +#define ISWATCHDOGENABLED_ID 714 +#define ISSYNCHRONIZED_ID 715 +#define MISSEDMSGCNT_ID 716 +#define MISSEDPULSECNT_ID 717 +#define MILFRAMEDELAY_ID 718 +#define EL1_CHIP_ID 719 +#define EL2_CHIP_ID 720 +#define EL1_ADDR_ID 721 +#define EL2_ADDR_ID 722 +#define ERR_LOG_ENB_ID 723 +#define ISERRLOGVALID_ID 724 +#define NOFERRLOGENTRIES_ID 725 +#define MAX_SEM_PCKT_CYC_ID 726 +#define FBF_BLCK_WR_DUR_ID 727 +#define FBF_BLCK_RD_DUR_ID 728 +#define ISFBFOPEN_ID 729 +#define ISFBFVALID_ID 730 +#define FBF_ENB_ID 731 +#define FBF_CHIP_ID 732 +#define FBF_ADDR_ID 733 +#define FBFNBLOCKS_ID 734 +#define THR_MA_A_1_ID 735 +#define THR_MA_A_2_ID 736 +#define THR_MA_A_3_ID 737 +#define THR_MA_A_4_ID 738 +#define THR_MA_A_5_ID 739 +#define WCET_1_ID 740 +#define WCET_2_ID 741 +#define WCET_3_ID 742 +#define WCET_4_ID 743 +#define WCET_5_ID 744 +#define WCETAVER_1_ID 745 +#define WCETAVER_2_ID 746 +#define WCETAVER_3_ID 747 +#define WCETAVER_4_ID 748 +#define WCETAVER_5_ID 749 +#define WCETMAX_1_ID 750 +#define WCETMAX_2_ID 751 +#define WCETMAX_3_ID 752 +#define WCETMAX_4_ID 753 +#define WCETMAX_5_ID 754 +#define NOFNOTIF_1_ID 755 +#define NOFNOTIF_2_ID 756 +#define NOFNOTIF_3_ID 757 +#define NOFNOTIF_4_ID 758 +#define NOFNOTIF_5_ID 759 +#define NOFFUNCEXEC_1_ID 760 +#define NOFFUNCEXEC_2_ID 761 +#define NOFFUNCEXEC_3_ID 762 +#define NOFFUNCEXEC_4_ID 763 +#define NOFFUNCEXEC_5_ID 764 +#define WCETTIMESTAMPFINE_1_ID 765 +#define WCETTIMESTAMPFINE_2_ID 766 +#define WCETTIMESTAMPFINE_3_ID 767 +#define WCETTIMESTAMPFINE_4_ID 768 +#define WCETTIMESTAMPFINE_5_ID 769 +#define WCETTIMESTAMPCOARSE_1_ID 770 +#define WCETTIMESTAMPCOARSE_2_ID 771 +#define WCETTIMESTAMPCOARSE_3_ID 772 +#define WCETTIMESTAMPCOARSE_4_ID 773 +#define WCETTIMESTAMPCOARSE_5_ID 774 +#define FLASHCONTSTEPCNT_ID 775 +#define OTA_TM1A_NOM_ID 776 +#define OTA_TM1A_RED_ID 777 +#define OTA_TM1B_NOM_ID 778 +#define OTA_TM1B_RED_ID 779 +#define OTA_TM2A_NOM_ID 780 +#define OTA_TM2A_RED_ID 781 +#define OTA_TM2B_NOM_ID 782 +#define OTA_TM2B_RED_ID 783 +#define OTA_TM3A_NOM_ID 784 +#define OTA_TM3A_RED_ID 785 +#define OTA_TM3B_NOM_ID 786 +#define OTA_TM3B_RED_ID 787 +#define OTA_TM4A_NOM_ID 788 +#define OTA_TM4A_RED_ID 789 +#define OTA_TM4B_NOM_ID 790 +#define OTA_TM4B_RED_ID 791 +#define CORE0LOAD_ID 792 +#define CORE1LOAD_ID 793 +#define INTERRUPTRATE_ID 794 +#define CYCLICALACTIVITIESCTR_ID 795 +#define UPTIME_ID 796 +#define SEMTICK_ID 797 +#define SEMPWRONTIMESTAMP_ID 798 +#define SEMPWROFFTIMESTAMP_ID 799 +#define IASW_EVT_CTR_ID 800 +#define BAD_COPY_ID_ID 801 +#define BAD_PASTE_ID_ID 802 +#define OBCINPUTBUFFERPACKETS_ID 803 +#define GRNDINPUTBUFFERPACKETS_ID 804 +#define MILBUSBYTESIN_ID 805 +#define MILBUSBYTESOUT_ID 806 +#define MILBUSDROPPEDBYTES_ID 807 +#define IRL1_ID 808 +#define IRL1_AHBSTAT_ID 809 +#define IRL1_GRGPIO_6_ID 810 +#define IRL1_GRTIMER_ID 811 +#define IRL1_GPTIMER_0_ID 812 +#define IRL1_GPTIMER_1_ID 813 +#define IRL1_GPTIMER_2_ID 814 +#define IRL1_GPTIMER_3_ID 815 +#define IRL1_IRQMP_ID 816 +#define IRL1_B1553BRM_ID 817 +#define IRL2_ID 818 +#define IRL2_GRSPW2_0_ID 819 +#define IRL2_GRSPW2_1_ID 820 +#define SEMROUTE_ID 821 +#define SPW0BYTESIN_ID 822 +#define SPW0BYTESOUT_ID 823 +#define SPW1BYTESIN_ID 824 +#define SPW1BYTESOUT_ID 825 +#define SPW0TXDESCAVAIL_ID 826 +#define SPW0RXPCKTAVAIL_ID 827 +#define SPW1TXDESCAVAIL_ID 828 +#define SPW1RXPCKTAVAIL_ID 829 +#define MILCUCCOARSETIME_ID 830 +#define MILCUCFINETIME_ID 831 +#define CUCCOARSETIME_ID 832 +#define CUCFINETIME_ID 833 +#define SRAM1SCRCURRADDR_ID 834 +#define SRAM2SCRCURRADDR_ID 835 +#define SRAM1SCRLENGTH_ID 836 +#define SRAM2SCRLENGTH_ID 837 +#define EDACSINGLEREPAIRED_ID 838 +#define EDACSINGLEFAULTS_ID 839 +#define EDACLASTSINGLEFAIL_ID 840 +#define EDACDOUBLEFAULTS_ID 841 +#define EDACDOUBLEFADDR_ID 842 +#define CPU2PROCSTATUS_ID 843 +#define HEARTBEAT_ENABLED_ID 844 +#define S1ALLOCDBS_ID 845 +#define S1ALLOCSW_ID 846 +#define S1ALLOCHEAP_ID 847 +#define S1ALLOCFLASH_ID 848 +#define S1ALLOCAUX_ID 849 +#define S1ALLOCRES_ID 850 +#define S1ALLOCSWAP_ID 851 +#define S2ALLOCSCIHEAP_ID 852 +#define TAALGOID_ID 853 +#define TAACQALGOID_ID 854 +#define TASPARE32_ID 855 +#define TATIMINGPAR1_ID 856 +#define TATIMINGPAR2_ID 857 +#define TADISTANCETHRD_ID 858 +#define TAITERATIONS_ID 859 +#define TAREBINNINGFACT_ID 860 +#define TADETECTIONTHRD_ID 861 +#define TASEREDUCEDEXTR_ID 862 +#define TASEREDUCEDRADIUS_ID 863 +#define TASETOLERANCE_ID 864 +#define TAMVATOLERANCE_ID 865 +#define TAAMATOLERANCE_ID 866 +#define TAPOINTUNCERT_ID 867 +#define TATARGETSIG_ID 868 +#define TANROFSTARS_ID 869 +#define TAMAXSIGFRACT_ID 870 +#define TABIAS_ID 871 +#define TADARK_ID 872 +#define TASKYBG_ID 873 +#define COGBITS_ID 874 +#define CENT_MULT_X_ID 875 +#define CENT_MULT_Y_ID 876 +#define CENT_OFFSET_X_ID 877 +#define CENT_OFFSET_Y_ID 878 +#define CENT_MEDIANFILTER_ID 879 +#define CENT_DIM_X_ID 880 +#define CENT_DIM_Y_ID 881 +#define CENT_CHECKS_ID 882 +#define CEN_SIGMALIMIT_ID 883 +#define CEN_SIGNALLIMIT_ID 884 +#define CEN_MEDIAN_THRD_ID 885 +#define OPT_AXIS_X_ID 886 +#define OPT_AXIS_Y_ID 887 +#define DIST_CORR_ID 888 +#define PSTCKORDERSCI_ID 889 +#define PWINSIZEXSCI_ID 890 +#define PWINSIZEYSCI_ID 891 +#define SDPIMAGEAPTSHAPE_ID 892 +#define SDPIMAGEAPTX_ID 893 +#define SDPIMAGEAPTY_ID 894 +#define SDPIMGTTAPTSHAPE_ID 895 +#define SDPIMGTTAPTX_ID 896 +#define SDPIMGTTAPTY_ID 897 +#define SDPIMGTTSTCKORDER_ID 898 +#define SDPLOSSTCKORDER_ID 899 +#define SDPLBLKSTCKORDER_ID 900 +#define SDPLDKSTCKORDER_ID 901 +#define SDPRDKSTCKORDER_ID 902 +#define SDPRBLKSTCKORDER_ID 903 +#define SDPTOSSTCKORDER_ID 904 +#define SDPTDKSTCKORDER_ID 905 +#define SDPIMGTTSTRAT_ID 906 +#define SDP3STATAMPL_ID 907 +#define SDPPHOTSTRAT_ID 908 +#define SDPPHOTRCENT_ID 909 +#define SDPPHOTRANN1_ID 910 +#define SDPPHOTRANN2_ID 911 +#define SDPCRC_ID 912 +#define CCPRODUCT_ID 913 +#define CCSTEP_ID 914 +#define XIB_FAILURES_ID 915 +#define FEE_SIDE_A_ID 916 +#define FEE_SIDE_B_ID 917 +#define NLCBORDERS_ID 918 +#define NLCCOEFF_A_ID 919 +#define NLCCOEFF_B_ID 920 +#define NLCCOEFF_C_ID 921 +#define NLCCOEFF_D_ID 922 +#define SDPGLOBALBIAS_ID 923 +#define BIASORIGIN_ID 924 +#define SDPGLOBALGAIN_ID 925 +#define SDPWINIMAGECEKEY_ID 926 +#define SDPWINIMGTTCEKEY_ID 927 +#define SDPWINHDRCEKEY_ID 928 +#define SDPWINMLOSCEKEY_ID 929 +#define SDPWINMLBLKCEKEY_ID 930 +#define SDPWINMLDKCEKEY_ID 931 +#define SDPWINMRDKCEKEY_ID 932 +#define SDPWINMRBLKCEKEY_ID 933 +#define SDPWINMTOSCEKEY_ID 934 +#define SDPWINMTDKCEKEY_ID 935 +#define SDPFULLIMGCEKEY_ID 936 +#define SDPFULLHDRCEKEY_ID 937 +#define CE_TIMETAG_CRS_ID 938 +#define CE_TIMETAG_FINE_ID 939 +#define CE_COUNTER_ID 940 +#define CE_VERSION_ID 941 +#define CE_INTEGRITY_ID 942 +#define CE_SEMWINDOWPOSX_ID 943 +#define CE_SEMWINDOWPOSY_ID 944 +#define CE_SEMWINDOWSIZEX_ID 945 +#define CE_SEMWINDOWSIZEY_ID 946 +#define SPILL_CTR_ID 947 +#define RZIP_ITER1_ID 948 +#define RZIP_ITER2_ID 949 +#define RZIP_ITER3_ID 950 +#define RZIP_ITER4_ID 951 +#define SDPLDKCOLMASK_ID 952 +#define SDPRDKCOLMASK_ID 953 +#define FPGA_VERSION_ID 954 +#define FPGA_DPU_STATUS_ID 955 +#define FPGA_DPU_ADDRESS_ID 956 +#define FPGA_RESET_STATUS_ID 957 +#define FPGA_SEM_STATUS_ID 958 +#define FPGA_OPER_HEATER_STATUS_ID 959 +#define GIBTOTRANSFER_ID 960 +#define TRANSFERMODE_ID 961 +#define S2TOTRANSFERSIZE_ID 962 +#define S4TOTRANSFERSIZE_ID 963 +#define TRANSFERCOMPLETE_ID 964 +#define NLCBORDERS_2_ID 965 +#define NLCCOEFF_A_2_ID 966 +#define NLCCOEFF_B_2_ID 967 +#define NLCCOEFF_C_2_ID 968 +#define RF100_ID 969 +#define RF230_ID 970 +#define DISTC1_ID 971 +#define DISTC2_ID 972 +#define DISTC3_ID 973 +#define SPARE_UI_0_ID 974 +#define SPARE_UI_1_ID 975 +#define SPARE_UI_2_ID 976 +#define SPARE_UI_3_ID 977 +#define SPARE_UI_4_ID 978 +#define SPARE_UI_5_ID 979 +#define SPARE_UI_6_ID 980 +#define SPARE_UI_7_ID 981 +#define SPARE_UI_8_ID 982 +#define SPARE_UI_9_ID 983 +#define SPARE_UI_10_ID 984 +#define SPARE_UI_11_ID 985 +#define SPARE_UI_12_ID 986 +#define SPARE_UI_13_ID 987 +#define SPARE_UI_14_ID 988 +#define SPARE_UI_15_ID 989 +#define SPARE_F_0_ID 990 +#define SPARE_F_1_ID 991 +#define SPARE_F_2_ID 992 +#define SPARE_F_3_ID 993 +#define SPARE_F_4_ID 994 +#define SPARE_F_5_ID 995 +#define SPARE_F_6_ID 996 +#define SPARE_F_7_ID 997 +#define SPARE_F_8_ID 998 +#define SPARE_F_9_ID 999 +#define SPARE_F_10_ID 1000 +#define SPARE_F_11_ID 1001 +#define SPARE_F_12_ID 1002 +#define SPARE_F_13_ID 1003 +#define SPARE_F_14_ID 1004 +#define SPARE_F_15_ID 1005 + +#endif /* CRIADATAPOOLID_H_ */ diff --git a/CrIa/src/CrIaIasw.c b/CrIa/src/CrIaIasw.c new file mode 100644 index 0000000000000000000000000000000000000000..947bc6a83b9ef8fde464258baf068efbf55d1172 --- /dev/null +++ b/CrIa/src/CrIaIasw.c @@ -0,0 +1,2967 @@ +/** + * @file CrIaIasw.c + * @ingroup CrIaIasw + * @authors V. Cechticky and A. Pasetti, P&P Software GmbH, 2015; R. Ottensamer and C. Reimers, Institute for Astrophysics, 2015-2016 + * @date September, 2016 + * + * @brief Implementation of the functions provided or used by the IASW. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup CrIaIasw IASW Base Components + * @ingroup IASW + * @brief All IASW base components + * + * @defgroup CrIaConfig IASW Configuration + * @ingroup IASW + * @brief User-configurable constants and types as well as user-modifiable parameters for the IASW components + * + * @defgroup CrIaSm State Machines + * @ingroup IASW + * @brief All state machines used in the IASW + * + * @defgroup CrIaPr Procedures + * @ingroup IASW + * @brief All procedures used in the IASW except the @ref Science Procedures + * + * @defgroup CrIaServices TM/TC Services OBC/GRND + * @ingroup IASW + * @brief Services provided to OBC and Ground + * + * @defgroup CrIaServicesSem TM/TC Services SEM + * @ingroup IASW + * @brief Services provided to SEM + * + * @defgroup CrIaServicesGeneral TM/TC Services General + * @ingroup IASW + * @brief General constants, setters and getters for the TM/TC services + * + * @defgroup CrIaPrSci Science Procedures + * @ingroup IASW + * @brief All science procedures used in the IASW + * + * Operation in science mode consists of a sequence of observations. On-board, the execution + * of such a sequence of observations is controlled by a Science Procedure. Thus, a science + * procedure is responsible for: + * - Bringing the SEM into the correct science mode for a certain observation + * - Configuring the SEM in accordance with the read-out mode required for the observation. The SEM is configured through its (220,3) and (220,11) telecommands. + * - Configuring the SDB in accordance with the needs of the observation. + * - Starting and stopping the algorithms required for the observation. + * - Managing the transfer of processed science data to ground. + * - Waiting until the observation is terminated and then, if the procedure is not yet + * + * The SemTransition variable is used to report the arrival of mode-transition events from the SEM. The variable is set in + * function CrSemServ5EvtNormUpdateAction in response to the reception of an event from the SEM and holds the current SEM state + * as reported by the event. The SemTransition variable is a global variable visible throughout the software where it is used to + * check whether the SEM has performed a certain state transition. The variable SemTransition is only used for the SEM state + * machines and corresponding procedures. It is reset to zero after it was checked in a condition and will not be used + * afterwards. + * + * In function CrSemServ5EvtNormUpdateAction the flags CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_[xyz]_SET are set in response to + * the reception of an event from the SEM. They are used to report the arrival of a mode-changing event from the SEM and is used + * for the SEM Mode Time-Out FdCheck. The flags are checked every cycle after the responding command (e.g. sending + * "GoToStabilize") was sent and the transition starts. To signal the start of an transition the flags + * CMD_MODE_TRANSITION_TO_[xyz]_Flag were set. They are reset after a successfull mode-transition is reported from SEM. + */ + + +/* Includes */ +#include <CrIaIasw.h> +#include <CrIaPckt.h> +#include <CrIaInCmp.h> + +#include <FwSmConfig.h> +#include <FwPrConfig.h> +#include <FwPrCore.h> +#include <OutCmp/CrFwOutCmp.h> +#include <IfswUtilities.h> + +/* FW Profile files */ +#include <FwSmConstants.h> + +/* State machines */ +#include "CrIaPrSm/CrIaIaswCreate.h" +#include "CrIaPrSm/CrIaSemCreate.h" +#include "CrIaPrSm/CrIaFdCheckCreate.h" +#include "CrIaPrSm/CrIaSduCreate.h" +#include "CrIaPrSm/CrIaSdbCreate.h" +#include "CrIaPrSm/CrIaAlgoCreate.h" + +/* Procedures */ +#include "CrIaPrSm/CrIaNomSciCreate.h" +#include "CrIaPrSm/CrIaAcqFullDropCreate.h" +#include "CrIaPrSm/CrIaCalFullSnapCreate.h" +#include "CrIaPrSm/CrIaSciWinCreate.h" +#include "CrIaPrSm/CrIaPrepSciCreate.h" +#include "CrIaPrSm/CrIaSciDataUpdCreate.h" +#include "CrIaPrSm/CrIaSaveImagesCreate.h" +#include "CrIaPrSm/CrIaTransferFbfToGroundCreate.h" +#include "CrIaPrSm/CrIaCentAlgoCreate.h" +#include "CrIaPrSm/CrIaAcquAlgoExecCreate.h" +#include "CrIaPrSm/CrIaCmprAlgoExecCreate.h" +#include "CrIaPrSm/CrIaCentValProcCreate.h" +#include "CrIaPrSm/CrIaSaaEvalAlgoExecCreate.h" +#include "CrIaPrSm/CrIaSdsEvalAlgoExecCreate.h" +#include "CrIaPrSm/CrIaTTC1Create.h" +#include "CrIaPrSm/CrIaTTC2Create.h" +#include "CrIaPrSm/CrIaFbfLoadCreate.h" +#include "CrIaPrSm/CrIaFbfSaveCreate.h" +#include "CrIaPrSm/CrIaSemInitCreate.h" +#include "CrIaPrSm/CrIaSemShutdownCreate.h" +#include "CrIaPrSm/CrIaCtrldSwitchOffCreate.h" +#include "CrIaPrSm/CrIaSemAnoEvtRPCreate.h" +#include "CrIaPrSm/CrIaHbSemMonCreate.h" +#include "CrIaPrSm/CrIaSemConsCheckCreate.h" + +/* Common framework files */ +#include <CrFwTime.h> +#include <Pckt/CrFwPckt.h> +#include <BaseCmp/CrFwBaseCmp.h> +#include <UtilityFunctions/CrFwUtilityFunctions.h> + +/* InStream */ +#include <InLoader/CrFwInLoader.h> +#include <InStream/CrFwInStream.h> +#include <InFactory/CrFwInFactory.h> +#include <InManager/CrFwInManager.h> +#include <InRegistry/CrFwInRegistry.h> + +/* OutStream */ +#include <OutLoader/CrFwOutLoader.h> +#include <OutStream/CrFwOutStream.h> +#include <OutFactory/CrFwOutFactory.h> +#include <OutManager/CrFwOutManager.h> +#include <OutRegistry/CrFwOutRegistry.h> + +/* Auxiliary functions */ +#include <Aux/CrFwAux.h> +#include <OutFactory/CrFwOutFactory.h> + +/* has ResetEventCounts() */ +#include <Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h> + +/* endianess treatment */ +#include <byteorder.h> + +/* bcc library functions */ +#include <string.h> +#include <stdlib.h> + +#if (__sparc__) +#include <asm/leon.h> /* for leon3_cpuid() */ +#include <wrap_malloc.h> /* for SRAM2_SDB_ADDR */ +#include <error_log.h> /* for ERROR_LOG_INFO_SIZE */ +#include <ibsw_interface.h> +#include <iwf_fpga.h> +#include "../../ifsw.h" /* cpu1_notification */ +#else +#include <sys/ipc.h> /* for shared memory */ +#include <sys/shm.h> /* for shared memory */ +#endif + +#ifdef PC_TARGET +#include <stdio.h> +#include <time.h> +#include <unistd.h> +#include <errno.h> +#include <signal.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <arpa/inet.h> +#include <pthread.h> +#define OBC_ENDPOINT_FOR_IASW "127.0.0.1:5572" +#define IASW_ENDPOINT_FOR_SEM "127.0.0.1:5573" +#endif /* PC_TARGET */ + +/* DataPool */ +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* Services */ +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> +#include <Services/General/CrIaParamSetter.h> + +/* SEM Events */ +#include <CrIaSemEvents.h> + +#include <Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h> + +#include <IfswDebug.h> + +#include <ScienceDataProcessing.h> /* for CrIaSib */ + +#ifdef PC_TARGET +#include <TargetAcquisition.h> +#endif + +/* global variables */ +static int IASW_initialised; +unsigned int milFrameDelay = 20000; /* is updated cyclically from the DP */ +unsigned short SemTransition = 0; /* needed by SemFunc and SemOperFunc */ +FwSmBool_t semShutdownProcTerminated = 0; /* needed by SemFunc */ +unsigned short SemHkIaswStateExecCnt = 0; /* needed by FdCheckFunc and InRep/CrSemServ3DatHk */ +FwSmBool_t flagDelayedSemHkPacket = 0; /* needed by FdCheckFunc and SemFunc */ +FwSmBool_t signalSemStateStandby = 1; /* needed by CrSemServ5EvtNorm and SemFunc */ +unsigned int warnLimitDefCnt, alarmLimitDefCnt; /* needed for FdCheckFunc and InRep/CrSemServ3DatHk */ +unsigned int warnLimitExtCnt, alarmLimitExtCnt; /* needed for FdCheckFunc and InRep/CrSemServ3DatHk */ +unsigned int semAliveStatusDefCnt, semAliveStatusExtCnt; /* needed by FdCheckFunc and InRep/CrSemServ3DatHk */ +unsigned short SemAnoEvtId; /* needed by FdCheck */ +unsigned int *sibAddressFull = NULL; /* needed by CrIaSdbFunc */ +unsigned int *cibAddressFull = NULL; +unsigned int *gibAddressFull = NULL; +unsigned int *sibAddressWin = NULL; +unsigned int *cibAddressWin = NULL; +unsigned int *gibAddressWin = NULL; + +unsigned int *sdb_address_orig; +unsigned int *res_address_orig; +unsigned int *aux_address_orig; +unsigned int *swap_address_orig; +unsigned long int sdb_offset; /* the address is also offset */ +unsigned long int res_offset; /* the address is also offset */ +unsigned long int aux_offset; /* the address is also offset */ +unsigned long int swap_offset; /* the address is also offset */ +unsigned int *sdb_address_mod; /* the address we use is 1 kiB aligned and offset */ +unsigned int *res_address_mod; /* the address we use is 1 kiB aligned and offset */ +unsigned int *aux_address_mod; /* the address we use is 1 kiB aligned and offset */ +unsigned int *swap_address_mod; /* the address we use is 1 kiB aligned and offset */ + +#if (__sparc__) +struct CrIaSib incomingSibInStruct; /* needed for S21 input buffering */ +struct CrIaSib outgoingSibInStruct; /* needed for Centroiding and Acquisition */ +#else +struct CrIaSib *ShmIncomingSibInPTR; /* shared memory for fork() */ +struct CrIaSib *ShmOutgoingSibInPTR; /* shared memory for fork() */ +#endif /* (__sparc__) */ + +unsigned int S21LastAcqId = 0xffffffff; +unsigned short S21LastPacketNum = 0; +unsigned char S21_Flag1 = 0; +unsigned char signal_Ta = 0; +unsigned char S196Flag = 0; + +static unsigned int LoggedEntries = 0; + +struct IaswEvent { + CrFwServSubType_t SubType; + unsigned short used; /* NOTE: make sure this is initialized to 0 */ + unsigned short evtId; + unsigned short evtData[2]; /* all of our events have a DataSize of 4 bytes */ + unsigned int DataSize; +} ; + +static struct IaswEvent IbswEvents[ERR_LOG_N3]; + +static struct IaswEvent SdpEvents[ERR_LOG_N3]; + +/* Prototypes */ +#ifdef PC_TARGET +int ShmSdbAddressOrigID; +int ShmResAddressOrigID; +int ShmAuxAddressOrigID; +int ShmSwapAddressOrigID; +unsigned int *ShmRequestAcquisitionPTR; /* shared memory for fork() */ +unsigned int *ShmRequestCompressionPTR; /* shared memory for fork() */ +static void *accept_connections(void *ptr); +static int setupConnection(const char* url); +static void shutdownSocket(int socket); +void pollConnectionSem(); +static void pollConnectionMil(); +static void debugPacket(char* pckt, size_t size); +static CrFwBool_t socketSendPackageOnExistingConnection(int fdType, CrFwPckt_t pckt); +static CrFwBool_t socketSendPackageOnNewConnection(CrFwPckt_t pckt, const char* url); +static CrFwPckt_t socketReceivePackage(int fdType); +static CrFwBool_t socketCheckPackageAvailable(int fdType); +static int socketConnectPoll(const char* url); +static void reRouteCnC(CrFwPckt_t pckt); +#endif /* PC_TARGET */ + +void InsertCrc(CrFwPckt_t pckt); +void CrIaLoadHeartbeatReport(); +void CrIaLoadPredefinedHousekeeping(); +void CrIaLoadSemTimeCmd(); + +void pollConnectionSem(); +static void pollConnectionMil(); + +static void printPackageInfo(CrFwPckt_t pckt); + +#ifdef PC_TARGET +static unsigned int PcSemCycleCount; +static int PcSemCollPckt; +static int PcMilUsed; +static int PcCycCount; +static int socketObc, socketSem; +static int socketConnectPoll(const char* url); +static int fdSem; +pthread_t th_obc, th_sem; +void cpu_relax(void) { /* PC stub */ } +#endif /* PC_TARGET */ + +FwSmDesc_t inStreamSem; /* global variable used by SEM Unit State Machine */ +static FwSmDesc_t inStreamObc, inStreamGrd; + +/* global handles for the state machines */ +FwSmDesc_t smDescSem, smDescIasw; +FwSmDesc_t smDescFdTelescopeTempMonitorCheck, smDescFdIncorrectSDSCntrCheck, smDescFdSemCommErrCheck; +FwSmDesc_t smDescFdSemModeTimeOutCheck, smDescFdSemSafeModeCheck, smDescFdSemAliveCheck; +FwSmDesc_t smDescFdSemAnomalyEventCheck, smDescFdSemLimitCheck, smDescFdDpuHousekeepingCheck; +FwSmDesc_t smDescFdCentroidConsistencyCheck, smDescFdResourceCheck, smDescFdSemModeConsistencyCheck; +FwSmDesc_t smDescSdu2, smDescSdu4; +FwSmDesc_t smDescSdb; +FwSmDesc_t smDescAlgoCent0, smDescAlgoCent1, smDescAlgoTtc1, smDescAlgoTtc2, smDescAlgoAcq1, smDescAlgoCmpr, smDescAlgoSaaEval, smDescAlgoSdsEval; +FwSmDesc_t algoSm[MAX_ID_ALGO]; + +/* global handles for the procedures */ +FwPrDesc_t prDescNomSci, prDescAcqFullDrop, prDescCalFullSnap, prDescSciStack; +FwPrDesc_t prDescPrepSci, prDescSciDataUpd, prDescSaveImages, prDescTransferFbfToGround; +FwPrDesc_t prDescCentAlgo, prDescAcq1AlgoExec, prDescCmprAlgoExec, prDescTtc1aft, prDescTtc1front, prDescTtc2aft, prDescTtc2front; +FwPrDesc_t prDescFbfLoad, prDescFbfSave; +FwPrDesc_t prDescCentVal, prDescSaaEval, prDescSdsEval; +FwPrDesc_t prDescSemInit, prDescSemShutdown, prDescCtrldSwitchOffIasw; +FwPrDesc_t prDescSemAnoEvtRP, prDescHbSemMon, prDescSemModeConsistencyCheck; +FwPrDesc_t procPr[MAX_ID_PROC]; + +/* global handles for TM/TCs */ +FwSmDesc_t smDescSemTimeCmd; + +/* global handles For FdCheck */ +unsigned int fdSemCommErrCnt; + +/* in v09 we need a global handle for the S21,3 pckt to replace the SetData/GetData mechanism */ +CrFwPckt_t S21SemPacket; /* (char *) */ + +unsigned short evtDataRep[2]; + +#if (__sparc__) +static unsigned int routing_status; +#endif + +#ifdef PC_TARGET +struct th_arg +{ + int *sock_fd; + int *conn_fd; +}; + +struct th_arg arg_obc, arg_sem; +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +void fpga_heater_on(enum heater __attribute__((unused)) h) { /* PC stub */ } +void fpga_heater_off(enum heater __attribute__((unused)) h) { /* PC stub */ } +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +unsigned short cpu1_notification (unsigned short action) +{ + /*return action;*/ + CRIA_UNUSED(action); + return SDP_STATUS_IDLE; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +/** + * * handle partial transmissions + * */ +static int send_all(int sockfd, char *buf, int len) +{ + int n; + + while(len) + { + n = send(sockfd, buf, len, 0); + if (n == -1) + { + perror("send_all"); + return len; + } + len -= n; + buf += n; + } + + return len; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +void sigint_handler(int s __attribute__((unused))) +{ + pthread_cancel(th_sem); + + if(fdSem) + close(fdSem); + if(socketObc) + close(socketObc); + if(socketSem) + close(socketSem); + + DEBUGP("\nExiting\n"); + exit(EXIT_SUCCESS); /* that's debatable */ + + return; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +void setupConnections() +{ + int err; + + socketSem = setupConnection(IASW_ENDPOINT_FOR_SEM); + + if((err = pthread_create(&th_sem, NULL, accept_connections, &arg_sem))) + { + DEBUGP("Epic fail in pthread_create: %s\n", strerror(err)); + exit(EXIT_FAILURE); + } + + arg_sem.sock_fd = &socketSem; + arg_sem.conn_fd = &fdSem; + + socketObc = socketConnectPoll(OBC_ENDPOINT_FOR_IASW); + DEBUGP("Socket connection established to: %s\n", OBC_ENDPOINT_FOR_IASW); + + return; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +void shutdownConnections() +{ + shutdownSocket(socketObc); + shutdownSocket(socketSem); + + return; +} +#endif /* PC_TARGET */ + + +/* PC FBF Stubs */ +#ifdef PC_TARGET +int CrIbFlashIsReady(void) {return 1; /* stub */} +void CrIbFbfClose(unsigned char __attribute__((unused)) fbf){/* stub */} +void CrIbFbfOpen(unsigned char __attribute__((unused)) fbf){/* stub */} +int CrIbFlashTriggerWrite(unsigned char __attribute__((unused)) fbf, unsigned int __attribute__((unused)) *mem){return 0; /* stub */} +int CrIbFlashTriggerRead(unsigned char __attribute__((unused)) fbf, unsigned short __attribute__((unused)) block, unsigned int __attribute__((unused)) *mem){return 0; /* stub */} +unsigned int flash_gen_logical_addr(unsigned int __attribute__((unused)) block, unsigned int __attribute__((unused)) page, unsigned int __attribute__((unused)) offset){return 0; /* stub */} +#endif /* PC_TARGET */ + + +/* these need to be global to enable the CrIaOutStreamConnectionAvail() in the cyc activities */ +FwSmDesc_t outStreamSem, outStreamObc, outStreamGrd; + + +/** + * @brief IASW Initialization Function implementing all initialization actions for the IASW + * + * - instantiate and start all IASW state machines needed by the IASW + * - instantiate all IASW procedures needed by the IASW + * - instantiate and initialize all IASW data structures + * - load the predefined housekeeping reports and the heartbeat report + * - start the SDS Evaluation Algorithm + * - start the TTC Algorithms + * - initialize the buildNumber variable in the data pool + * + * @note Ready Check Procedure of the predefined housekeeping reports is not used + * @note Watchdog Reset Procedure is not used + * + * @param none + */ +int CrIaInit() +{ + FwSmDesc_t fwCmp[CR_IA_NOF_FW_CMP]; + int i, i_algo; + unsigned int buildNumber; + unsigned char FdCheckDpuHousekeepingIntEn, FdCheckResourceIntEn; + +#ifdef PC_TARGET + PcCycCount = 0; +#endif /* PC_TARGET */ + + /* + NOTE: If we wanted to test the RAM EDAC, we would instrument the code + here like this: + + CrIbInjectFault(1,3,(void *)SRAM1_FLASH_ADDR); + CrIbInjectFault(1,2,(void *)(SRAM1_FLASH_ADDR + 40*4096)); + */ + + /** + * N1: Instantiate the Data Pool + */ + + /* set LTbl init for Crc to 0 */ + LTblInit = 0; + + /* clear all SEM event flags */ + CrIaClearSemEventFlags(); + + /* reset the V09+ event filter */ + ResetEventCounts(); + + /* insert the build number into the data pool */ + buildNumber = BUILD; + CrIaPaste(BUILDNUMBER_ID, &buildNumber); + + /** + * N2: Instantiate all IASW-Specific Components, like all the state machines + */ + DEBUGP("### CrIaInit ### Instantiate all IASW-Specific Components\n"); + + /********************/ + /* SDB Structure SM */ + /********************/ + + /* due to the 16 bit sib, cib, gib pointers, we need special measures + to manage the SDB */ +#if (__sparc__) + sdb_address_orig = (unsigned int *)SRAM2_SDB_ADDR; + res_address_orig = (unsigned int *)SRAM1_RES_ADDR; + aux_address_orig = (unsigned int *)SRAM1_AUX_ADDR; + swap_address_orig = (unsigned int *)SRAM1_SWAP_ADDR; +#else + /* on the PC we simulate the SRAM2 SDB with a 32 MiB buffer in a shared memory */ + ShmSdbAddressOrigID = shmget(IPC_PRIVATE, 32*1024*1024, IPC_CREAT | 0666); + ShmResAddressOrigID = shmget(IPC_PRIVATE, 6*1024*1024, IPC_CREAT | 0666); + ShmAuxAddressOrigID = shmget(IPC_PRIVATE, 4*1024*1024, IPC_CREAT | 0666); + ShmSwapAddressOrigID = shmget(IPC_PRIVATE, 6*1024*1024, IPC_CREAT | 0666); + + sdb_address_orig = (unsigned int *) shmat(ShmSdbAddressOrigID, NULL, 0); + res_address_orig = (unsigned int *) shmat(ShmResAddressOrigID, NULL, 0); + aux_address_orig = (unsigned int *) shmat(ShmAuxAddressOrigID, NULL, 0); + swap_address_orig = (unsigned int *) shmat(ShmSwapAddressOrigID, NULL, 0); +#endif /* __sparc__ */ + + /* align the address to 1 kiB */ + sdb_address_mod = (unsigned int *)((((unsigned int)sdb_address_orig) + 1023) & 0xFFFFFC00); + res_address_mod = (unsigned int *)((((unsigned int)res_address_orig) + 1023) & 0xFFFFFC00); + aux_address_mod = (unsigned int *)((((unsigned int)aux_address_orig) + 1023) & 0xFFFFFC00); + swap_address_mod = (unsigned int *)((((unsigned int)swap_address_orig) + 1023) & 0xFFFFFC00); + + /* the address shifted by 10 is still larger than 16 bit, so we need a local offset */ + sdb_offset = (unsigned int)sdb_address_mod; + res_offset = (unsigned int)res_address_mod; + aux_offset = (unsigned int)aux_address_mod; + swap_offset = (unsigned int)swap_address_mod; + + + smDescSdb = CrIaSdbCreate(NULL); + if (FwSmCheckRec(smDescSdb) != smSuccess) + { + DEBUGP("SDB SM is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + DEBUGP("# Start SDB SM ...\n"); + FwSmStart(smDescSdb); + + /********************/ + /* SDU SMs */ + /********************/ + smDescSdu2 = CrIaSduCreate(NULL); + if (FwSmCheckRec(smDescSdu2) != smSuccess) + { + DEBUGP("SDU2 SM is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + DEBUGP("# Start SDU2 SM ...\n"); + FwSmStart(smDescSdu2); + + smDescSdu4 = CrIaSduCreate(NULL); + if (FwSmCheckRec(smDescSdu4) != smSuccess) + { + DEBUGP("SDU4 SM is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + DEBUGP("# Start SDU4 SM ...\n"); + FwSmStart(smDescSdu4); + + /********************/ + /* FD Check SMs */ + /********************/ + + /* Instantiation of State Machine for FdCheck Telescope Temperature Monitor */ + smDescFdTelescopeTempMonitorCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdTelescopeTempMonitorCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for Telescope Temperature Monitor is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdTelescopeTempMonitorCheck); + + /** Instantiation of State Machine for FdCheck Incorrect Science Data Sequence Counter */ + smDescFdIncorrectSDSCntrCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdIncorrectSDSCntrCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for Incorrect Science Data Sequence Counter is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdIncorrectSDSCntrCheck); + + /** Instantiation of State Machine for FdCheck SEM Communication Error */ + smDescFdSemCommErrCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdSemCommErrCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for SEM Communication Error is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdSemCommErrCheck); + + /** Instantiation of State Machine for FdCheck SEM Mode Time-Out */ + smDescFdSemModeTimeOutCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdSemModeTimeOutCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for SEM Mode Time-Out is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdSemModeTimeOutCheck); + + /* SEM Safe Mode */ + smDescFdSemSafeModeCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdSemSafeModeCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for SEM Safe Mode Check is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdSemSafeModeCheck); + + /* SEM Alive Check */ + smDescFdSemAliveCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdSemAliveCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for SEM Alive Check is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdSemAliveCheck); + + /** Instantiation of State Machine for FdCheck SEM Anomaly Event */ + smDescFdSemAnomalyEventCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdSemAnomalyEventCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for SEM Anomaly Event is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdSemAnomalyEventCheck); + + /** Instantiation of State Machine for FdCheck SEM Limit Check */ + smDescFdSemLimitCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdSemLimitCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for SEM Limit Check is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdSemLimitCheck); + + /** Instantiation of State Machine for FdCheck DPU Housekeeping Check */ + smDescFdDpuHousekeepingCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdDpuHousekeepingCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for DPU Housekeeping Check is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdDpuHousekeepingCheck); + /* Enable DPU housekeeping FdCheck */ + FdCheckDpuHousekeepingIntEn = 1; + CrIaPaste(FDCHECKDPUHKINTEN_ID, &FdCheckDpuHousekeepingIntEn); + + /** Instantiation of State Machine for FdCheck Centroid Consistency Check */ + smDescFdCentroidConsistencyCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdCentroidConsistencyCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for Centroid Consistency Check is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdCentroidConsistencyCheck); + + /** Instantiation of State Machine for FdCheck Resource Check */ + smDescFdResourceCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdResourceCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for Resource Check is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdResourceCheck); + /* Enable Resource FdCheck */ + FdCheckResourceIntEn = 1; + CrIaPaste(FDCHECKRESINTEN_ID, &FdCheckResourceIntEn); + + /** Instantiation of State Machine for FdCheck SEM Mode Consistency Check */ + smDescFdSemModeConsistencyCheck = CrIaFdCheckCreate(NULL); + if (FwSmCheckRec(smDescFdSemModeConsistencyCheck) != smSuccess) + { + DEBUGP("The state machine CrIaFdCheck for SEM Mode Consistency Check is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + FwSmStart(smDescFdSemModeConsistencyCheck); + + /********************/ + /* Save Images Pr */ + /********************/ + prDescSaveImages = CrIaSaveImagesCreate(NULL); + if (FwPrCheck(prDescSaveImages) != prSuccess) + { + DEBUGP("Save Images PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /*****************************/ + /* Transfer Fbf To Ground Pr */ + /*****************************/ + prDescTransferFbfToGround = CrIaTransferFbfToGroundCreate(NULL); + if (FwPrCheck(prDescTransferFbfToGround) != prSuccess) + { + DEBUGP("Transfer Fbf To Ground PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* Nom Science Pr */ + /********************/ + prDescNomSci = CrIaNomSciCreate(NULL); + if (FwPrCheck(prDescNomSci) != prSuccess) + { + DEBUGP("Nominal Science PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* Acq Full Drop Pr */ + /********************/ + prDescAcqFullDrop = CrIaAcqFullDropCreate(NULL); + if (FwPrCheck(prDescAcqFullDrop) != prSuccess) + { + DEBUGP("Acquire Full Drop PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* Cal Full Snap Pr */ + /********************/ + prDescCalFullSnap = CrIaCalFullSnapCreate(NULL); + if (FwPrCheck(prDescCalFullSnap) != prSuccess) + { + DEBUGP("Calibrate Full Snap PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* Science Stack Pr */ + /********************/ + prDescSciStack = CrIaSciWinCreate(NULL); + if (FwPrCheck(prDescSciStack) != prSuccess) + { + DEBUGP("Science Stack PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* PreScience Pr */ + /********************/ + prDescPrepSci = CrIaPrepSciCreate(NULL); + if (FwPrCheck(prDescPrepSci) != prSuccess) + { + DEBUGP("Prepare Science PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* CentAlgo Pr */ + /********************/ + prDescCentAlgo = CrIaCentAlgoCreate(NULL); + if (FwPrCheck(prDescCentAlgo) != prSuccess) + { + DEBUGP("Cent Algo PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* Acq1Algo Exec Pr */ + /********************/ + prDescAcq1AlgoExec = CrIaAcquAlgoExecCreate(NULL); + if (FwPrCheck(prDescAcq1AlgoExec) != prSuccess) + { + DEBUGP("Acq1 Algo Exec PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* CmprAlgo Exec Pr */ + /********************/ + prDescCmprAlgoExec = CrIaCmprAlgoExecCreate(NULL); + if (FwPrCheck(prDescCmprAlgoExec) != prSuccess) + { + DEBUGP("Cmpr Algo Exec PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* TTC1 Pr */ + /********************/ + prDescTtc1aft = CrIaTTC1Create(NULL); + if (FwPrCheck(prDescTtc1aft) != prSuccess) + { + DEBUGP("TTC1 PR for aft thermistors/heaters is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + prDescTtc1front = CrIaTTC1Create(NULL); + if (FwPrCheck(prDescTtc1front) != prSuccess) + { + DEBUGP("TTC1 PR for front thermistors/heaters is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* TTC2 Pr */ + /********************/ + prDescTtc2aft = CrIaTTC2Create(NULL); + if (FwPrCheck(prDescTtc2aft) != prSuccess) + { + DEBUGP("TTC2 PR for aft thermistors/heaters is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + prDescTtc2front = CrIaTTC2Create(NULL); + if (FwPrCheck(prDescTtc2front) != prSuccess) + { + DEBUGP("TTC2 PR for front thermistors/heaters is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* Fbf Pr's */ + /********************/ + prDescFbfLoad = CrIaFbfLoadCreate(NULL); + if (FwPrCheck(prDescFbfLoad) != prSuccess) + { + DEBUGP("FBF Load PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + prDescFbfSave = CrIaFbfSaveCreate(NULL); + if (FwPrCheck(prDescFbfSave) != prSuccess) + { + DEBUGP("FBF Save PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /* initialize procedure descriptors in an array */ + procPr[CRIA_SERV198_SAVE_IMG_PR-1] = prDescSaveImages; + procPr[CRIA_SERV198_ACQ_FULL_DROP-1] = prDescAcqFullDrop; + procPr[CRIA_SERV198_CAL_FULL_SNAP-1] = prDescCalFullSnap; + procPr[CRIA_SERV198_FBF_LOAD_PR-1] = prDescFbfLoad; + procPr[CRIA_SERV198_FBF_SAVE_PR-1] = prDescFbfSave; + procPr[CRIA_SERV198_SCI_STACK_PR-1] = prDescSciStack; + procPr[CRIA_SERV198_FBF_TO_GND_PR-1] = prDescTransferFbfToGround; + procPr[CRIA_SERV198_NOM_SCI_PR-1] = prDescNomSci; + procPr[CRIA_SERV198_CONFIG_SDB_PR-1] = NULL; /* this procedure is instantaneous */ + + /********************/ + /* Validity Pr's */ + /********************/ + prDescCentVal = CrIaCentValProcCreate(NULL); + if (FwPrCheck(prDescCentVal) != prSuccess) + { + DEBUGP("Centroid Validity PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + prDescSaaEval = CrIaSaaEvalAlgoExecCreate(NULL); + if (FwPrCheck(prDescSaaEval) != prSuccess) + { + DEBUGP("SAA Evaluation PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + prDescSdsEval = CrIaSdsEvalAlgoExecCreate(NULL); + if (FwPrCheck(prDescSdsEval) != prSuccess) + { + DEBUGP("SDS Evaluation PR is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* SEM Init Pr */ + /********************/ + prDescSemInit = CrIaSemInitCreate(NULL); + if (FwPrCheck(prDescSemInit) != prSuccess) { + DEBUGP("The procedure CrIaSemInit is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* SEM Shutdown Pr */ + /********************/ + prDescSemShutdown = CrIaSemShutdownCreate(NULL); + if (FwPrCheck(prDescSemShutdown) != prSuccess) + { + DEBUGP("The procedure CrIaSemShutdown is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /***********************/ + /* Ctrld Switch Off Pr */ + /***********************/ + prDescCtrldSwitchOffIasw = CrIaCtrldSwitchOffCreate(NULL); + if (FwPrCheck(prDescCtrldSwitchOffIasw) != prSuccess) + { + DEBUGP("The procedure CrIaCtrldSwitchOff is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /************************/ + /* SEM Anomaly Event Pr */ + /************************/ + prDescSemAnoEvtRP = CrIaSemAnoEvtRPCreate(NULL); + if (FwPrCheck(prDescSemAnoEvtRP) != prSuccess) + { + DEBUGP("The procedure CrIaSemAnoEvtRP is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + + /********************/ + /* SEM Unit SM */ + /********************/ + /** Define the state machine descriptor (SMD) */ + smDescSem = CrIaSemCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDescSem) != smSuccess) + { + DEBUGP("The SEM state machine is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The SEM state machine is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + DEBUGP("# Start SEM State Machine ...\n"); + FwSmStart(smDescSem); /* -> enters state OFF */ + + /********************/ + /* Algo SMs */ + /********************/ + smDescAlgoCent0 = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoCent0) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for Cent0 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The state machine CrIaAlgo for Cent0 is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + FwSmStart(smDescAlgoCent0); + + smDescAlgoCent1 = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoCent1) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for Cent1 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The state machine CrIaAlgo for Cent1 is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + FwSmStart(smDescAlgoCent1); + + smDescAlgoTtc1 = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoTtc1) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for Ttc1 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + DEBUGP("The state machine CrIaAlgo for Ttc1 is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + FwSmStart(smDescAlgoTtc1); + + smDescAlgoTtc2 = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoTtc2) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for Ttc2 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + DEBUGP("The state machine CrIaAlgo for Ttc2 is properly configured ... SUCCESS\n"); + } +#ifdef PC_TARGET +{ + /* Set the enable status of the TTC2 Algorithm to true, because the Data Pool is still not initialized */ + unsigned char algoTtc2Enabled = 1; + CrIaPaste(ALGOTTC2ENABLED_ID, &algoTtc2Enabled); +} +#endif /* PC_TARGET */ + /** Start the SM */ + FwSmStart(smDescAlgoTtc2); + /** Activate TTC2 Algorithm by default */ + FwSmMakeTrans(smDescAlgoTtc2, Start); + + smDescAlgoAcq1 = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoAcq1) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for Acq1 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The state machine CrIaAlgo for Acq1 is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + FwSmStart(smDescAlgoAcq1); + + smDescAlgoCmpr = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoCmpr) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for Cmpr is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The state machine CrIaAlgo for Cmpr is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + FwSmStart(smDescAlgoCmpr); + + smDescAlgoSaaEval = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoSaaEval) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for SAA Eval is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The state machine CrIaAlgo for SAA Eval is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + FwSmStart(smDescAlgoSaaEval); + + smDescAlgoSdsEval = CrIaAlgoCreate(NULL); + if (FwSmCheckRec(smDescAlgoSdsEval) != smSuccess) + { + DEBUGP("The state machine CrIaAlgo for SDS Eval is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The state machine CrIaAlgo for SDS Eval is properly configured ... SUCCESS\n"); + } + /** Start the SM */ + FwSmStart(smDescAlgoSdsEval); + /** Mantis 2232: Activate SDS Algorithm by default */ + FwSmMakeTrans(smDescAlgoSdsEval, Start); + + for (i_algo=0;i_algo<MAX_ID_ALGO;i_algo++) + { + algoSm[i_algo] = NULL; + } + algoSm[SAA_EVAL_ALGO-1] = smDescAlgoSaaEval; + algoSm[CLCT_ALGO-1] = smDescAlgoCmpr; + algoSm[ACQ1_ALGO-1] = smDescAlgoAcq1; + algoSm[CNT1_ALGO-1] = smDescAlgoCent1; + algoSm[SDS_EVAL_ALGO-1] = smDescAlgoSdsEval; + algoSm[TTC1_ALGO-1] = smDescAlgoTtc1; + algoSm[TTC2_ALGO-1] = smDescAlgoTtc2; + algoSm[CENT0_ALGO-1] = smDescAlgoCent0; + + + /********************/ + /* Sci Data Upd Pr * (21,3) InRep from SEM */ + /********************/ + prDescSciDataUpd = CrIaSciDataUpdCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDescSciDataUpd) != prSuccess) + { + DEBUGP("The procedure CrIaSciDataUpd is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The procedure CrIaSciDataUpd is properly configured ... SUCCESS\n"); + } + + /********************/ + /* HbSem Mon Pr */ + /********************/ + prDescHbSemMon = CrIaHbSemMonCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDescHbSemMon) != prSuccess) { + DEBUGP("The procedure CrIaHbSemMon is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The procedure CrIaHbSemMon is properly configured ... SUCCESS\n"); + } + /** Start the procedure */ + FwPrStart(prDescHbSemMon); + + /***************************/ + /* SEM Mode Consistency Pr */ + /***************************/ + prDescSemModeConsistencyCheck = CrIaSemConsCheckCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDescSemModeConsistencyCheck) != prSuccess) { + DEBUGP("The procedure CrIaSemConsCheck is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The procedure CrIaSemConsCheck is properly configured ... SUCCESS\n"); + } + + /** + * N3: Instantiate all Framework Components + * This is done by calling the factory functions + * offered by the CORDET Framework + */ + + /* Check consistency of configuration parameters */ + switch (CrFwAuxConfigCheck()) + { + case crConsistencyCheckSuccess: + DEBUGP("### CrIaInit ### MA: Consistency check of configuration parameters ran successfully.\n"); + break; + case crOutRegistryConfigParInconsistent: + DEBUGP("Consistency check of OutRegistry parameters failed\n"); + return -1; + case crOutFactoryConfigParInconsistent: + DEBUGP("Consistency check of OutFactory parameters failed\n"); + return -1; + case crInFactoryInCmdConfigParInconsistent: + DEBUGP("Consistency check of InCommand parameters in InFactory failed\n"); + return -1; + case crInFactoryInRepConfigParInconsistent: + DEBUGP("Consistency check of InRepot parameters in InFactory failed\n"); + return -1; + } + + /* Create In- and OutStreams */ + inStreamSem = CrFwInStreamMake(0); + inStreamObc = CrFwInStreamMake(1); + inStreamGrd = CrFwInStreamMake(2); + outStreamSem = CrFwOutStreamMake(0); + outStreamObc = CrFwOutStreamMake(1); + outStreamGrd = CrFwOutStreamMake(2); + + /** + * N4: Start all IASW State Machines + * This is done through the framework- + * function FwSmStart + */ + + /** Define the state machine descriptor (SMD) */ + smDescIasw = CrIaIaswCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDescIasw) != smSuccess) + { + DEBUGP("The IASW state machine is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else + { + DEBUGP("The IASW state machine is properly configured ... SUCCESS\n"); + } + + /** Start the SM */ + DEBUGP("# Start IASW State Machine ...\n"); + FwSmStart(smDescIasw); + + /** + * N5: Initialize all Framework Components + * This is done through the framework- + * provided function CrFwCmpInit + */ + + /* Initialize the In- and OutStreams */ + CrFwCmpInit(inStreamSem); + CrFwCmpInit(inStreamObc); + CrFwCmpInit(inStreamGrd); + CrFwCmpInit(outStreamSem); + CrFwCmpInit(outStreamObc); + CrFwCmpInit(outStreamGrd); + if (!CrFwCmpIsInInitialized(inStreamSem)) return -1; + if (!CrFwCmpIsInInitialized(inStreamObc)) return -1; + if (!CrFwCmpIsInInitialized(inStreamGrd)) return -1; + if (!CrFwCmpIsInInitialized(outStreamSem)) return -1; + if (!CrFwCmpIsInInitialized(outStreamObc)) return -1; + if (!CrFwCmpIsInInitialized(outStreamGrd)) return -1; + + /** + * N6: Configure all Framework Components + * This is done through the framework- + * provided function CrFwCmpReset + */ + + /* Configure the In- and OutStreams */ + CrFwCmpReset(inStreamSem); + CrFwCmpReset(inStreamObc); + CrFwCmpReset(inStreamGrd); + CrFwCmpReset(outStreamSem); + CrFwCmpReset(outStreamObc); + CrFwCmpReset(outStreamGrd); + + /* Initialize and reset framework components */ + fwCmp[0] = CrFwOutFactoryMake(); + fwCmp[1] = CrFwInFactoryMake(); + fwCmp[2] = CrFwInLoaderMake(); + fwCmp[3] = CrFwInManagerMake(0); + fwCmp[4] = CrFwInManagerMake(1); + fwCmp[5] = CrFwInRegistryMake(); + fwCmp[6] = CrFwOutLoaderMake(); + fwCmp[7] = CrFwOutRegistryMake(); + fwCmp[8] = CrFwOutManagerMake(0); + fwCmp[9] = CrFwOutManagerMake(1); + fwCmp[10] = CrFwOutManagerMake(2); + + /** + * N7: Perform Configuartion Check + * on Framwork Components + * The framework configuration check verifies + * that all framework components are in state + * CONFIGURED (this is done using function + * CrFwCmpIsInConfigured + */ + if (!CrFwCmpIsInConfigured(inStreamSem)) return -1; + if (!CrFwCmpIsInConfigured(inStreamObc)) return -1; + if (!CrFwCmpIsInConfigured(inStreamGrd)) return -1; + if (!CrFwCmpIsInConfigured(outStreamSem)) return -1; + if (!CrFwCmpIsInConfigured(outStreamObc)) return -1; + if (!CrFwCmpIsInConfigured(outStreamGrd)) return -1; + + for (i=0; i<CR_IA_NOF_FW_CMP; i++) + { + CrFwCmpInit(fwCmp[i]); + if (!CrFwCmpIsInInitialized(fwCmp[i])) return -1; + CrFwCmpReset(fwCmp[i]); + if (!CrFwCmpIsInConfigured(fwCmp[i])) return -1; + } + + /* If instantiation or configuration check successful */ + CrIaLoadPredefinedHousekeeping(); + CrIaLoadHeartbeatReport(); + + /* DEBUGP("INIT SUCCESSFUL!\n"); */ + + IASW_initialised = 1; + + return 0; +} + + +static void EventRaise(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize, struct IaswEvent *EventBuffer) +{ + unsigned int i; + + for (i=0; i < ERR_LOG_N3; i++) + { + if (EventBuffer[i].used == 0) + break; + } + + /* i is the index of the next free write slot */ + + if (i == ERR_LOG_N3) + { + /* no space in SavedEvents array */ + return; + } + + EventBuffer[i].SubType = SubType; + EventBuffer[i].evtId = evtId; + EventBuffer[i].evtData[0] = evtData[0]; + EventBuffer[i].evtData[1] = evtData[1]; + EventBuffer[i].DataSize = DataSize; + + cpu_relax(); /* Mantis 1977: this barrier prevents the compiler from reordering the last assignment */ + EventBuffer[i].used = 1; + + return; +} + + +/** + * @brief Report an Event by saving it in the IbswEvents array + * + * Instead of generating an event such as done with the @ref CrIaEvtRep function, this function only + * saves the event to be picked up later and flushed out with the @ref FlushEvents function. + * + */ + +void CrIaEvtRaise(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize) +{ + EventRaise (SubType, evtId, evtData, DataSize, IbswEvents); +} + +/** + * @brief Report an Event by the Science + * + * Instead of generating an event such as done with the @ref CrIaEvtRep function, this function only + * saves the event to be picked up later and flushed out with the @ref FlushEvents function. + * + */ + +void SdpEvtRaise(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize) +{ +#if (__sparc__) + if(leon3_cpuid() == 0) +#endif + { + /* on PC as well as on the first core we just want to emit the event */ + CrIaEvtRep (SubType, evtId, evtData, DataSize); + return; + } + + EventRaise (SubType, evtId, evtData, DataSize, SdpEvents); + + return; +} + + +/** + * @brief Flush the events saved in the IaswSavedEvents array out + * + * For every saved event, the @ref CrIaEvtRep function is called. + * + */ + +void FlushEvents (struct IaswEvent *EventBuffer) +{ + unsigned int i; + + /* flush out all IBSW events */ + for (i=0; i < ERR_LOG_N3; i++) + { + if (EventBuffer[i].used == 1) + { + CrIaEvtRep(EventBuffer[i].SubType, EventBuffer[i].evtId, &(EventBuffer[i].evtData[0]), EventBuffer[i].DataSize); + + cpu_relax(); /* Mantis 1977: this barrier prevents the compiler from reordering the last assignment */ + EventBuffer[i].used = 0; + } + } + + return; +} + + +/** + * @brief Generate Service 5 Event Reports + * + * @note An event filtering is done in the case an event with the same event ID is notified periodically. + * Then the filter reduces the generation of this event report packets. + * + */ + +void CrIaEvtRep(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize) +{ + FwSmDesc_t rep; + unsigned char evtRepEnbldStatus, counts; + unsigned short CibNFull, SibNFull, GibNFull, SibNWin, CibNWin, GibNWin; /* for Error Event SDB Config Failure */ + unsigned short CibSizeFull, SibSizeFull, GibSizeFull, CibSizeWin, SibSizeWin, GibSizeWin; /* for Error Event SDB Config Failure */ + unsigned short iaswEvtCtr; + + + CrIaCopy(IASW_EVT_CTR_ID, &iaswEvtCtr); + iaswEvtCtr++; + CrIaPaste(IASW_EVT_CTR_ID, &iaswEvtCtr); + + if(!IASW_initialised) + return; + + /* NOTE: errors are copied to the error log */ + if (SubType == CRIA_SERV5_EVT_ERR_MED_SEV) + CrIaErrRep (SubType, evtId, evtData, DataSize); + + if (SubType == CRIA_SERV5_EVT_ERR_HIGH_SEV) + CrIaErrRep (SubType, evtId, evtData, DataSize); + + /* first get the count limit from the EVTENABLEDLIST */ + CrIaCopyArrayItem(EVTENABLEDLIST_ID, &evtRepEnbldStatus, EventIndex(evtId)); + + /* we increment the counter for this event no matter if it is enabled */ + counts = CountEvent(evtId); + + /* counts will always be >0 here because it is increased before. + so if the Limit is set to 0 counts will already be > and no event is generated. */ + if (counts > evtRepEnbldStatus) + { +#if (__sparc__) + /* + We have to further mask the SPW interrrupts temporarily + for the link errors to prevent the interrupt storm. + These are re-enabled in the CrIa cycle. + */ + if (evtId == CRIA_SERV5_EVT_SPW_ERR_M) + { + CrIbDisableSemSpWLinkErrorIRQ(); +#if (__SPW_ROUTING__) + CrIbDisableMonSpWLinkErrorIRQ(); +#endif + } + + if (evtId == CRIA_SERV5_EVT_SPW_ERR_H) + { + CrIbDisableSemSpWLinkErrorIRQ(); +#if (__SPW_ROUTING__) + CrIbDisableMonSpWLinkErrorIRQ(); +#endif + } +#endif + return; + } + /* end of filter */ + + /* Create out component */ + /* Normal/Progress Report and Error Report - Low Severity */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV5, SubType, evtId, 0); /* arguments: type, subType, discriminant/evtId, length */ + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + CrFwOutCmpSetDest(rep, CR_FW_CLIENT_GRD_PUS); + + /* Set parameters of service (5,1) and (5,2) */ + CrIaServ5EvtSetEvtId(rep, evtId); + + switch (evtId) + { + + case CRIA_SERV5_EVT_INV_DEST: + CrIaServ5EvtInvDestParamSetInvDest (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SEQ_CNT_ERR: + CrIaServ5EvtSeqCntErrParamSetExpSeqCnt (rep, evtData[0]); + CrIaServ5EvtSeqCntErrParamSetActSeqCnt (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_INREP_CR_FAIL: + CrIaServ5EvtInrepCrFailParamSetRepSeqCnt (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_PCRL2_FULL: + CrIaServ5EvtPcrl2FullParamSetRepSeqCnt (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_FD_FAILED: + CrIaServ5EvtFdFailedParamSetFdCheckId (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_RP_STARTED: + CrIaServ5EvtRpStartedParamSetFdCheckId (rep, evtData[0]); + CrIaServ5EvtRpStartedParamSetRecovProcId (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SEM_TR: + CrIaServ5EvtSemTrParamSetSrcSemSt (rep, evtData[0]); + CrIaServ5EvtSemTrParamSetDestSemSt (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_IASW_TR: + CrIaServ5EvtIaswTrParamSetSrcIaswSt (rep, evtData[0]); + CrIaServ5EvtIaswTrParamSetDestIaswSt (rep,evtData[1]); + break; + + case CRIA_SERV5_EVT_SDSC_ILL: + CrIaServ5EvtSdscIllParamSetSciSeqCnt (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_SDSC_OOS: + CrIaServ5EvtSdscOosParamSetExpSciSeqCnt (rep, evtData[0]); + CrIaServ5EvtSdscOosParamSetActSciSeqCnt (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_CLCT_SIZE: + CrIaServ5EvtClctSizeParamSetGibSize(rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_SIB_SIZE: + CrIaServ5EvtSibSizeParamSetSibSize (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_FBF_LOAD_RISK: + CrIaServ5EvtFbfLoadRiskParamSetFbfId (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_FBF_SAVE_DENIED: + CrIaServ5EvtFbfSaveDeniedParamSetFbfId (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_FBF_SAVE_ABRT: + CrIaServ5EvtFbfSaveAbrtParamSetFbfId (rep, evtData[0]); + CrIaServ5EvtFbfSaveAbrtParamSetFbfNBlocks (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SDB_CNF_FAIL: + CrIaServ5EvtSdbCnfFailParamSetProcId (rep, evtData[0]); /* is filled via evtData by SDB Config */ + /* Full */ + CrIaCopy(CIBNFULL_ID, &CibNFull); + CrIaServ5EvtSdbCnfFailParamSetCibNFull (rep, (unsigned char)CibNFull); + CrIaCopy(CIBSIZEFULL_ID, &CibSizeFull); + CrIaServ5EvtSdbCnfFailParamSetCibSizeFull (rep, CibSizeFull); + CrIaCopy(SIBNFULL_ID, &SibNFull); + CrIaServ5EvtSdbCnfFailParamSetSibNFull (rep, (unsigned char)SibNFull); + CrIaCopy(SIBSIZEFULL_ID, &SibSizeFull); + CrIaServ5EvtSdbCnfFailParamSetSibSizeFull (rep, SibSizeFull); + CrIaCopy(GIBNFULL_ID, &GibNFull); + CrIaServ5EvtSdbCnfFailParamSetGibNFull (rep, (unsigned char)GibNFull); + CrIaCopy(GIBSIZEFULL_ID, &GibSizeFull); + CrIaServ5EvtSdbCnfFailParamSetGibSizeFull (rep, GibSizeFull); + /* Win */ + CrIaCopy(SIBNWIN_ID, &SibNWin); + CrIaServ5EvtSdbCnfFailParamSetSibNWin (rep, (unsigned char)SibNWin); + CrIaCopy(SIBSIZEWIN_ID, &SibSizeWin); + CrIaServ5EvtSdbCnfFailParamSetSibSizeWin (rep, SibSizeWin); + CrIaCopy(CIBNWIN_ID, &CibNWin); + CrIaServ5EvtSdbCnfFailParamSetCibNWin (rep, (unsigned char)CibNWin); + CrIaCopy(CIBSIZEWIN_ID, &CibSizeWin); + CrIaServ5EvtSdbCnfFailParamSetCibSizeWin (rep, CibSizeWin); + CrIaCopy(GIBNWIN_ID, &GibNWin); + CrIaServ5EvtSdbCnfFailParamSetGibNWin (rep, (unsigned char)GibNWin); + CrIaCopy(GIBSIZEWIN_ID, &GibSizeWin); + CrIaServ5EvtSdbCnfFailParamSetGibSizeWin (rep, GibSizeWin); + break; + + case CRIA_SERV5_EVT_CMPR_SIZE: + CrIaServ5EvtCmprSizeParamSetImgBufferSize (rep, ((unsigned int)evtData[0] << 16) | ((unsigned int) evtData[1])); + break; + + case CRIA_SERV5_EVT_SEMOP_TR: + CrIaServ5EvtSemopTrParamSetSrcSemOpSt (rep, evtData[0]); + CrIaServ5EvtSemopTrParamSetDestSemOpSt (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SC_PR_STRT: + CrIaServ5EvtScPrStrtParamSetProcId (rep, evtData[0]); + break; + + case CRIA_SERV5_EVT_SC_PR_END: + CrIaServ5EvtScPrEndParamSetProcId (rep, evtData[0]); + CrIaServ5EvtScPrEndParamSetProcTermCode (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_INSTRM_PQF: /* was: EVT_INSTREAM_PQ_FULL */ + CrIaServ5EvtInstrmPqfParamSetInStreamId (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_OCMP_INVD: + CrIaServ5EvtOcmpInvdParamSetOutCompId (rep, evtData[0]); + CrIaServ5EvtOcmpInvdParamSetInvDest (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_OCMP_ILLGR: /* was: EVT_OUTCMP_ILL_GROUP */ + CrIaServ5EvtOcmpIllgrParamSetOutStreamId (rep, evtData[0]); + CrIaServ5EvtOcmpIllgrParamSetGroupId (rep, evtData[1]&0xff); + break; + + case CRIA_SERV5_EVT_IN_ILLGR: /* was: EVT_INCMDREP_ILL_GROUP */ + CrIaServ5EvtInIllgrParamSetInStreamId(rep, evtData[0]); + CrIaServ5EvtInIllgrParamSetGroupId(rep, evtData[1] & 0xff); + break; + + case CRIA_SERV5_EVT_INV_CENT: + /* no parameter */ + break; + + case CRIA_SERV5_EVT_OOL_PARAM: + CrIaServ5EvtOolParamParamSetParamId(rep, (evtData[0] << 16) | evtData[1]); + break; + + case CRIA_SERV5_EVT_INIT_SUCC: + /* no parameter */ + break; + + case CRIA_SERV5_EVT_INIT_FAIL: + CrIaServ5EvtInitFailParamSetNoOfErrors (rep, evtData[0]); + CrIaServ5EvtInitFailParamSetIbswErrNo (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_THRD_OR: + CrIaServ5EvtThrdOrParamSetThrdId (rep, evtData[0]); + CrIaServ5EvtThrdOrParamSetThrdOrSize (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_NOTIF_ERR: + CrIaServ5EvtNotifErrParamSetContdId (rep, evtData[0]); + CrIaServ5EvtNotifErrParamSetNotifCnt (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_1553_ERR_L: + CrIaServ5Evt1553ErrLParamSetIbswErrNo (rep, evtData[1]); /* errno is in evtData[1] */ + break; + + case CRIA_SERV5_EVT_1553_ERR_M: + CrIaServ5Evt1553ErrMParamSetIbswErrNo (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_1553_ERR_H: + CrIaServ5Evt1553ErrHParamSetIbswErrNo (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SPW_ERR_L: + fdSemCommErrCnt++; /* counter to signal that an communication error occurs; will be reseted every IASW cycle */ + CrIaServ5EvtSpwErrLParamSetIbswErrNo (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SPW_ERR_M: + fdSemCommErrCnt++; /* counter to signal that an communication error occurs; will be reseted every IASW cycle */ + CrIaServ5EvtSpwErrMParamSetIbswErrNo (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SPW_ERR_H: + fdSemCommErrCnt++; /* counter to signal that an communication error occurs; will be reseted every IASW cycle */ + CrIaServ5EvtSpwErrHParamSetIbswErrNo (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_FL_EL_ERR: + CrIaServ5EvtFlElErrParamSetIbswErrNo (rep, errno); /* NOTE: we only see the last errno of this cycle */ + CrIaServ5EvtFlElErrParamSetFlashAdd (rep, (evtData[0] << 16) | evtData[1]); + break; + + case CRIA_SERV5_EVT_FL_FBF_ERR: + CrIaServ5EvtFlFbfErrParamSetIbswErrNo (rep, errno); /* NOTE: we only see the last errno of this cycle */ + CrIaServ5EvtFlFbfErrParamSetFlashAdd (rep, 0); /* NOTE: we cannot get the address here, this will stay 0 */ + CrIaServ5EvtFlFbfErrParamSetFbfId (rep, evtData[1]); /* right short word because of big endianess */ + break; + + case CRIA_SERV5_EVT_FL_FBF_BB: + CrIaServ5EvtFlFbfBbParamSetChipId (rep, evtData[0]); + CrIaServ5EvtFlFbfBbParamSetBlck (rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SBIT_ERR: + CrIaServ5EvtSbitErrParamSetRamAdd(rep, (evtData[0] << 16) | evtData[1]); + break; + + case CRIA_SERV5_EVT_DBIT_ERR: + CrIaServ5EvtDbitErrParamSetRamAdd(rep, (evtData[0] << 16) | evtData[1]); + break; + + case CRIA_SERV5_EVT_SYNC_LOSS: + /* no parameter */ + break; + + case CRIA_SERV5_EVT_SDP_NOMEM: + CrIaServ5EvtSdpNomemParamSetStepNmb(rep, evtData[0]); + CrIaServ5EvtSdpNomemParamSetDebugVal(rep, evtData[1]); + break; + + case CRIA_SERV5_EVT_SEM_ILL_ST: + CrIaSetUShortValue(rep, evtData[0], 2); /* generic setter used */ + CrIaSetUShortValue(rep, evtData[1], 4); + break; + + case CRIA_SERV5_EVT_ACQ_FAIL: + /* no parameter */ + break; + + case CRIA_SERV5_EVT_PROCBUF_INSUF: + CrIaServ5EvtProcbufInsufParamSetProductID(rep, evtData[0]); + CrIaServ5EvtProcbufInsufParamSetReqSize(rep, (((unsigned int)evtData[1])<<16) | ((unsigned int)evtData[2])); + CrIaServ5EvtProcbufInsufParamSetAvailSize(rep, (((unsigned int)evtData[3])<<16) | ((unsigned int)evtData[4])); + break; + + case CRIA_SERV5_EVT_IMG_INSUF: + CrIaServ5EvtImgInsufParamSetProductID(rep, evtData[0]); + CrIaServ5EvtImgInsufParamSetStepID(rep, evtData[1]); + CrIaServ5EvtImgInsufParamSetReqSize(rep, (((unsigned int)evtData[2])<<16) | ((unsigned int)evtData[3])); + CrIaServ5EvtImgInsufParamSetAvailSize(rep, (((unsigned int)evtData[4])<<16) | ((unsigned int)evtData[5])); + break; + + case CRIA_SERV5_EVT_XIB_FULL : + CrIaServ5EvtXibFullParamSetBufID(rep, evtData[0]); /* was: CrIaSetUShortValue(rep, evtData[0], 2); */ + break; + + default : + DEBUGP("!!!! UNKNOWN EVENT: %d\n", evtId); + break; + } + + CrFwOutLoaderLoad(rep); + + return; +} + + +/* NOTE: do not call directly, but call CrIaEvtRep instead. It will call CrIaErrRep for MED and HIGH */ +void CrIaErrRep(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize) +{ +#if (__sparc__) + unsigned int i; + unsigned char loginfo[ERR_LOG_N2]; + + if(!IASW_initialised) + return; + + DEBUGP("ERR \n"); + + /* make local copy */ + memcpy(loginfo, evtData, DataSize); + + /* pad with zeroes */ + for (i=DataSize; i < ERR_LOG_N2; i++) + loginfo[i] = 0; + + /* Make entry in the RAM error log if the number of errors + reported in this cycle has not yet reached the limit. */ + if (LoggedEntries < ERR_LOG_N3) + { + CrIbLogError (evtId, loginfo); + LoggedEntries++; + } +#endif /* __sparc__ */ + + (void) SubType; + (void) evtId; + (void) evtData; + (void) DataSize; + + return; +} + + +/** + * @brief Execution of the Cyclical Activities + * + * @param none + */ + +void CrIaExecCycActivities() +{ + unsigned int pctr; + unsigned int MaxSemPcktCyc; +#if (__sparc__) + unsigned int edacErrors; + unsigned short cpu2status, scrublength; + unsigned char edacSingleRepaired; +#endif /* __sparc__ */ + unsigned char lstpckt; + unsigned short routing = 0; + + +#ifdef PC_TARGET + PcSemCycleCount = 0; + PcSemCollPckt = 0; + PcMilUsed = 0; +#endif /* PC_TARGET */ + + CrIaCopy(MILFRAMEDELAY_ID, &milFrameDelay); + + CrIaCopy(SEMROUTE_ID, &routing); + +#if (__sparc__) + if (routing_status == 0) + { + if (routing == 1) + { + CrIbEnableSpWRoutingNOIRQ(); + routing_status = 1; + } + } + + if (routing_status == 1) + { + if (routing == 0) + { + CrIbDisableSpWRouting(); + routing_status = 0; + } + } + +#endif /* __sparc__ */ + + + if (routing == 0) + { + /* Load packets from the instreams */ + + /* 1.1 Execute CrFwInStreamPcktAvail on InStreamSem */ + /* Load packets from SEM */ + pollConnectionSem(); + + /* 1.2 Execute the InLoader on InStreamSem MAX_SEM_PCKT_CYC times */ + /* packets from SEM */ + CrIaCopy(MAX_SEM_PCKT_CYC_ID, &MaxSemPcktCyc); + CrFwInLoaderSetInStream(inStreamSem); + + for (pctr = 0; pctr < MaxSemPcktCyc; pctr++) + { + FwSmExecute(CrFwInLoaderMake()); + } + } + else + { +#if (__sparc__) + CrIbSpWRoute(); +#endif + } + + +#if (__sparc__) + /* update the ADC values in the data pool */ + CrIbUpdateDataPoolVariablesWithFpgaValues(); + + /* + DEBUGP("H1: %d\n", fpga_heater_status(HEATER_1)); + DEBUGP("H2: %d\n", fpga_heater_status(HEATER_2)); + DEBUGP("H3: %d\n", fpga_heater_status(HEATER_3)); + DEBUGP("H4: %d\n", fpga_heater_status(HEATER_4)); + */ + + /* update the IBSW values in the data pool */ + /* CrIbUpdateDataPoolVariablesWithValuesFromIbswSysctlTree(8); */ +#endif /* __sparc__ */ + + /* Execute managers */ + /* 2 Execute the inManagerSem */ + FwSmExecute(CrFwInManagerMake(0)); + + /* 3 Execute SEM Unit State Machine */ + FwSmMakeTrans(smDescSem, Execute); + + /* 4 Execute, in sequence, each FdCheck and its associated Recovery Procedure + NB: The Recovery Procedures consist of one-shot actions. They are therefore + not implemented as self-standing procedures. They are instead implemented + in function CrIaFdCheckFunc::executeRecoveryProc. This function is executed + by an FdCheck when a failure is declared. Hence, the code below (which only + executes the FdCheck) is equivalent to the specification (which requires + the execution of the FdCheck and of their recovery procedures). + */ + FwSmMakeTrans(smDescFdTelescopeTempMonitorCheck, Execute); + FwSmMakeTrans(smDescFdIncorrectSDSCntrCheck, Execute); + FwSmMakeTrans(smDescFdSemCommErrCheck, Execute); + FwSmMakeTrans(smDescFdSemModeTimeOutCheck, Execute); + FwSmMakeTrans(smDescFdSemSafeModeCheck, Execute); + FwSmMakeTrans(smDescFdSemAliveCheck, Execute); + FwSmMakeTrans(smDescFdSemAnomalyEventCheck, Execute); + FwSmMakeTrans(smDescFdSemLimitCheck, Execute); + FwSmMakeTrans(smDescFdDpuHousekeepingCheck, Execute); + FwSmMakeTrans(smDescFdCentroidConsistencyCheck, Execute); + FwSmMakeTrans(smDescFdResourceCheck, Execute); + FwSmMakeTrans(smDescFdSemModeConsistencyCheck, Execute); + + /* reset counter, which signals that an communication error in this IASW cycle occured */ + fdSemCommErrCnt = 0; + + /* 5 Execute the Validity Procedure */ + FwPrExecute(prDescCentVal); + + /* 6 Execute the IASW State Machine */ + FwSmMakeTrans(smDescIasw, Execute); + + /* 7.1 Execute all Science Procedures */ + /* NOTE: prDescNomSci is executed by IASW Science Do Action */ + /* NOTE: prDescAcqFullDrop is executed by IASW Science Do Action */ + /* NOTE: prDescCalFullSnap is executed by IASW Science Do Action */ + /* NOTE: prDescSciStack is executed by IASW Science Do Action */ + /* NOTE: prDescSciDataUpd is executed in S21 DatCcdWindowUpdate action */ + FwPrExecute(prDescSaveImages); +#ifdef PC_TARGET + FwPrExecute(prDescAcq1AlgoExec); + FwPrExecute(prDescCmprAlgoExec); +#endif /* PC_TARGET */ + + /* 7.2 Execute FBF Procedures */ + FwPrExecute(prDescFbfLoad); + FwPrExecute(prDescFbfSave); + FwPrExecute(prDescTransferFbfToGround); + + /* 8 Execute all Algorithm State Machines */ + FwSmExecute(smDescAlgoCent0); + FwSmExecute(smDescAlgoCent1); + FwSmExecute(smDescAlgoTtc1); + FwSmExecute(smDescAlgoTtc2); +#ifdef PC_TARGET + FwSmExecute(smDescAlgoAcq1); + FwSmExecute(smDescAlgoCmpr); +#endif /* PC_TARGET */ + FwSmExecute(smDescAlgoSaaEval); + FwSmExecute(smDescAlgoSdsEval); + + /* 9 Execute the Update operation on the data pool */ + /* Note: this does not update asynchronous items */ + CrFwUpdateDataPool(CrFwInManagerMake(0), /* inManagerSem */ + CrFwInManagerMake(1), /* inManagerGrdObc */ + CrFwOutManagerMake(0), /* outManager1 */ + CrFwOutManagerMake(1), /* outManager2 */ + CrFwOutManagerMake(2), /* outManager3 */ + inStreamSem, + inStreamObc, + inStreamGrd, + outStreamSem, + outStreamObc, + outStreamGrd); + + /* 10.1 Execute CrFwInStreamPcktAvail on InStreamObc */ + /* 10.2 Execute CrFwInStreamPcktAvail on InStreamGrd */ + /* Load packets from OBC and GRND */ + pollConnectionMil(); + + /* 10.3 Execute the InLoader on InStreamObc */ + /* Load packets from the instreams */ + CrFwInLoaderSetInStream(inStreamObc); + FwSmExecute(CrFwInLoaderMake()); + /* 10.4 Execute the InLoader on InStreamGrd */ + /* Load packets from the instreams */ + CrFwInLoaderSetInStream(inStreamGrd); + FwSmExecute(CrFwInLoaderMake()); + + /* 11 Execute the InManagerGrdObc */ + /* Execute managers */ + FwSmExecute(CrFwInManagerMake(1)); + + /* Mantis 1823 */ + FlushEvents(IbswEvents); + + /* Mantis 1977 */ + FlushEvents(SdpEvents); + + /* 12 Execute the OutManager1 */ + /* Execute managers */ + FwSmExecute(CrFwOutManagerMake(0)); + + /* 13 Execute SDU2 State Machine */ + FwSmMakeTrans(smDescSdu2, Execute); + + /* 14 Execute the OutManager2 */ + /* Execute managers */ + FwSmExecute(CrFwOutManagerMake(1)); + + /* 15 Execute SDU2 State Machine */ + FwSmMakeTrans(smDescSdu2, Execute); + + /* 16 Execute the OutManager2 */ + /* Execute managers */ + FwSmExecute(CrFwOutManagerMake(1)); + + /* 17 Execute SDU4 State Machines */ + FwSmMakeTrans(smDescSdu4, Execute); + + /* 18 Execute the OutManager3 */ + /* Execute managers */ + FwSmExecute(CrFwOutManagerMake(2)); /* OutManager3 */ + + /* 19 Execute SDU4 State Machines */ + FwSmMakeTrans(smDescSdu4, Execute); + + /* 20 Execute the OutManager3 */ + /* Execute managers */ + FwSmExecute(CrFwOutManagerMake(2)); /* OutManager3 */ + + /* Clear all SEM Event flags Mantis 1179, has to be after the out managers */ + CrIaClearSemEventFlags(); + + /* reset the V09+ event filter each cycle */ + ResetEventCounts(); + +#if (__sparc__) + /* re-enable SpW interrupts just in case they were deactivated by the filter */ + CrIbEnableSemSpWLinkErrorIRQ(); +#if (__SPW_ROUTING__) + CrIbEnableMonSpWLinkErrorIRQ(); +#endif +#endif + +#if (__sparc__) + /* Memory scrubbing as part of the cycle (no thread) */ + + CrIaCopy (SRAM1SCRLENGTH_ID, &scrublength); + if (scrublength > 0) + CrIbScrubMemory (SRAM1_ID, scrublength); + + CrIaCopy (SRAM2SCRLENGTH_ID, &scrublength); + if (scrublength > 0) + CrIbScrubMemory (SRAM2_ID, scrublength); + + /* Check if the second cpu is running in this cycle, then correct. + If it is active, then we retry in the next cycle. */ + CrIaCopy (CPU2PROCSTATUS_ID, &cpu2status); + + if (cpu2status == SDP_STATUS_IDLE) + { + /* set status to ERROR and correct EDAC errors */ + cpu2status = SDP_STATUS_ERROR; + CrIaPaste (CPU2PROCSTATUS_ID, &cpu2status); + + edacErrors = CrIbMemRepair (); + + CrIaCopy(EDACSINGLEREPAIRED_ID, &edacSingleRepaired); + edacSingleRepaired += (unsigned char) edacErrors; + CrIaPaste(EDACSINGLEREPAIRED_ID, &edacSingleRepaired); + + /* set back to IDLE */ + cpu2status = SDP_STATUS_IDLE; + CrIaPaste (CPU2PROCSTATUS_ID, &cpu2status); + } +#endif /* __sparc__ */ + + /* Start and Execute the TTC1 procedure -> already done in Algorithm State Machine */ + + /* 21 Execute the Watchdog Reset Procedure */ +#if (__sparc__) + CrIbResetWd(); +#endif /* __sparc__ */ + + /* 22 reset the LastSemPcktFlag and the S196Flag */ + lstpckt = 0; + CrIaPaste(LASTSEMPCKT_ID, &lstpckt); + S196Flag = 0; + + /* issue ConnectionAvailable signals */ + CrIaOutStreamConnectionAvail(outStreamSem); + CrIaOutStreamConnectionAvail(outStreamObc); + CrIaOutStreamConnectionAvail(outStreamGrd); + + CrIbUpdateDataPoolVariablesWithValuesFromIbswSysctlTree(8.0); + + /* periodic creation of Service 9 time (+ this triggers a tick) */ + + +#ifdef PC_TARGET + PcCycCount ++; +#endif /* PC_TARGET */ + + /* Execute HbSem Mon Pr */ + if (FwSmGetExecCnt(smDescIasw) % HBSEM_MON_PER == 0) + { + FwPrExecute(prDescHbSemMon); + } + + /* reset received SEM Anomaly Event ID */ + SemAnoEvtId = 0; + + /* reset limit for error log entries per cycle */ + LoggedEntries = 0; + + return; +} + + +void CrIaOutStreamConnectionAvail(FwSmDesc_t smDesc) { + CrFwOutStreamConnectionAvail(smDesc); +} + + +CrFwTimeStamp_t CrFwGetCurrentTime() +{ + return CrIbGetCurrentTime(); +} + + +#ifdef PC_TARGET +/** + * Provide the current time. + * + * This function implements the CORDET interface from CrFwTime.h. Time is + * provided as a 32-bit integer of which the MSB 8 bits are set to zero and the + * remaining 24 bits comply with the CUC time format (the 0 + */ +CrFwTimeStamp_t CrIbGetCurrentTime() +{ + struct timespec now; + time_t coarse; + unsigned int fine; + CrFwTimeStamp_t ts; /* unsigned char struct.t[6] */ + + clock_gettime(CLOCK_REALTIME, &now); + coarse = now.tv_sec; + fine = (unsigned int)(32.768 * (float)now.tv_nsec / (float)1000000); +/* + DEBUGP("Coarsetime: %ld\n", coarse); + DEBUGP("Finetime: %d\n", fine); +*/ + + ts.t[3] = coarse & 0xff; + ts.t[2] = (coarse >> 8) & 0xff; + ts.t[1] = (coarse >> 16) & 0xff; + ts.t[0] = (coarse >> 24) & 0xff; + ts.t[4] = (fine >> 7) & 0x7f; + ts.t[5] = fine & 0xfe; + + return ts; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +void CrIbUpdateDataPoolVariablesWithValuesFromIbswSysctlTree(unsigned int hz) +{ + static unsigned int firstcoarse; + unsigned int coarse; + CrFwTimeStamp_t ts; + + (void) hz; + + ts = CrIbGetCurrentTime(); + + coarse = ((unsigned int)ts.t[0] << 24) | ((unsigned int)ts.t[1] << 16) | ((unsigned int)ts.t[2] << 8) | (unsigned int)ts.t[3]; + + if (firstcoarse == 0) + firstcoarse = coarse; + + coarse -= firstcoarse; + + CrIaPaste(UPTIME_ID, &coarse); + + return; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +/** + * Provide the time at next sync pulse. Dummy implementation for PC + */ +CrFwTimeStamp_t CrIbGetNextTime() +{ + return CrIbGetCurrentTime(); +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +/** + * Provide the current cycle on PC + */ +unsigned int CrIbGetNotifyCnt() +{ + return (PcCycCount % 8) + 1; +} +#endif /* PC_TARGET */ + + +/** + * Load Predefined Housekeeping + * Service (3, 25) OutRep + */ +void CrIaLoadPredefinedHousekeeping() +{ + FwSmDesc_t rep; + CrFwGroup_t group = 1; /* PCAT = 2 */ + unsigned char sid; + unsigned int hkSize; + + DEBUGP("### CrIaInit ### Within IASW predefined Housekeeping packet generation.\n"); + + /* Create out components predefined housekeepings */ + for(sid = 1; sid <= 6; sid++) + { + hkSize = getHkDataSize (sid); + + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV3, CRIA_SERV3_HK_DR, sid, hkSize); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + DEBUGP("ERROR: CrIaLoadPredefinedHousekeeping cannot generate a packet!\n"); + return; + } + + CrFwOutCmpSetGroup(rep, group); + CrFwOutLoaderLoad(rep); + } + + return; +} + +/** + * Load Heartbeat Report + * Service (195, 1) OutRep + */ +void CrIaLoadHeartbeatReport() +{ + FwSmDesc_t rep; + CrFwGroup_t group = 1; /* group 1 PCAT = 2 */ + + /* Create out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV195, CRIA_SERV195_HB_REP, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + DEBUGP("ERROR: CrIaLoadHeartbeatReport cannot generate a packet!\n"); + return; + } + + /* Set out component parameters */ + CrFwOutCmpSetGroup(rep, group); + + CrFwOutCmpSetDest(rep, CR_FW_CLIENT_OBC); + + CrFwOutLoaderLoad(rep); + + return; +} + +/** + * Load Aocs Report + * Service (196, 1) OutRep + */ +void CrIaLoadAocsReport() /* used in CrIaIaswFunc */ +{ + FwSmDesc_t rep; + CrFwGroup_t group = 2; /* group 2 PCAT = 3 */ + + /* Create an out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV196, CRIA_SERV196_AOCS_REP, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + CrFwOutCmpSetGroup(rep, group); + + CrFwOutCmpSetDest(rep, CR_FW_CLIENT_OBC); /* obc: CR_FW_CLIENT_OBC, grnd: CR_FW_CLIENT_GRD_PUS */ + + CrFwOutLoaderLoad(rep); + + return; +} + +/** + * Load Sem Service 9 time command + * Service (9, 1) OutCmd + */ +void CrIaLoadSemTimeCmd() /* used in CrIaSemFunc */ +{ + /* S9 command for the time distribution */ + CrFwBool_t SemTimeCmdAcceptFlag = 0; + CrFwBool_t SemTimeCmdStartFlag = 0; + CrFwBool_t SemTimeCmdProgressFlag = 0; + CrFwBool_t SemTimeCmdTermFlag = 0; + + /* prepare the Load TC(9,129) to SEM */ + smDescSemTimeCmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV9, CRSEM_SERV9_CMD_TIME_UPDATE, 0, 0); + + if (smDescSemTimeCmd != NULL) + { + CrFwOutCmpSetAckLevel(smDescSemTimeCmd, SemTimeCmdAcceptFlag, SemTimeCmdStartFlag, SemTimeCmdProgressFlag, SemTimeCmdTermFlag); + CrFwOutCmpSetDest(smDescSemTimeCmd, CR_FW_CLIENT_SEM); + /* NOTE: the time is set in the update action of serv 9 outCmd */ + } + + CrFwOutLoaderLoad(smDescSemTimeCmd); + + return; +} + + +void CrIbRebootDpu() +{ + /* nothing to do */ +} + + +void CrIbResetDpu() +{ + /* nothing to do */ +} + + +#ifdef PC_TARGET +CrFwBool_t CrIbIsSemPcktAvail(CrFwDestSrc_t src) +{ + unsigned int MaxSemPcktCyc; + + /* DEBUGP("\nCrIbIsSemPcktAvail()\n"); */ + CRIA_UNUSED(src); + + CrIaCopy(MAX_SEM_PCKT_CYC_ID, &MaxSemPcktCyc); + if (PcSemCycleCount < MaxSemPcktCyc) + { + PcSemCycleCount++; + return socketCheckPackageAvailable(fdSem); + } + + DEBUGP("SEM Cycle count exceeded!\n"); + return 0; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +CrFwPckt_t CrIbSemPcktCollect(CrFwDestSrc_t src) +{ + DEBUGP("\nCrIbSemPcktCollect() \n"); + CRIA_UNUSED(src); + PcSemCollPckt++; + return socketReceivePackage(fdSem); +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +CrFwBool_t CrIbSemPcktHandover(CrFwPckt_t pckt) +{ + DEBUGP("\nCrIbSemPcktHandover()\n"); + InsertCrc(pckt); + return socketSendPackageOnExistingConnection(fdSem, pckt); +} +#endif /* PC_TARGET */ + + +CrFwBool_t CrIbIsObcPcktAvail(CrFwDestSrc_t src) +{ + (void) src; + return CrIbIsMilBusPcktAvail(CR_FW_CLIENT_OBC); +} + +CrFwBool_t CrIbIsGrdPcktAvail(CrFwDestSrc_t src) +{ + (void) src; + return CrIbIsMilBusPcktAvail(CR_FW_CLIENT_GRD); +} + +CrFwPckt_t CrIbObcPcktCollect(CrFwDestSrc_t src) +{ + (void) src; + return CrIbMilBusPcktCollect(CR_FW_CLIENT_OBC); +} + +CrFwPckt_t CrIbGrdPcktCollect(CrFwDestSrc_t src) +{ + (void) src; + return CrIbMilBusPcktCollect(CR_FW_CLIENT_GRD); +} + + +#ifdef PC_TARGET +CrFwBool_t CrIbIsMilBusPcktAvail(CrFwDestSrc_t src) +{ + CRIA_UNUSED(src); + return socketCheckPackageAvailable(socketObc); /* on PC, we only have OBC */ +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +CrFwPckt_t CrIbMilBusPcktCollect(CrFwDestSrc_t src) +{ + CRIA_UNUSED(src); + return socketReceivePackage(socketObc); /* on PC, we only have OBC */ +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +CrFwBool_t CrIbMilBusPcktHandover(CrFwPckt_t pckt) +{ + CrFwPcktLength_t len; + + DEBUGP("\nCrIbMilBusPcktHandover()\n"); + + /* usleep(60000); */ /* 62.5 ms ~ 16 Hz */ + /* instead of the sleep we imitate the milbus via fill state */ + + len = CrFwPcktGetLength(pckt); + + if ((PcMilUsed + len) > 2048) + return 0; + + PcMilUsed += len; /* the slot is reset at the end of a cycle */ + + return socketSendPackageOnExistingConnection(socketObc, pckt);; +} +#endif /* PC_TARGET */ + + +CrFwBool_t CrIbMilBusPcktHandoverPrepare(CrFwPckt_t pckt) +{ +#if (__sparc__) + InsertCrc(pckt); +#endif /* __sparc__ */ + return CrIbMilBusPcktHandover(pckt); +} + +CrFwBool_t CrIbSemPcktHandoverPrepare(CrFwPckt_t pckt) +{ +#if (__sparc__) + InsertCrc(pckt); +#endif /* __sparc__ */ + return CrIbSemPcktHandover(pckt); +} + + +#ifdef PC_TARGET +static void *accept_connections(void *ptr) +{ + int fd=0; + struct th_arg arg, *p_arg; + struct sockaddr_storage client_addr; + socklen_t client_addr_len; + + p_arg = (struct th_arg *) ptr; + + arg.sock_fd = p_arg->sock_fd; + arg.conn_fd = p_arg->conn_fd; + + /** + * for simplicity, close an existing connection + * as soon as anther client connects. + * if we really need to have multiple clients at once, we'll have to manage + * file descriptors in one fd_set per socket + */ + + client_addr_len = sizeof(client_addr); + while(1) + { + fd = accept((*arg.sock_fd), (struct sockaddr *) &client_addr, &client_addr_len); + if (fd < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + if((*arg.conn_fd)) + { + close((*arg.conn_fd)); + } + + (*arg.conn_fd) = fd; + } +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +static int setupConnection(const char* url) +{ + char *str; + int sockfd, endpoint; + int optval=1; + struct sockaddr_in server; + + struct sigaction sigint; + + str = malloc(strlen(url)+1); + if (str == NULL) + { + perror("ERROR setting up connection\n"); + exit(EXIT_FAILURE); + } + strcpy(str,url); + + /* don't getaddrinfo(), explicitly bind to given address */ + server.sin_addr.s_addr = inet_addr(strtok(str, ":")); + server.sin_family = AF_INET; + server.sin_port = htons(atoi(strtok(NULL, ":"))); + + free(str); + + sockfd = socket(AF_INET , SOCK_STREAM , 0); + + if (sockfd < 0) + { + DEBUGP("socket creation failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + + endpoint = bind(sockfd, (struct sockaddr *) &server , sizeof(server)); + + if (endpoint < 0) + { + close(sockfd); + DEBUGP("could not bind endpoint %s: %s\n", url, strerror(errno)); + exit(EXIT_FAILURE); + } + + sigint.sa_handler = sigint_handler; + sigemptyset(&sigint.sa_mask); + sigint.sa_flags = 0; + if (sigaction(SIGINT, &sigint, NULL) == -1) + { + perror("sigaction"); + close(sockfd); + exit(EXIT_FAILURE); + } + + if (listen(sockfd, 0) < 0) + { + close(sockfd); + perror("listen"); + exit(EXIT_FAILURE); + } + + return sockfd; +} +#endif /* PC_TARGET */ + +#ifdef PC_TARGET +static void shutdownSocket(int socket) +{ + int ret = 0; + + ret = shutdown(socket, 0); + if (ret == -1) + { + DEBUGP("socket shutdown failed: %s\n", strerror(errno)); + } + + return; +} +#endif /* PC_TARGET */ + + +void pollConnectionSem() +{ + FwSmDesc_t inStream; + + if (CrIbIsSemPcktAvail(0) == 0) + { + return; + } + + inStream = CrFwInStreamGet(CR_FW_CLIENT_SEM); + CrFwInStreamPcktAvail(inStream); + + return; +} + + +static void pollConnectionMil() +{ + FwSmDesc_t localInStreamObc, localInStreamGrd; + + if (CrIbIsObcPcktAvail(CR_FW_CLIENT_OBC) != 0) + { + /* DEBUGP("get pckt from OBC\n"); */ + localInStreamObc = CrFwInStreamGet(CR_FW_CLIENT_OBC); + CrFwInStreamPcktAvail(localInStreamObc); + } + + if (CrIbIsGrdPcktAvail(CR_FW_CLIENT_GRD) != 0) + { + /* DEBUGP("get pckt from GRD\n"); */ + localInStreamGrd = CrFwInStreamGet(CR_FW_CLIENT_GRD); + CrFwInStreamPcktAvail(localInStreamGrd); + } + + return; +} + +void InsertCrc(CrFwPckt_t pckt) +{ + CrIaPcktCrc_t Chk; + CrFwPcktLength_t len, i; + + /* Calculate CRC */ + Chk = 0xFFFF; + if (!LTblInit) + { + InitLtbl(LTbl); + LTblInit = 1; + } + len = CrFwPcktGetLength(pckt) - sizeof(CrIaPcktCrc_t); + for (i=0; i<len; ++i) + { + Chk = Crc(pckt[i], Chk, LTbl); + } + Chk = cpu_to_le16(Chk); + CrIaPcktSetCrc(pckt, Chk); + + return; +} + + +#ifdef PC_TARGET +/* just a dummy. implementation only in OBC simulation. */ +__attribute__((unused)) +static void reRouteCnC(CrFwPckt_t pckt) +{ + CRIA_UNUSED(pckt); +} +#endif + + +#ifdef PC_TARGET +/* + * Function: socketCheckPackageAvailable() + * ----------------------------------- + * Check if package is available on given socket. + * + * fdType: specifies the socket endpoint: e.g. fdGrnd or fdIasw or fdObc + * + * returns: 0 in case of error, 1 in case of success. + */ +static CrFwBool_t socketCheckPackageAvailable(int fdType) +{ + __attribute__((unused)) int i; + ssize_t recv_bytes; + char recv_buffer_small[6]; + unsigned short int packet_length; + char recv_buffer[CR_IA_MAX_SIZE_PCKT_LARGE]; + struct timeval timeout; + + fd_set readset; + + if(!fdType) + return 0; + + timeout.tv_sec=0; + timeout.tv_usec=500; + + FD_ZERO(&readset); + FD_SET(fdType, &readset); + + if(select(FD_SETSIZE, &readset, NULL, NULL, &timeout) <= 0) + { + return 0; /* socket's not ready */ + } + + /* check if there's at least a valid PUS header in the recv stream + * we obviously assume that the top of the recv queue always + * starts with a valid PUS header + * if this must be safe, we need circular recv buffers and a + * full packet inspection + */ + recv_bytes = recv(fdType, recv_buffer_small, 6, MSG_PEEK); + if (recv_bytes <= 0) + { + perror("socketCheckPackageAvailable()"); + close(fdType); + return 0; + } + /*for (i=0; i<recv_bytes; i++) { + DEBUGP("%x-",recv_buffer[i]); + } + DEBUGP("\n");*/ + + if (recv_bytes == 6) + { + DEBUGP("\nat least 6 bytes received \n"); + packet_length = ((unsigned short int) recv_buffer_small[4] << 8) | (((unsigned short int) recv_buffer_small[5]) & 0x00ff); + /* ecss say: C = (Number of octets in packet data field) - 1 */ + packet_length++; + DEBUGP("the packet length is: %d \n", packet_length); + + recv_bytes = recv(fdType, recv_buffer, packet_length+6, MSG_PEEK); + DEBUGP("got all bytes: %d \n", recv_bytes); + + if (recv_bytes == packet_length+6) + { + DEBUGP("\npacket is available \n"); + return 1; + } + else if (recv_bytes < packet_length+6) + { + DEBUGP("\nclear: %d Bytes \n", recv_bytes); + recv_bytes = recv(fdType, recv_buffer, recv_bytes, 0); + (void) recv_bytes; + } + } + + return 0; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +/* + * Function: socketSendPackageOnExistingConnection() + * ----------------------------------- + * Sends given package via existing socket connection. + * + * pckt: The framework package type CrFwPckt_t holding the package that will be sent. + * fdType: specifies the socket endpoint: e.g. fdGrnd or fdIasw or fdObc + * + * returns: 0 in case of error, 1 in case of success. + */ +static CrFwBool_t socketSendPackageOnExistingConnection(int fdType, CrFwPckt_t pckt) +{ + int ret; + char *buf; + CrFwPcktLength_t len, __attribute__((unused)) len1; + CrFwTimeStamp_t __attribute__((unused)) timeS; + + /* Christian: check TimeStamp and insert CRC */ + DEBUGP("InsertCrc (existing connection)\n"); + InsertCrc(pckt); + len = CrFwPcktGetLength(pckt); + DEBUGP("len = %d\n", len); + + buf = malloc(len); + if (buf == NULL) + { + perror("ERROR setting up connection\n"); + exit(EXIT_FAILURE); + } + memcpy(buf, pckt, len); + + ret = send_all(fdType, buf, len); + + free(buf); + + if (ret) + { + DEBUGP("socket send failed to transmit all bytes: %d remaining\n", ret); + return 0; + } + + DEBUGP ("package sent:"); + printPackageInfo(pckt); + + return 1; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +/* + * Function: socketSendPackageOnNewConnection() + * ----------------------------------- + * Opens socket connection to specified host url and sends given package. Socket is closed afterwards. + * + * pckt: The framework package type CrFwPckt_t holding the package that will be sent. + * url: String holding the socket url (inclusive port). + * + * returns: 0 in case of error, 1 in case of success. + */ +__attribute__((unused)) +static CrFwBool_t socketSendPackageOnNewConnection(CrFwPckt_t pckt, const char* url) +{ + int ret, sockfd, endpoint; + char *buf, *str; + struct sockaddr_in server; + CrFwPcktLength_t len; + __attribute__((unused)) CrFwTimeStamp_t timeS; + + /* Christian: check TimeStamp and insert CRC */ + DEBUGP("InsertCrc (new connection)\n"); + InsertCrc(pckt); + len = CrFwPcktGetLength(pckt); + DEBUGP("len = %d\n", len); + + buf = malloc(len); + if (buf == NULL) + { + perror("ERROR setting up connection\n"); + exit(EXIT_FAILURE); + } + memcpy(buf, pckt, len); + + str = malloc(strlen(url)); + if (str == NULL) + { + perror("ERROR setting up connection\n"); + exit(EXIT_FAILURE); + } + strcpy(str, url); + + server.sin_addr.s_addr = inet_addr(strtok(str, ":")); + server.sin_family = AF_INET; + server.sin_port = htons(atoi(strtok(NULL, ":"))); + free(str); + + sockfd = socket(AF_INET , SOCK_STREAM , 0); + endpoint = connect(sockfd, (struct sockaddr *) &server , sizeof(server)); + if (endpoint < 0) + { + close(sockfd); + free(buf); + DEBUGP("could not connect to endpoint: %s\n", url); + return 0; + } + + ret = send_all(sockfd, buf, len); + free(buf); + + if (ret) + { + DEBUGP("socket send failed to transmit all bytes: %d remaining\n", ret); + return 0; + } + + DEBUGP ("package sent to: %s\n", url); + printPackageInfo(pckt); + close(endpoint); + close(sockfd); + + return 1; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +/* + * Function: socketReceivePackage() + * ----------------------------------- + * Receives package as bytes on a given server socket. This method is called by collection methods like: CrIbGrndPcktCollect() and CrIbMilBusPcktCollect() + * + * fdType: specifies the socket endpoint: e.g. fdGrnd or fdIasw or fdObc + * + * returns: The framework package type CrFwPckt_t + */ +static CrFwPckt_t socketReceivePackage(int fdType) +{ + __attribute__((unused)) int i; + ssize_t recv_bytes; + unsigned short int packet_length; + char recv_buffer_small[6]; + char recv_buffer[CR_IA_MAX_SIZE_PCKT_LARGE]; + CrFwPckt_t pckt; + + /* peek at the header again and try to fetch a packet*/ + recv_bytes = recv(fdType, recv_buffer_small, 6, MSG_PEEK); + if (recv_bytes < 6) + { + DEBUGP("ERROR reading from socket\n"); + } + + /* DEBUGP("Received header\n"); */ + + packet_length = ((unsigned short int) recv_buffer_small[4] << 8) | (((unsigned short int) recv_buffer_small[5]) & 0x00ff); + /* ecss say: C = (Number of octets in packet data field) - 1 */ + packet_length++; + + recv_bytes = recv(fdType, recv_buffer, packet_length+6, 0); + + if (recv_bytes == -1) + { + perror("receivePackageOnSocket()"); + return NULL; + } + /* DEBUGP("recv_bytes: %d ", recv_bytes); + for (i=0; i<recv_bytes; i++) { + + DEBUGP("%x-",(unsigned int)recv_buffer[i]&0xff); + + } + DEBUGP("\n"); */ + debugPacket(recv_buffer, packet_length+6); + + if ((((ssize_t) packet_length)+6) != recv_bytes) + { + DEBUGP("returning NULL \n"); + return NULL; + } + + DEBUGP("CrFwPcktMake with a length of %d bytes\n", recv_bytes); + pckt = CrFwPcktMake((CrFwPcktLength_t)recv_bytes); + if (pckt == NULL) + { + DEBUGP("CrFwPcktMake returned null on %d bytes\n", recv_bytes); + return NULL; + } + memcpy(pckt, recv_buffer, ((int)recv_bytes)); + /* free(recv_buffer); */ + + /* DEBUG: Injecting specific package.*/ + /*pckt = CrFwPcktMake((CrFwPcktLength_t) (12)); + memcpy(pckt, srv17TcIasw, 12); */ + + DEBUGP ("package received:\n"); + printPackageInfo(pckt); + + reRouteCnC(pckt); + + return pckt; +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +static int socketConnectPoll(const char* url) +{ + int sockfd, ret; + char *str; + struct sockaddr_in server; + + DEBUGP("connecting to endpoint: %s\n", url); + + str = malloc(strlen(url)+1); + if (str == NULL) + { + perror("ERROR setting up connection\n"); + exit(EXIT_FAILURE); + } + strcpy(str, url); + + server.sin_addr.s_addr = inet_addr(strtok(str, ":")); + server.sin_family = AF_INET; + server.sin_port = htons(atoi(strtok(NULL, ":"))); + free(str); + sockfd = socket(AF_INET , SOCK_STREAM , 0); + while(1) + { + ret = connect(sockfd, (struct sockaddr *) &server , sizeof(server)); + if (ret < 0) + { + sleep(1); + } + else + { + return sockfd; + } + } +} +#endif /* PC_TARGET */ + + +#ifdef PC_TARGET +static void debugPacket(char* pckt, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + { + if (i > 0) DEBUGP(":"); + DEBUGP("%02X", (unsigned char)pckt[i]); + } + DEBUGP("\n"); + + return; +} +#endif /* PC_TARGET */ + + +__attribute__((unused)) static void printPackageInfo(CrFwPckt_t pckt) +{ + /* CLANG does not see DEBUGP using these variables */ + __attribute__((unused)) CrFwDestSrc_t pcktDest; + __attribute__((unused)) CrFwDestSrc_t pcktSrc; + __attribute__((unused)) CrFwGroup_t group; + __attribute__((unused)) char* str; + + int type; + + pcktDest = CrFwPcktGetDest(pckt); + pcktSrc = CrFwPcktGetSrc(pckt); + type = CrFwPcktGetCmdRepType(pckt); + group = CrFwPcktGetGroup(pckt); + if (type == crCmdType) + { + str = "command"; + } + else + { + str = "report"; + } + DEBUGP("Package -- sourceID: %d, destID: %d, packetType: %s, Group: %d \n", pcktSrc, pcktDest, str, group); + + return; +} diff --git a/CrIa/src/CrIaIasw.h b/CrIa/src/CrIaIasw.h new file mode 100644 index 0000000000000000000000000000000000000000..2f4415d1e03c3a6d7982cbf84a1c443c2587224f --- /dev/null +++ b/CrIa/src/CrIaIasw.h @@ -0,0 +1,204 @@ +/** + * @file CrIaIasw.h + * @authors V. Cechticky and A. Pasetti, P&P Software GmbH, 2015; R. Ottensamer and C. Reimers, Institute for Astrophysics, 2015-2016 + * + * @brief Functions provided or called by the IASW. + * + * These functions define the call-back interface that the IASW software + * provides or uses. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef CRIA_IASW_H +#define CRIA_IASW_H + +/* Includes */ +#include <CrFwConstants.h> +#include <CrIaDataPool.h> /* for MAX_ID_ALGO */ +#include <stddef.h> + +#define MAX_PUS_PACKET_SIZE 65542 /* 16 bit addressing + 6 header bytes */ + +/* Constants as of CHEOPS-PNP-INST-RS-001, issue 8.1, section 13, HbSem Monitoring Function */ +#define HBSEM_MON_LIM 6 +#define HBSEM_MON_PER 160 /* cycles */ + +/* global variable for state machine descriptor for the SEM state machine */ +extern FwSmDesc_t smDescSem, smDescIasw; +extern FwSmDesc_t smDescFdTelescopeTempMonitorCheck, smDescFdIncorrectSDSCntrCheck, smDescFdSemCommErrCheck; +extern FwSmDesc_t smDescFdSemModeTimeOutCheck, smDescFdSemSafeModeCheck, smDescFdSemAliveCheck; +extern FwSmDesc_t smDescFdSemAnomalyEventCheck, smDescFdSemLimitCheck, smDescFdDpuHousekeepingCheck; +extern FwSmDesc_t smDescFdCentroidConsistencyCheck, smDescFdResourceCheck, smDescFdSemModeConsistencyCheck; +extern unsigned char CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_SET; +extern FwSmDesc_t outStreamSem, outStreamObc, outStreamGrd; +extern FwSmDesc_t smDescSdu2, smDescSdu4; +extern FwSmDesc_t smDescSdb; +extern FwSmDesc_t smDescAlgoCent0, smDescAlgoCent1, smDescAlgoTtc1, smDescAlgoTtc2, smDescAlgoAcq1, smDescAlgoCmpr, smDescAlgoSaaEval, smDescAlgoSdsEval; +extern FwSmDesc_t algoSm[MAX_ID_ALGO]; + +/* global variable for procedure descriptor for the Science Procedure */ +extern FwPrDesc_t prDescNomSci, prDescAcqFullDrop, prDescCalFullSnap, prDescSciStack; +extern FwPrDesc_t prDescPrepSci, prDescSciDataUpd, prDescSaveImages, prDescTransferFbfToGround; +extern FwPrDesc_t prDescCentAlgo, prDescAcq1AlgoExec, prDescCmprAlgoExec, prDescTtc1aft, prDescTtc1front, prDescTtc2aft, prDescTtc2front; +extern FwPrDesc_t prDescFbfLoad, prDescFbfSave; +extern FwPrDesc_t prDescCentVal, prDescSaaEval, prDescSdsEval; +extern FwPrDesc_t prDescSemInit, prDescSemShutdown, prDescCtrldSwitchOffIasw; +extern FwPrDesc_t prDescSemAnoEvtRP, prDescHbSemMon, prDescSemModeConsistencyCheck; +extern FwPrDesc_t procPr[MAX_ID_PROC]; + +/* global handles for TM/TCs */ +extern FwSmDesc_t smDescSemTimeCmd; + +/* global variable used by SEM Unit State Machine */ +extern FwSmDesc_t inStreamSem; + +/* global handles For FdCheck */ +extern unsigned int fdSemCommErrCnt; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_POWERON_Flag; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_SAFE_Flag; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_STAB_Flag; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_TEMP_Flag; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_CCDWIN_Flag; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_CCDFULL_Flag; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_DIAG_Flag; +extern CrFwBool_t CMD_MODE_TRANSITION_TO_STANDBY_Flag; +extern CrFwBool_t FD_SDSC_ILL_Flag, FD_SDSC_OOS_Flag; + +/* S21 globals. */ +#if (__sparc__) +extern struct CrIaSib incomingSibInStruct; +extern struct CrIaSib outgoingSibInStruct; +#else +extern struct CrIaSib *ShmIncomingSibInPTR; /* shared memory for fork() */ +extern struct CrIaSib *ShmOutgoingSibInPTR; /* shared memory for fork() */ +#endif /* (__sparc__) */ + +/* our collection of flags */ +extern unsigned int S21LastAcqId; +extern unsigned short S21LastPacketNum; +extern unsigned char S21_Flag1; +extern unsigned char signal_Ta; +extern unsigned char S196Flag; + +extern CrFwBool_t firstCycleAcqCycTtc2; + +/* Demo Specific Interface */ +void setupConnections(); +void shutdownConnections(); + +#if (__sparc__) +#include "../../ifsw.h" +#else +#define RTCONT_ACQ 4 +#define RTCONT_CMPR 5 +#define DEADLINE_ACQ 0.0f +#define DEADLINE_CMPR 0.0f +unsigned short cpu1_notification (unsigned short action); +void run_acquisition(void); +void run_compression(void); +void execute_acquisition(void); +void execute_compression(void); +void run_rt(unsigned int rt_id, float deadline, void (*behaviour) (void)); +#endif /* __sparc__ */ + +extern unsigned int *sibAddressFull, *cibAddressFull, *gibAddressFull; +extern unsigned int *sibAddressWin, *cibAddressWin, *gibAddressWin; + +extern CrFwPckt_t S21SemPacket; + +#include "Sdp/SdpBuffers.h" + + +/** + * Interface provided by the IASW and called by the IBSW. + * + * \return 0 in case of success, -1 in case of error. + */ +int CrIaInit(); + +void CrIaEvtRaise(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize); + +void SdpEvtRaise(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize); + +void CrIaEvtRep(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize); + +void CrIaErrRep(CrFwServSubType_t SubType, unsigned short evtId, unsigned short *evtData, unsigned int DataSize); + +void CrIaExecCycActivities(); + +void CrIaLoadSemTimeCmd(); + +void CrIaOutStreamConnectionAvail(FwSmDesc_t smDesc); + +/* Interface provided by IBSW and called by the IASW */ +CrFwBool_t CrIbIsSemPcktAvail(CrFwDestSrc_t src); +CrFwPckt_t CrIbSemPcktCollect(CrFwDestSrc_t src); +CrFwBool_t CrIbSemPcktHandover(CrFwPckt_t pckt); + +CrFwBool_t CrIbIsObcPcktAvail(CrFwDestSrc_t src); +CrFwBool_t CrIbIsGrdPcktAvail(CrFwDestSrc_t src); +CrFwBool_t CrIbIsMilBusPcktAvail(CrFwDestSrc_t src); +CrFwPckt_t CrIbObcPcktCollect(CrFwDestSrc_t src); +CrFwPckt_t CrIbGrdPcktCollect(CrFwDestSrc_t src); +CrFwPckt_t CrIbMilBusPcktCollect(CrFwDestSrc_t src); + +CrFwBool_t CrIbMilBusPcktHandover(CrFwPckt_t pckt); +CrFwBool_t CrIbMilBusPcktHandoverPrepare(CrFwPckt_t pckt); +CrFwBool_t CrIbSemPcktHandoverPrepare(CrFwPckt_t pckt); + +/* framework wants "Fw" not "Ib" */ +CrFwTimeStamp_t CrFwGetCurrentTime(); + +#ifdef PC_TARGET +/*extern unsigned int requestAcquisition;*/ +/*extern unsigned int requestCompression;*/ +/* global handles for shared memory for fork() for PC simulation */ +extern unsigned int *ShmRequestAcquisitionPTR; /* shared memory for fork() */ +extern unsigned int *ShmRequestCompressionPTR; /* shared memory for fork() */ + +extern struct DataPoolCordet dpCordet; +extern struct DataPoolIasw dpIasw; +extern struct DataPoolIbsw dpIbsw; +#endif /* PC_TARGET */ + +/* time interface for PC simulation */ +#ifdef PC_TARGET +CrFwTimeStamp_t CrIbGetCurrentTime(); +CrFwTimeStamp_t CrIbGetNextTime(); +unsigned int CrIbGetNotifyCnt(); +void CrIbUpdateDataPoolVariablesWithValuesFromIbswSysctlTree(unsigned int hz); +#endif /* PC_TARGET */ + +/* heater switches stubs for PC */ +#ifdef PC_TARGET +enum heater {HEATER_1, HEATER_2, HEATER_3, HEATER_4}; +void fpga_heater_on(enum heater h); +void fpga_heater_off(enum heater h); +#endif /* PC_TARGET */ + +/* flash stubs for PC */ +#ifdef PC_TARGET +int CrIbFlashIsReady(void); +void CrIbFbfClose(unsigned char fbf); +void CrIbFbfOpen(unsigned char fbf); +int CrIbFlashTriggerWrite(unsigned char fbf, unsigned int *mem); +int CrIbFlashTriggerRead(unsigned char fbf, unsigned short block, unsigned int *mem); +unsigned int flash_gen_logical_addr(unsigned int block, unsigned int page, unsigned int offset); +#endif /* PC_TARGET */ + +void CrIaLoadHeartbeatReport(); + +void CrIaLoadAocsReport(); + +#endif /* CRIA_IASW_H */ + diff --git a/CrIa/src/CrIaInCmp.c b/CrIa/src/CrIaInCmp.c new file mode 100644 index 0000000000000000000000000000000000000000..6642b3b3533e1f433c6b360decbcf2af1d0bfe82 --- /dev/null +++ b/CrIa/src/CrIaInCmp.c @@ -0,0 +1,114 @@ +/** + * @file CrIaInCmp.c + * @ingroup CrIaDemo + * + * Implmentation of Cordet Framework adaptation points for InComponents. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +/* Includes */ +#include <string.h> +#include "FwProfile/FwPrConfig.h" +#include "CrFramework/Pckt/CrFwPckt.h" +#include "CrFwCmpData.h" +#include "CrIaPckt.h" +#include <byteorder.h> + +#include <string.h> + +#include <IfswDebug.h> +#include <IfswUtilities.h> + +int LTblInit; /* set in CrIaInit to 0 */ +CrIaPcktCrc_t LTbl[256]; + + +CrFwBool_t CheckCrc(CrFwPckt_t pckt) +{ + CrIaPcktCrc_t CrcPckt; + CrIaPcktCrc_t CrcCheck; + CrFwPcktLength_t len, i; + + /* Get stored CRC from packet */ + CrcPckt = CrIaPcktGetCrc(pckt); + + /* Calculate CRC from packet */ + CrcCheck = 0xFFFF; + if (!LTblInit) + { + InitLtbl(LTbl); + LTblInit = 1; + } + len = CrFwPcktGetLength(pckt) - sizeof(CrIaPcktCrc_t); + for (i=0; i<len; ++i) + { + CrcCheck = Crc(pckt[i], CrcCheck, LTbl); + } + CrcCheck = be16_to_cpu(CrcCheck); + + DEBUGP("CRC stored in packet: %d \nCRC calculated from package: %d \n", CrcPckt, CrcCheck); + + /* Compare stored and calculated CRC + * 0 = failure + * 1 = success + */ + return (CrcPckt == CrcCheck); +} + +CrFwBool_t CrIaInCmdValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* cmpSpecificData; + CrFwPckt_t pckt; + + cmpData = (CrFwCmpData_t*)FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + pckt = cmpSpecificData->pckt; + + DEBUGP("CrIaInCmdValidityCheck: prDesc is at home at %08x\n", (unsigned int)prDesc); + + /* Check checksum of InCmd. Note that this also implicitly verifies the + correctness of the command's length. This is because function CheckCrc + uses the command length to locate the position of the CRC field. hence, + if the command length is incorrect, the CRC cannot be found and the + CRC check fails */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* Ckeck length of InCmd: NOTE is done implicitly with previous check of CRC */ + DEBUGP("CrIaInCmdValidityCheck: length = %d\n", CrFwPcktGetLength(pckt)); + + return 1; +} + +CrFwBool_t CrIaInRepValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInRepData_t* cmpSpecificData; + CrFwPckt_t pckt; + + cmpData = (CrFwCmpData_t*)FwPrGetData(prDesc); + cmpSpecificData = (CrFwInRepData_t*)(cmpData->cmpSpecificData); + pckt = cmpSpecificData->pckt; + + DEBUGP("CrIaInRepValidityCheck: prDesc is at home at %08x\n", (unsigned int)prDesc); + + /* No CRC check for service 21 InReps */ + if (CrFwPcktGetServType(pckt) != 21) + { + /* Check checksum of InRep */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + } + + return 1; +} + diff --git a/CrIa/src/CrIaInCmp.h b/CrIa/src/CrIaInCmp.h new file mode 100644 index 0000000000000000000000000000000000000000..5b591e23b5c8442e50add18f12b1078f76371d9b --- /dev/null +++ b/CrIa/src/CrIaInCmp.h @@ -0,0 +1,28 @@ +/** + * @file CrIaInCmp.h + * @ingroup CrIaDemo + * + * Implmentation of Cordet Framework adaptation points for InComponents. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRIA_INCMP_H +#define CRIA_INCMP_H + +/* Includes */ +#include <FwPrConstants.h> +#include <CrFwConstants.h> + +extern int LTblInit; +extern CrIaPcktCrc_t LTbl[256]; + +CrFwBool_t CheckCrc(CrFwPckt_t pckt); + +CrFwBool_t CrIaInCmdValidityCheck(FwPrDesc_t prDesc); + +CrFwBool_t CrIaInRepValidityCheck(FwPrDesc_t prDesc); + +#endif /* CRIA_INCMP_H */ + diff --git a/CrIa/src/CrIaInLoader.c b/CrIa/src/CrIaInLoader.c new file mode 100644 index 0000000000000000000000000000000000000000..043e67d46004e072876296c7455f156ce22ef2cc --- /dev/null +++ b/CrIa/src/CrIaInLoader.c @@ -0,0 +1,42 @@ +/** + * @file CrIaInLoader.c + * @ingroup CrIaDemo + * + * Implementation of the functions used by the InLoader component. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +/* Includes */ +#include <stdlib.h> +#include "CrIaInLoader.h" +#include "IfswDebug.h" + +CrFwInstanceId_t CrIaInLoaderGetInManager(CrFwServType_t servType, + CrFwServSubType_t servSubType, CrFwDiscriminant_t discriminant, + CrFwCmdRepType_t cmdRepFlag) +{ + CRIA_UNUSED(servType); + CRIA_UNUSED(servSubType); + CRIA_UNUSED(discriminant); + if (cmdRepFlag == crRepType) + { + /* incoming TM packets from SEM */ + DEBUGP("CrIaInLoaderGetInManager: incoming TM packets from SEM\n"); + return 0; + } + /* incoming TC packets from Grnd / OBC */ + DEBUGP("CrIaInLoaderGetInManager: incoming TM packets from Grnd / OBC\n"); + return 1; +} + +CrFwDestSrc_t CrIaInLoaderGetReroutingDestination(CrFwDestSrc_t pcktDest) +{ + if ((pcktDest == CR_FW_CLIENT_SEM) || + (pcktDest == CR_FW_CLIENT_OBC) || + (pcktDest == CR_FW_CLIENT_GRD)) + return pcktDest; /* Packet must be re-routed to the SEM, OBC or GRD */ + else + return 0; /* Packet destination is invalid */ +} diff --git a/CrIa/src/CrIaInLoader.h b/CrIa/src/CrIaInLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..54edf5068bba202e2378a2f2813118252b9d880d --- /dev/null +++ b/CrIa/src/CrIaInLoader.h @@ -0,0 +1,26 @@ +/** + * @file CrIaInLoader.h + * @ingroup CrIaDemo + * + * Definition of the functions used by the InLoader component. + * + * \see CrFwInLoader.h + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRIA_INLOADER_H +#define CRIA_INLOADER_H + +/* Includes */ +#include <CrFwConstants.h> +#include "CrFwUserConstants.h" + +CrFwInstanceId_t CrIaInLoaderGetInManager(CrFwServType_t servType, CrFwServSubType_t servSubType, + CrFwDiscriminant_t discriminant, CrFwCmdRepType_t cmdRepFlag); + +CrFwDestSrc_t CrIaInLoaderGetReroutingDestination(CrFwDestSrc_t pcktDest); + +#endif /* CRIA_INLOADER_H */ + diff --git a/CrIa/src/CrIaMain.c b/CrIa/src/CrIaMain.c new file mode 100644 index 0000000000000000000000000000000000000000..1d2fedfe3d975fcb5b7bf0607a32a46ade03d610 --- /dev/null +++ b/CrIa/src/CrIaMain.c @@ -0,0 +1,279 @@ +/** + * @file CrIaDemoMain.c + * @ingroup CrIaDemo + * + * Implementation of the functionality of the IBSW. + * + * This module is an emulation of the functionality of the Instrument Basic + * Software (IBSW). Its main responsibility for the demo application is to run + * an infinite loop that triggers the IASW components. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#define IASW_ENDPOINT_GRND "tcp://*:5571" +#define IASW_ENDPOINT_SEM "tcp://*:5572" +#define BILLION 1000000000 +#define CYCLIC_INTERVAL 125000000 /* 125 ms */ + +typedef struct timespec Time; + +/* Includes DEBUG staff */ +#include "IfswDebug.h" + +/* Includes */ +#include "CrIaIasw.h" + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <stdint.h> +#include <unistd.h> /* for fork() */ + +#ifdef PC_TARGET +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> +#include <ScienceDataProcessing.h> +#include <EngineeringAlgorithms.h> +#include <TargetAcquisition.h> +#include <IfswConversions.h> +#include <sys/ipc.h> /* for shared memory */ +#include <sys/shm.h> /* for shared memory */ +#include <unistd.h> /* for fork() */ +#include <string.h> /* mor memcpy */ +#endif /* PC_TARGET */ + +static unsigned int nOfNotif_ID[N_RT_CONT] = { + NOFNOTIF_1_ID, NOFNOTIF_2_ID, NOFNOTIF_3_ID, NOFNOTIF_4_ID, + NOFNOTIF_5_ID}; + +/* Prototypes */ +int startCyclicActivities(); +Time addTime(Time t1, Time t2); +int diffTime(Time t3, Time t4); + +int main() { + if (CrIaInit() == -1) return EXIT_FAILURE; + +#ifdef PC_TARGET + setupConnections(); + + DEBUGP("start cyclic execution IASW %u\n", BUILD); + if (startCyclicActivities() == -1) return EXIT_FAILURE; + + shutdownConnections(); +#else + /** TODO **/ +#endif /* PC_TARGET */ + + return EXIT_SUCCESS; +} + +#ifdef PC_TARGET +int startCyclicActivities() +{ +/* int ShmID; */ +/* int *ShmPTR; */ + pid_t pid; +/* int status; */ + int ShmRequestAcquisitionID; + int ShmRequestCompressionID; + int ShmOutgoingSibInID; + int ShmIncomingSibInID; + int ShmdpCordetID; + int ShmdpIaswID; + int ShmdpIbswID; + struct DataPoolCordet *pdpCordet; + struct DataPoolIasw *pdpIasw; + struct DataPoolIbsw *pdpIbsw; + unsigned short status; + unsigned int rt_idx; + unsigned int nOfNotif; + unsigned char FdCheckDpuHousekeepingIntEn, FdCheckResourceIntEn; + short valueShort, ADC_TEMP1_RAW, DPU_N5V_RAW; + float valueFloat; + + Time nextTime, interval; + + interval.tv_sec = 0; + interval.tv_nsec = CYCLIC_INTERVAL; + + if (clock_gettime(CLOCK_MONOTONIC, &nextTime) == -1) + { + perror("clock_gettime error"); + return -1; + } + + ShmRequestAcquisitionID = shmget(IPC_PRIVATE, sizeof(unsigned int), IPC_CREAT | 0666); + ShmRequestCompressionID = shmget(IPC_PRIVATE, sizeof(unsigned int), IPC_CREAT | 0666); + ShmOutgoingSibInID = shmget(IPC_PRIVATE, sizeof(struct CrIaSib), IPC_CREAT | 0666); + ShmIncomingSibInID = shmget(IPC_PRIVATE, sizeof(struct CrIaSib), IPC_CREAT | 0666); + + ShmRequestAcquisitionPTR = (unsigned int *) shmat(ShmRequestAcquisitionID, NULL, 0); + ShmRequestCompressionPTR = (unsigned int *) shmat(ShmRequestCompressionID, NULL, 0); + ShmOutgoingSibInPTR = (struct CrIaSib *) shmat(ShmOutgoingSibInID, NULL, 0); + ShmIncomingSibInPTR = (struct CrIaSib *) shmat(ShmIncomingSibInID, NULL, 0); + + ShmdpCordetID = shmget(IPC_PRIVATE, sizeof(struct DataPoolCordet), IPC_CREAT | 0666); + ShmdpIaswID = shmget(IPC_PRIVATE, sizeof(struct DataPoolIasw), IPC_CREAT | 0666); + ShmdpIbswID = shmget(IPC_PRIVATE, sizeof(struct DataPoolIbsw), IPC_CREAT | 0666); + + pdpCordet = (struct DataPoolCordet *) shmat(ShmdpCordetID, NULL, 0); + pdpIasw = (struct DataPoolIasw *) shmat(ShmdpIaswID, NULL, 0); + pdpIbsw = (struct DataPoolIbsw *) shmat(ShmdpIbswID, NULL, 0); + + memcpy (pdpCordet, &dpCordetInit, sizeof(struct DataPoolCordet)); + memcpy (pdpIasw, &dpIaswInit, sizeof(struct DataPoolIasw)); + memcpy (pdpIbsw, &dpIbswInit, sizeof(struct DataPoolIbsw)); + + /* fork */ + pid = fork(); + + if (!pid) + { + initDpAddresses(pdpCordet, pdpIasw, pdpIbsw); + + usleep(10000); + + /* child: CPU2 */ + while (1) + { + usleep(1000); + + /* waiting for notifications */ + + if (ShmRequestAcquisitionPTR[0] > 0) + { + DEBUGP(">>>\n>>> CPU2 was notified for ACQUISITION (Cnt: %d), and start TargetAcquisition ...\n>>>\n", ShmRequestAcquisitionPTR[0]); + + CrIaCopy(CPU2PROCSTATUS_ID, &status); + + if (status == SDP_STATUS_IDLE) + { + status = SDP_STATUS_ACQUISITION; + CrIaPaste(CPU2PROCSTATUS_ID, &status); + + TargetAcquisition(ShmOutgoingSibInPTR); + + status = SDP_STATUS_IDLE; + CrIaPaste(CPU2PROCSTATUS_ID, &status); + ShmRequestAcquisitionPTR[0]--; + } + + DEBUGP(">>>\n>>> CPU2 finished TargetAcquisition ...\n>>>\n"); + } + + if (ShmRequestCompressionPTR[0] > 0) + { + DEBUGP(">>>\n>>> CPU2 was notified COMPRESSION (Cnt: %d), and start ScienceProcessing ...\n>>>\n", ShmRequestCompressionPTR[0]); + + CrIaCopy(CPU2PROCSTATUS_ID, &status); + + /* increment nOfNotif */ + rt_idx = 0; + CrIaCopy(nOfNotif_ID[rt_idx], &nOfNotif); + nOfNotif++; + CrIaPaste(nOfNotif_ID[rt_idx], &nOfNotif); + + DEBUGP("nOfNotif = %d\n", nOfNotif); + + if (status == SDP_STATUS_IDLE) + { + status = SDP_STATUS_SCIENCE; + CrIaPaste(CPU2PROCSTATUS_ID, &status); + + ScienceProcessing(); + + status = SDP_STATUS_IDLE; + CrIaPaste(CPU2PROCSTATUS_ID, &status); + ShmRequestCompressionPTR[0]--; + } + + DEBUGP(">>>\n>>> CPU2 finished ScienceProcessing ...\n>>>\n"); + } + + } + + } + else if (pid > 0) + { + initDpAddresses(pdpCordet, pdpIasw, pdpIbsw); + + usleep(10000); + + /* Enable DPU housekeeping FdCheck */ + FdCheckDpuHousekeepingIntEn = 1; + CrIaPaste(FDCHECKDPUHKINTEN_ID, &FdCheckDpuHousekeepingIntEn); + + /* Enable Resource FdCheck */ + FdCheckResourceIntEn = 1; + CrIaPaste(FDCHECKRESINTEN_ID, &FdCheckResourceIntEn); + + /* Initialize temperature values */ + DPU_N5V_RAW = 3504; /* = -5.12488317489624 V */ + CrIaPaste(ADC_N5V_RAW_ID, &DPU_N5V_RAW); + valueShort = 3300; /* = -16.437718 degC */ + CrIaPaste(ADC_TEMPOH1A_RAW_ID, &valueShort); + CrIaPaste(ADC_TEMPOH2A_RAW_ID, &valueShort); + CrIaPaste(ADC_TEMPOH3A_RAW_ID, &valueShort); + CrIaPaste(ADC_TEMPOH4A_RAW_ID, &valueShort); + CrIaPaste(ADC_TEMPOH1B_RAW_ID, &valueShort); + CrIaPaste(ADC_TEMPOH2B_RAW_ID, &valueShort); + CrIaPaste(ADC_TEMPOH3B_RAW_ID, &valueShort); + CrIaPaste(ADC_TEMPOH4B_RAW_ID, &valueShort); + ADC_TEMP1_RAW = 4700; /* = 19.545044 degC */ + CrIaPaste(ADC_TEMP1_RAW_ID, &ADC_TEMP1_RAW); + valueFloat = convertToTempEngVal_DPU(ADC_TEMP1_RAW) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMP1_ID, &valueFloat); + + /* parent: CPU1 */ + while (1) + { + CrIaExecCycActivities(); + nextTime = addTime(nextTime, interval); + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &nextTime, NULL); + } + + } + else + { + perror("fork error"); + return -1; + + } + + return 0; +} + +Time addTime(Time t1, Time t2) { + Time resTime; + long sec = t2.tv_sec + t1.tv_sec; + long nsec = t2.tv_nsec + t1.tv_nsec; + if (nsec >= BILLION) { + nsec -= BILLION; + sec++; + } + resTime.tv_sec = sec; + resTime.tv_nsec = nsec; + return resTime; +} + +int diffTime(Time t3, Time t4) { + Time resTime; + long sec = t4.tv_sec - t3.tv_sec; + long nsec = t4.tv_nsec - t3.tv_nsec; + if (nsec < 0) { + nsec += BILLION; + sec--; + } + resTime.tv_sec = sec; + resTime.tv_nsec = nsec; + if(resTime.tv_sec<0) { + return 1; + } else { + return 0; + } +} +#endif /* PC_TARGET */ diff --git a/CrIa/src/CrIaOutCmp.c b/CrIa/src/CrIaOutCmp.c new file mode 100644 index 0000000000000000000000000000000000000000..620ff3b14e0b8e8c25c3e083b68c0b6ff83b2213 --- /dev/null +++ b/CrIa/src/CrIaOutCmp.c @@ -0,0 +1,48 @@ +/** + * @file CrIaOutCmp.c + * @ingroup CrIaDemo + * + * Implmentation of Cordet Framework adaptation points for OutComponents. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +/* Includes */ +#include <CrFwConstants.h> +#include <Pckt/CrFwPckt.h> +#include <FwSmConfig.h> +#include "CrFwCmpData.h" +#include "CrIaPckt.h" + +/** + * Set packet values fixed for the IASW. + * + * Fixed fields in the TC / TM packets are. + * - Version Number (always binary '000') + * - Data Field Header flag (always binary '1') + * - Sequence / Segmentation flags (always binary '11') + * - PUS version number (always binary '001') + * - CRC + * - CRC not done because of Mantis 756 + */ +static void CrIaPcktSetFixedFields(CrFwPckt_t pckt) +{ + CrIaPcktSetVersion(pckt, 0x00); + CrIaPcktSetDataFieldFlag(pckt, 0x01); + CrIaPcktSetSeqFlags(pckt, 0x03); + CrIaPcktSetPusVersion(pckt, 0x01); + return; +} + + +void CrIaOutCmpDefSerialize(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + pckt = cmpSpecificData->pckt; + CrIaPcktSetFixedFields(pckt); + return; +} + diff --git a/CrIa/src/CrIaOutCmp.h b/CrIa/src/CrIaOutCmp.h new file mode 100644 index 0000000000000000000000000000000000000000..cbda279b3e75cf309ec332d7bf3583925662c43e --- /dev/null +++ b/CrIa/src/CrIaOutCmp.h @@ -0,0 +1,20 @@ +/** + * @file CrIaOutCmp.h + * @ingroup CrIaDemo + * + * Implmentation of Cordet Framework adaptation points for OutComponents. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRIA_OUTCMP_H +#define CRIA_OUTCMP_H + +/* Includes */ +#include <CrFwConstants.h> + +void CrIaOutCmpDefSerialize(FwSmDesc_t smDesc); + +#endif /* CRIA_OUTCMP_H */ + diff --git a/CrIa/src/CrIaOutLoader.c b/CrIa/src/CrIaOutLoader.c new file mode 100644 index 0000000000000000000000000000000000000000..1995fd6cda30de7c5c1a76ec781c7067bf194616 --- /dev/null +++ b/CrIa/src/CrIaOutLoader.c @@ -0,0 +1,64 @@ +/** + * @file CrIaOutLoader.c + * @ingroup CrIaDemo + * + * Implementation of the functions used by the InLoader component. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +/* Includes */ +#include "CrFwUserConstants.h" +#include "CrIaOutLoader.h" +#include "CrFwCmpData.h" +#include <Pckt/CrFwPckt.h> +#include <OutManager/CrFwOutManager.h> +#include <FwSmConfig.h> +#include <Services/General/CrIaParamGetter.h> + +FwSmDesc_t CrIaOutLoaderGetOutManager(FwSmDesc_t outCmp) +{ + CrFwCmpData_t* data; + CrFwOutCmpData_t* cmpSpecificData; + CrFwPckt_t pckt; + CrFwServType_t servType; + CrFwServSubType_t servSubType; + CrFwCmdRepType_t cmdRepType; + CrFwDestSrc_t dest; + unsigned char sduId = 0; + + /* Get package */ + data = (CrFwCmpData_t*)FwSmGetData(outCmp); + cmpSpecificData = (CrFwOutCmpData_t*)(data->cmpSpecificData); + pckt = cmpSpecificData->pckt; + + servType = CrFwPcktGetServType(pckt); + servSubType = CrFwPcktGetServSubType(pckt); + cmdRepType = CrFwPcktGetCmdRepType(pckt); + dest = CrFwPcktGetDest(pckt); + + /* OutManager2 and OutManager3 controls all service 13 reports to the OBC/Ground */ + if (cmdRepType == crRepType + && servType == 13 + && dest == CR_FW_CLIENT_GRD) + { + + /* get SduId */ + if (servSubType==1) + CrIaServ13FstDwlkParamGetSduId(&sduId, pckt); + if (servSubType==2) + CrIaServ13IntmDwlkParamGetSduId(&sduId, pckt); + if (servSubType==3) + CrIaServ13LastDwlkParamGetSduId(&sduId, pckt); + + if (sduId==2) + return CrFwOutManagerMake(1); /* controlled by OutManager 2 */ + if ((sduId==3) || (sduId==4)) + return CrFwOutManagerMake(2); /* controlled by OutManager 3 */ + + } + + /* Everything else is controlled by OutManager1 */ + return CrFwOutManagerMake(0); +} diff --git a/CrIa/src/CrIaOutLoader.h b/CrIa/src/CrIaOutLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..99ce574aa2f81ceeaca4fdbc6c35380c31d978e6 --- /dev/null +++ b/CrIa/src/CrIaOutLoader.h @@ -0,0 +1,23 @@ +/** + * @file CrIaOutLoader.h + * @ingroup CrIaDemo + * + * Definition of the functions used by the OutLoader component. + * + * \see CrFwOutLoader.h + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRIA_OUTLOADER_H +#define CRIA_OUTLOADER_H + +/* Includes */ +#include <FwSmConstants.h> + +FwSmDesc_t CrIaOutLoaderGetOutManager(FwSmDesc_t outCmp); + +#endif /* CRIA_OUTLOADER_H */ + + diff --git a/CrIa/src/CrIaPckt.c b/CrIa/src/CrIaPckt.c new file mode 100644 index 0000000000000000000000000000000000000000..0a030a1b47e7d3665b69126ce1daf6a27a8f5d30 --- /dev/null +++ b/CrIa/src/CrIaPckt.c @@ -0,0 +1,777 @@ +/** + * @file CrIaPckt.c + * @ingroup CrIaDemo + * + * Default implementation of the packet interface of CrFwPckt.h. + * + * The implementation of this interface is one of the adaptation points of the + * CORDET Framework. + * + * This file provide the implementation for the IASW application. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +/* Includes */ +#include "IfswDebug.h" +#include "CrIaPckt.h" + +/* for CR_FW_PCAT_SEM_TC */ +#include "CrFwUserConstants.h" + +#include <BaseCmp/CrFwBaseCmp.h> +#include <Pckt/CrFwPckt.h> +#include <UtilityFunctions/CrFwUtilityFunctions.h> + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifdef PC_TARGET +#include <arpa/inet.h> +#include <byteorder.h> +#endif /* PC_TARGET */ + + +/** + * The array holding the small packets. + */ +static char pcktArraySmall[CR_IA_NOF_PCKT_SMALL * CR_IA_MAX_SIZE_PCKT_SMALL]; + +/** + * The array holding the large packets. + */ +static char pcktArrayLarge[CR_IA_NOF_PCKT_LARGE * CR_IA_MAX_SIZE_PCKT_LARGE]; + +/** + * The array holding the "in use" status of small packets. + * + * A packet is in use if it has been requested through a call to the "make" + * function and has not yet been released through a call to the "release" + * function. + */ +/* static CrFwBool_t pcktInUseSmall[CR_IA_MAX_SIZE_PCKT_SMALL] = {0}; */ +static CrFwBool_t pcktInUseSmall[CR_IA_NOF_PCKT_SMALL] = {0}; + +/** + * The array holding the "in use" status of large packets. + * + * A packet is in use if it has been requested through a call to the "make" + * function and has not yet been released through a call to the "release" + * function. + */ +/* static CrFwBool_t pcktInUseLarge[CR_IA_MAX_SIZE_PCKT_LARGE] = {0}; */ +static CrFwBool_t pcktInUseLarge[CR_IA_NOF_PCKT_LARGE] = {0}; + +/** + * The number of currently allocated packets. + */ +static CrFwCounterU2_t nOfAllocatedPckts = 0; + + +CrFwDestSrc_t CrIaPcktGetPid(CrFwPckt_t pckt) +{ + char pid0, pid1; + /* The packet header should be valid */ + pid0 = (pckt[OFFSET_ID_FIELD] & PID0_MASK); + pid1 = (pckt[OFFSET_ID_FIELD + 1] & PID1_MASK) >> PID1_SHIFT; + return ((pid0 << 4) | pid1); +} + +void CrIaPcktSetPid(CrFwPckt_t pckt, CrFwDestSrc_t pid) +{ + char pid0, pid1; + /* The packet header should be valid */ + pckt[OFFSET_ID_FIELD] &= (~PID0_MASK); + pckt[OFFSET_ID_FIELD + 1] &= (~PID1_MASK); + /* Split pid in one 3 (pid0) and one 4 bit (pid1) parts */ + pid0 = ((pid & 0x70) >> 4); + pid1 = (pid & 0x0F); + pckt[OFFSET_ID_FIELD] |= pid0; + pckt[OFFSET_ID_FIELD + 1] |= (pid1 << PID1_SHIFT); + return; +} + +unsigned short CrIaPcktGetApid(CrFwPckt_t pckt) +{ + char apid0, apid1; + /* The packet header should be valid */ + apid0 = (pckt[OFFSET_ID_FIELD] & PID0_MASK); + apid1 = pckt[OFFSET_ID_FIELD + 1]; + return ((apid0 << 8) | apid1); +} + +unsigned short CrIaPcktGetPacketId(CrFwPckt_t pckt) +{ + char packetid0, packetid1; + /* The packet header should be valid */ + packetid0 = pckt[OFFSET_ID_FIELD]; + packetid1 = pckt[OFFSET_ID_FIELD + 1]; + return ((packetid0 << 8) | packetid1); +} + +CrFwGroup_t CrIaPcktGetPcat(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return (pckt[OFFSET_ID_FIELD + PCAT_OFFSET] & PCAT_MASK); +} + +void CrIaPcktSetPcat(CrFwPckt_t pckt, CrFwGroup_t pcat) +{ + /* The packet header should be valid */ + pckt[OFFSET_ID_FIELD + PCAT_OFFSET] &= (~PCAT_MASK); + pckt[OFFSET_ID_FIELD + PCAT_OFFSET] |= (pcat & PCAT_MASK); + return; +} + +CrFwPckt_t CrFwPcktMake(CrFwPcktLength_t pcktLength) +{ + CrFwCounterU2_t i; + CrFwPcktLength_t pcktLengthPUS; + char pcktLengthPUSN[2]; + char *buf; + + DEBUGP("the incoming length is %d\n", pcktLength); + + if (pcktLength > CR_IA_MAX_SIZE_PCKT_LARGE) + { + CrFwSetAppErrCode(crPcktAllocationFail); + return NULL; + } + + if (pcktLength < SRC_PCKT_HDR_LENGTH + 2) + { + CrFwSetAppErrCode(crPcktAllocationFail); + return NULL; + } + + /* Calculate the PUS packet length */ + pcktLengthPUS = pcktLength - SRC_PCKT_HDR_LENGTH - 1; + + /* it will be set using memcpy, so we better use a char array for that */ + pcktLengthPUSN[0] = (pcktLengthPUS >> 8) & 0xff; + pcktLengthPUSN[1] = pcktLengthPUS & 0xff; + + DEBUGP("the length is %01x %01x\n", pcktLengthPUSN[0], pcktLengthPUSN[1]); + + if (pcktLength <= CR_IA_MAX_SIZE_PCKT_SMALL) + { + for (i=0; i<CR_IA_NOF_PCKT_SMALL; i++) + { + if (pcktInUseSmall[i] == 0) + { + pcktInUseSmall[i] = 1; + buf = &pcktArraySmall[(i*CR_IA_MAX_SIZE_PCKT_SMALL)+OFFSET_LENGTH_FIELD]; + memcpy(buf, &pcktLengthPUSN, sizeof(CrFwPcktLength_t)); + nOfAllocatedPckts++; + buf = &pcktArraySmall[(i*CR_IA_MAX_SIZE_PCKT_SMALL)]; + return buf; + } + } + } + else + { + for (i=0; i<CR_IA_NOF_PCKT_LARGE; i++) + { + if (pcktInUseLarge[i] == 0) + { + pcktInUseLarge[i] = 1; + buf = &pcktArrayLarge[(i*CR_IA_MAX_SIZE_PCKT_LARGE)+OFFSET_LENGTH_FIELD]; + memcpy(buf, &pcktLengthPUSN, sizeof(CrFwPcktLength_t)); + buf = &pcktArrayLarge[i*CR_IA_MAX_SIZE_PCKT_LARGE]; + nOfAllocatedPckts++; + return buf; + } + } + } + + CrFwSetAppErrCode(crPcktAllocationFail); + return NULL; +} + +void CrFwPcktRelease(CrFwPckt_t pckt) +{ + CrFwCounterU2_t i; + char *buf; + + if (pckt == NULL) + { + CrFwSetAppErrCode(crPcktRelErr); + return; + } + + if (CrFwPcktGetLength(pckt) <= CR_IA_MAX_SIZE_PCKT_SMALL) + { + for (i=0; i<CR_IA_NOF_PCKT_SMALL; i++) + { + buf = &pcktArraySmall[i*CR_IA_MAX_SIZE_PCKT_SMALL]; + if (pckt == buf) + { + if (pcktInUseSmall[i] == 0) + { + CrFwSetAppErrCode(crPcktRelErr); + } + else + { + nOfAllocatedPckts--; + pcktInUseSmall[i] = 0; + } + return; + } + } + } + else + { + for (i=0; i<CR_IA_NOF_PCKT_LARGE; i++) + { + buf = &pcktArrayLarge[i*CR_IA_MAX_SIZE_PCKT_LARGE]; + if (pckt == buf) + { + if (pcktInUseLarge[i] == 0) + { + CrFwSetAppErrCode(crPcktRelErr); + } + else + { + nOfAllocatedPckts--; + pcktInUseLarge[i] = 0; + } + return; + } + } + } + + CrFwSetAppErrCode(crPcktRelErr); + return; +} + +CrFwCounterU2_t CrFwPcktGetNOfAllocated() +{ + return nOfAllocatedPckts; +} + +CrFwPcktLength_t CrFwPcktGetMaxLength() +{ + return CR_IA_MAX_SIZE_PCKT_LARGE; +} + +CrFwCmdRepType_t CrFwPcktGetCmdRepType(CrFwPckt_t pckt) +{ + unsigned char pusType; + /* The packet header should be valid */ + pusType = ((pckt[OFFSET_ID_FIELD] & PCKT_TYPE_MASK) >> PCKT_TYPE_SHIFT); + if (pusType == 0) + { + return crRepType; + } + return crCmdType; +} + +void CrFwPcktSetCmdRepType(CrFwPckt_t pckt, CrFwCmdRepType_t type) +{ + /* The packet header should be valid */ + pckt[OFFSET_ID_FIELD] &= ~(PCKT_TYPE_MASK); + if (type == crCmdType) + { + pckt[OFFSET_ID_FIELD] |= (1 << PCKT_TYPE_SHIFT); + } + return; +} + +CrFwPcktLength_t CrFwPcktGetLength(CrFwPckt_t pckt) +{ + CrFwPcktLength_t length; + /* The packet header should be valid */ + length = pckt[OFFSET_LENGTH_FIELD + 0] << 8; + length |= (pckt[OFFSET_LENGTH_FIELD + 1] & 0xff); + + DEBUGP("our length is %d\n", length); + + /* The length is the PUS length. This is specified as 'packet_data_field-1' */ + /* Christian: PACKET LENGTH + 1 + SRC_PCKT_HDR_LENGTH (=6) + incl. 2 Bytes length of CRC ? */ + + return length + 1 + SRC_PCKT_HDR_LENGTH; +} + +CrFwSeqCnt_t CrFwPcktGetSeqCtrl(CrFwPckt_t pckt) +{ + unsigned char seqCtrl0, seqCtrl1; + /* The packet header should be valid */ + seqCtrl0 = pckt[OFFSET_SEQ_CTRL_FIELD]; + seqCtrl1 = pckt[OFFSET_SEQ_CTRL_FIELD + 1]; + return ((seqCtrl0 << 8) | seqCtrl1); +} + +void CrFwPcktSetSeqCnt(CrFwPckt_t pckt, CrFwSeqCnt_t seqCnt) +{ + CrIaPcktSeqFlags_t storedFlags; + CrFwSeqCnt_t seqCntN; + storedFlags = CrIaPcktGetSeqFlags(pckt); + +#ifdef PC_TARGET + /* endian handling must be defined */ + seqCntN = (htons(seqCnt & SEQ_COUNT_MASK)); +#else + seqCntN = seqCnt & SEQ_COUNT_MASK; +#endif /* PC_TARGET */ + + /* The packet header should be valid */ + memcpy(&pckt[OFFSET_SEQ_CTRL_FIELD], &seqCntN, sizeof(CrFwSeqCnt_t)); + /* Restore sequence flags */ + CrIaPcktSetSeqFlags(pckt, storedFlags); + + return; +} + +CrFwSeqCnt_t CrFwPcktGetSeqCnt(CrFwPckt_t pckt) +{ + CrFwSeqCnt_t seqCntH, seqCntN; + /* The packet header should be valid */ + memcpy(&seqCntN, &pckt[OFFSET_SEQ_CTRL_FIELD], sizeof(CrFwSeqCnt_t)); + +#ifdef PC_TARGET + /* endian handling must be defined */ + seqCntH = ntohs(seqCntN); +#else + seqCntH = seqCntN; +#endif /* PC_TARGET */ + + return (seqCntH & SEQ_COUNT_MASK); +} + +void CrIaPcktSetCCSDSFlag(CrFwPckt_t pckt, CrFwBool_t flag) +{ + /* The packet header should be valid */ + pckt[OFFSET_DATA_FIELD_TC_TM] &= ~(CCSDS_MASK); + if (flag) + { + pckt[OFFSET_DATA_FIELD_TC_TM] |= (1 << CCSDS_SHIFT); + } + return; +} + +CrFwBool_t CrIaPcktGetCCSDSFlag(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_DATA_FIELD_TC_TM] & CCSDS_MASK) >> CCSDS_SHIFT); +} + +CrFwTimeStamp_t CrFwPcktGetTimeStamp(CrFwPckt_t pckt) +{ + /* No endian conversion for timestamp */ + CrFwTimeStamp_t timeStamp; + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + memset(&timeStamp, 0, sizeof(CrFwTimeStamp_t)); + return timeStamp; + } + /* The packet header should be valid */ + memcpy(&timeStamp, &pckt[OFFSET_DATA_FIELD_TC_TM + SC_TIME_OFFSET], sizeof(CrFwTimeStamp_t)); + return timeStamp; +} + +void CrFwPcktSetTimeStamp(CrFwPckt_t pckt, CrFwTimeStamp_t timeStamp) +{ + CrFwTimeStamp_t timeStamp_f; + + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + return; + } + + memcpy(timeStamp_f.t, timeStamp.t, sizeof(timeStamp.t)/sizeof(timeStamp.t[0])); + + /* The packet header should be valid */ + memcpy(&pckt[OFFSET_DATA_FIELD_TC_TM + SC_TIME_OFFSET], &timeStamp_f, sizeof(CrFwTimeStamp_t)); + + return; +} + + +CrFwDiscriminant_t CrFwPcktGetDiscriminant(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + if ((CrFwPcktGetServType(pckt) == 3) && (CrFwPcktGetServSubType(pckt) == 25)) + { + CrFwDiscriminant_t disc = pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT]; + return disc; + } + else if ((CrFwPcktGetServType(pckt) == 5) + && ((CrFwPcktGetServSubType(pckt) == 1) + || (CrFwPcktGetServSubType(pckt) == 2) + || (CrFwPcktGetServSubType(pckt) == 3) + || (CrFwPcktGetServSubType(pckt) == 4))) + { + CrFwDiscriminant_t disc = ((pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] << 8) | + (pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] & 0xff)); + return disc; + } + else + { + return 0; + } +} + + +void CrFwPcktSetDiscriminant(CrFwPckt_t pckt, CrFwDiscriminant_t discriminant) +{ + /* The packet header should be valid */ + if ((CrFwPcktGetServType(pckt) == 3) && (CrFwPcktGetServSubType(pckt) == 25)) + { + pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT] = discriminant; + } + else if ((CrFwPcktGetServType(pckt) == 5) + && ((CrFwPcktGetServSubType(pckt) == 1) + || (CrFwPcktGetServSubType(pckt) == 2) + || (CrFwPcktGetServSubType(pckt) == 3) + || (CrFwPcktGetServSubType(pckt) == 4))) + { + pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (discriminant >> 8); + pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (discriminant & 0xFF); + } + + return; +} + +void CrFwPcktSetServType(CrFwPckt_t pckt, CrFwServType_t servType) +{ + /* The packet header should be valid */ + pckt[OFFSET_DATA_FIELD_TC_TM + SRV_TYPE_OFFSET] = servType; + return; +} + +CrFwServType_t CrFwPcktGetServType(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return (pckt[OFFSET_DATA_FIELD_TC_TM + SRV_TYPE_OFFSET]); +} + +void CrFwPcktSetServSubType(CrFwPckt_t pckt, CrFwServSubType_t servSubType) +{ + /* The packet header should be valid */ + pckt[OFFSET_DATA_FIELD_TC_TM + SRV_SUBTYPE_OFFSET] = servSubType; + return; +} + +CrFwServSubType_t CrFwPcktGetServSubType(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return (pckt[OFFSET_DATA_FIELD_TC_TM + SRV_SUBTYPE_OFFSET]); +} + +void CrFwPcktSetGroup(CrFwPckt_t pckt, CrFwGroup_t group) +{ + CrIaPcktSetPcat(pckt, group+1); + return; +} + +/* Group is not the PCAT, it is derived from the PCAT */ +CrFwGroup_t CrFwPcktGetGroup(CrFwPckt_t pckt) +{ + CrFwGroup_t pcat; + + pcat = CrIaPcktGetPcat(pckt); + + switch (pcat) + { + case CR_FW_PCAT_SEM_TC : + /* case CR_FW_PCAT_DPU_TC : */ + case CR_FW_PCAT_SEM_TM : + /* case CR_FW_PCAT_DPU_TM_SERV1_5_6 : */ + return 0; + + case CR_FW_PCAT_DPU_TM_SERV13 : + return 3; + + case CR_FW_PCAT_DPU_TM_SERV196 : + return 2; + + case CR_FW_PCAT_DPU_TM_OTHER : + return 1; + + default: + break; + } + + return 0xEE; +} + +void CrFwPcktSetDest(CrFwPckt_t pckt, CrFwDestSrc_t dest) +{ + CrFwDestSrc_t mappedDest; + + mappedDest = dest; + if (dest == CR_FW_CLIENT_GRD) + { + mappedDest = CR_FW_CLIENT_GRD_PUS; + } + + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + CrIaPcktSetPid(pckt, mappedDest); + CrIaPcktSetPcat(pckt, CR_FW_PCAT_SEM_TC); /* commands get the SEM TC pcat */ + } + else + { + /* The packet header should be valid */ + pckt[OFFSET_DATA_FIELD_TC_TM + SRC_DEST_OFFSET] = mappedDest; + } + + return; +} + +CrFwDestSrc_t CrFwPcktGetDest(CrFwPckt_t pckt) +{ + CrFwDestSrc_t rawDest; + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + rawDest = CrIaPcktGetPid(pckt); + } + else + { + /* The packet header should be valid */ + rawDest = pckt[OFFSET_DATA_FIELD_TC_TM + SRC_DEST_OFFSET]; + } + + if (rawDest == CR_FW_CLIENT_GRD_PUS) + { + return CR_FW_CLIENT_GRD; + } + else + { + return rawDest; + } +} + +void CrFwPcktSetSrc(CrFwPckt_t pckt, CrFwDestSrc_t src) +{ + CrFwDestSrc_t mappedSrc; + mappedSrc = src; + if (src == CR_FW_CLIENT_GRD) + { + mappedSrc = CR_FW_CLIENT_GRD_PUS; + } + + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + /* The packet header should be valid */ + pckt[OFFSET_DATA_FIELD_TC_TM + SRC_DEST_OFFSET] = mappedSrc; + } + else + { + CrIaPcktSetPid(pckt, mappedSrc); + } + + return; +} + +CrFwDestSrc_t CrFwPcktGetSrc(CrFwPckt_t pckt) +{ + CrFwDestSrc_t rawSrc; + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + /* The packet header should be valid */ + rawSrc = (pckt[OFFSET_DATA_FIELD_TC_TM + SRC_DEST_OFFSET]); + } + else + { + rawSrc = CrIaPcktGetPid(pckt); + } + + if (rawSrc == CR_FW_CLIENT_GRD_PUS) + { + return CR_FW_CLIENT_GRD; + } + else + { + return rawSrc; + } +} + +void CrFwPcktSetCmdRepId(CrFwPckt_t pckt, CrFwInstanceId_t id) +{ + /* Field not present */ + (void)(pckt); + (void)(id); + return; +} + +CrFwInstanceId_t CrFwPcktGetCmdRepId(CrFwPckt_t pckt) +{ + /* Field not present */ + (void)(pckt); + return 0; +} + +void CrFwPcktSetAckLevel(CrFwPckt_t pckt, CrFwBool_t accept, CrFwBool_t start, + CrFwBool_t progress, CrFwBool_t term) +{ + /* The packet header should be valid */ + pckt[OFFSET_DATA_FIELD_TC_TM] &= ~(ACK_MASK); + pckt[OFFSET_DATA_FIELD_TC_TM] |= (accept << ACK_A_SHIFT); + pckt[OFFSET_DATA_FIELD_TC_TM] |= (start << ACK_SE_SHIFT); + pckt[OFFSET_DATA_FIELD_TC_TM] |= (progress << ACK_PE_SHIFT); + pckt[OFFSET_DATA_FIELD_TC_TM] |= (term << ACK_CE_SHIFT); + return; +} + +CrFwBool_t CrFwPcktIsAcceptAck(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_DATA_FIELD_TC_TM] & ACK_A_MASK) >> ACK_A_SHIFT); +} + +CrFwBool_t CrFwPcktIsStartAck(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_DATA_FIELD_TC_TM] & ACK_SE_MASK) >> ACK_SE_SHIFT); +} + +CrFwBool_t CrFwPcktIsProgressAck(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_DATA_FIELD_TC_TM] & ACK_PE_MASK) >> ACK_PE_SHIFT); +} + +CrFwBool_t CrFwPcktIsTermAck(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_DATA_FIELD_TC_TM] & ACK_CE_MASK) >> ACK_CE_SHIFT); +} + +char* CrFwPcktGetParStart(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + return &pckt[OFFSET_SRC_DATA_CMD]; + } + return &pckt[OFFSET_SRC_DATA_REP]; +} + +CrFwPcktLength_t CrFwPcktGetParLength(CrFwPckt_t pckt) +{ + if (CrFwPcktGetCmdRepType(pckt) == crCmdType) + { + return (CrFwPcktGetLength(pckt)-OFFSET_PAR_LENGTH_TC); + } + return (CrFwPcktGetLength(pckt)-OFFSET_PAR_LENGTH_TM); +} + +void CrIaPcktSetVersion(CrFwPckt_t pckt, CrIaPcktVersion_t version) +{ + /* The packet header should be valid */ + pckt[OFFSET_ID_FIELD] &= ~(VERSION_MASK); + pckt[OFFSET_ID_FIELD] |= ((version << VERSION_SHIFT) & VERSION_MASK); + return; +} + +CrIaPcktVersion_t CrIaPcktGetVersion(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_ID_FIELD] & VERSION_MASK) >> VERSION_SHIFT); +} + +void CrIaPcktSetDataFieldFlag(CrFwPckt_t pckt, CrFwBool_t flag) +{ + /* The packet header should be valid */ + pckt[OFFSET_ID_FIELD] &= ~(HDR_FLAG_MASK); + if (flag) + { + pckt[OFFSET_ID_FIELD] |= (1 << HDR_FLAG_SHIFT); + } + return; +} + +CrFwBool_t CrIaPcktGetDataFieldFlag(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_ID_FIELD] & HDR_FLAG_MASK) >> HDR_FLAG_SHIFT); +} + +void CrIaPcktSetSeqFlags(CrFwPckt_t pckt, CrIaPcktSeqFlags_t flags) +{ + /* The packet header should be valid */ + pckt[OFFSET_SEQ_CTRL_FIELD] &= ~(SEQ_FLAGS_MASK); + pckt[OFFSET_SEQ_CTRL_FIELD] |= ((flags << SEQ_FLAGS_SHIFT) & SEQ_FLAGS_MASK); + return; +} + +CrIaPcktSeqFlags_t CrIaPcktGetSeqFlags(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_SEQ_CTRL_FIELD] & SEQ_FLAGS_MASK) >> SEQ_FLAGS_SHIFT); +} + +void CrIaPcktSetPusVersion(CrFwPckt_t pckt, CrIaPcktVersion_t ver) +{ + /* The packet header should be valid */ + pckt[OFFSET_DATA_FIELD_TC_TM] &= ~(PUS_VER_MASK); + pckt[OFFSET_DATA_FIELD_TC_TM] |= ((ver << PUS_VER_SHIFT) & PUS_VER_MASK); + return; +} + +CrIaPcktVersion_t CrIaPcktGetPusVersion(CrFwPckt_t pckt) +{ + /* The packet header should be valid */ + return ((pckt[OFFSET_DATA_FIELD_TC_TM] & PUS_VER_MASK) >> PUS_VER_SHIFT); +} + +void CrIaPcktSetCrc(CrFwPckt_t pckt, CrIaPcktCrc_t crc) +{ + /* No endian conversion for crc */ + size_t pos; + DEBUGP("SetCrc: Length is: %d\n", CrFwPcktGetLength(pckt)); + pos = CrFwPcktGetLength(pckt) - sizeof(CrIaPcktCrc_t); + DEBUGP("SetCrc: Position is: %lu\n", (unsigned long) pos); + + crc = (crc << 8) | ((crc >> 8) & 0xff); + /* The packet header should be valid */ + memcpy(&pckt[pos], &crc, sizeof(CrIaPcktCrc_t)); + + return; +} + +CrIaPcktCrc_t CrIaPcktGetCrc(CrFwPckt_t pckt) +{ + /* No endian conversion for crc */ + CrIaPcktCrc_t crc; + size_t pos; + + DEBUGP("this packet length is: %d\n", CrFwPcktGetLength(pckt)); + DEBUGP("crc datatype length is: %d\n", sizeof(CrIaPcktCrc_t)); + + pos = CrFwPcktGetLength(pckt) - sizeof(CrIaPcktCrc_t); + /* The packet header should be valid */ + memcpy(&crc, &pckt[pos], sizeof(CrIaPcktCrc_t)); + + return crc; +} + +CrIaPcktCrc_t Crc(unsigned char d, CrIaPcktCrc_t chk, CrIaPcktCrc_t table[]) +{ + return (((chk << 8) & 0xFF00)^table[(((chk >> 8)^d) & 0x00FF)]); +} + +void InitLtbl(CrIaPcktCrc_t table[]) +{ + CrIaPcktCrc_t i, tmp; + + for (i=0; i<256; i++) + { + tmp=0; + if ((i & 1) != 0) tmp=tmp ^ 0x1021; + if ((i & 2) != 0) tmp=tmp ^ 0x2042; + if ((i & 4) != 0) tmp=tmp ^ 0x4084; + if ((i & 8) != 0) tmp=tmp ^ 0x8108; + if ((i & 16) != 0) tmp=tmp ^ 0x1231; + if ((i & 32) != 0) tmp=tmp ^ 0x2462; + if ((i & 64) != 0) tmp=tmp ^ 0x48C4; + if ((i & 128) != 0) tmp=tmp ^ 0x9188; + table [i] = tmp; + } + + return; +} + diff --git a/CrIa/src/CrIaPckt.h b/CrIa/src/CrIaPckt.h new file mode 100644 index 0000000000000000000000000000000000000000..97b42756f9a8240d3fa4c06b6276d63bc06754c6 --- /dev/null +++ b/CrIa/src/CrIaPckt.h @@ -0,0 +1,287 @@ +/** + * @file CrIaPckt.h + * @ingroup CrIaDemo + * + * IASW specific packet manipulation functions. + * + * @authors V. Cechticky and A. Pasetti + * @copyright P&P Software GmbH, 2014 + */ + +#ifndef CRIA_PCKT_H +#define CRIA_PCKT_H + +/* Includes */ +#include "CrIaDataPool.h" +#include <CrFwConstants.h> +#include "Services/General/CrIaConstants.h" + +/** Offset for the parameter length */ +/** +#define OFFSET_PAR_LENGTH_TC 10 +#define OFFSET_PAR_LENGTH_TM 16 +*/ + +/** + * The size of a small packet in bytes. + */ +#define CR_IA_MAX_SIZE_PCKT_SMALL 128 /* section 6.6 of issue 5 of DD-001 */ + +/** + * The size of a large packets in bytes. This is the maximum size of a TM/TC + * packet. + */ +#define CR_IA_MAX_SIZE_PCKT_LARGE 1024 /* section 6.6 of issue 5 of DD-001 */ + +/** + * The number of pre-allocated small packets. + */ +#define CR_IA_NOF_PCKT_SMALL N_PCKT_SMALL + +/** + * The number of pre-allocated large packets. + */ +#define CR_IA_NOF_PCKT_LARGE N_PCKT_LARGE + +/** Offset of the packet id field. */ +#define OFFSET_ID_FIELD 0 + +/** Offset of the packet sequence control field. */ +#define OFFSET_SEQ_CTRL_FIELD 2 + +/** Offset of the length field. */ +#define OFFSET_LENGTH_FIELD 4 + +/** Offset of the data field for TC/TM */ +#define OFFSET_DATA_FIELD_TC_TM 6 + +/** Offset of the application data for commands. */ +#define OFFSET_SRC_DATA_CMD 11 + +/** Offset of the application data for reports. */ +#define OFFSET_SRC_DATA_REP 17 + +/** Offset for the parameter length */ +#define OFFSET_PAR_LENGTH_TC 10 +#define OFFSET_PAR_LENGTH_TM 16 + +/** Length of the packet without the packet data field */ +#define SRC_PCKT_HDR_LENGTH 6 + +/** Defines for the version number within the packet id field */ +#define VERSION_MASK 0xE0 +#define VERSION_SHIFT 5 +/** Defines for the packet type within the packet id field */ +#define PCKT_TYPE_MASK 0x10 +#define PCKT_TYPE_SHIFT 4 +/** Defines for the data field header flag within the packet id field */ +#define HDR_FLAG_MASK 0x08 +#define HDR_FLAG_SHIFT 3 +/** Defines for the APID (application process id) */ +#define PID0_MASK 0x07 +#define PID1_MASK 0xF0 +#define PID1_SHIFT 4 +#define PCAT_MASK 0x0F +#define PCAT_OFFSET 1 + +/** Mask of the sequence flags within the packet sequence control field. */ +#define SEQ_FLAGS_MASK 0xC0 +#define SEQ_FLAGS_SHIFT 6 +/** Mask of the sequence count within the packet sequence control field. */ +#define SEQ_COUNT_MASK 0x3FFF + +/** Mask of the CCSDS secondary header flag within the data field header. */ +#define CCSDS_MASK 0x80 +#define CCSDS_SHIFT 7 +/** Mask of the PUS version within the data field header. */ +#define PUS_VER_MASK 0x70 +#define PUS_VER_SHIFT 4 +/** Mask for all acknolegde flags in a TC */ +#define ACK_MASK 0x0F +/** Mask of the ack flag A (acceptance) within the data field header. */ +#define ACK_A_MASK 0x01 +#define ACK_A_SHIFT 0 +/** Mask of the ack flag SE (start execution) within the data field header. */ +#define ACK_SE_MASK 0x02 +#define ACK_SE_SHIFT 1 +/** Mask of the ack flag PE (progress execution) within the data field header. */ +#define ACK_PE_MASK 0x04 +#define ACK_PE_SHIFT 2 +/** Mask of the ack flag CE (completion execution) within the data field header. */ +#define ACK_CE_MASK 0x08 +#define ACK_CE_SHIFT 3 +/** Offset of the service type in the data field header */ +#define SRV_TYPE_OFFSET 1 +/** Offset of the service subtype in the data field header */ +#define SRV_SUBTYPE_OFFSET 2 +/** Offset of the source id (in TC) and destination id (TM) in the data field header */ +#define SRC_DEST_OFFSET 3 +/** Offset of the SC Time field in the data field header */ +#define SC_TIME_OFFSET 4 + + +CrFwDestSrc_t CrIaPcktGetPid(CrFwPckt_t pckt); + +void CrIaPcktSetPid(CrFwPckt_t pckt, CrFwDestSrc_t pid); + +unsigned short CrIaPcktGetApid(CrFwPckt_t pckt); + +unsigned short CrIaPcktGetPacketId(CrFwPckt_t pckt); + +CrFwGroup_t CrIaPcktGetPcat(CrFwPckt_t pckt); + +void CrIaPcktSetPcat(CrFwPckt_t pckt, CrFwGroup_t pcat); + +CrFwPckt_t CrFwPcktMake(CrFwPcktLength_t pcktLength); + +void CrFwPcktRelease(CrFwPckt_t pckt); + +CrFwCounterU2_t CrFwPcktGetNOfAllocated(); + +CrFwPcktLength_t CrFwPcktGetMaxLength(); + +CrFwCmdRepType_t CrFwPcktGetCmdRepType(CrFwPckt_t pckt); + +void CrFwPcktSetCmdRepType(CrFwPckt_t pckt, CrFwCmdRepType_t type); + +CrFwPcktLength_t CrFwPcktGetLength(CrFwPckt_t pckt); + +CrFwSeqCnt_t CrFwPcktGetSeqCtrl(CrFwPckt_t pckt); + +void CrFwPcktSetSeqCnt(CrFwPckt_t pckt, CrFwSeqCnt_t seqCnt); + +CrFwSeqCnt_t CrFwPcktGetSeqCnt(CrFwPckt_t pckt); + +void CrFwPcktSetServType(CrFwPckt_t pckt, CrFwServType_t servType); + +CrFwServType_t CrFwPcktGetServType(CrFwPckt_t pckt); + +void CrFwPcktSetServSubType(CrFwPckt_t pckt, CrFwServSubType_t servSubType); + +CrFwServSubType_t CrFwPcktGetServSubType(CrFwPckt_t pckt); + +void CrFwPcktSetDiscriminant(CrFwPckt_t pckt, CrFwDiscriminant_t discriminant); + +CrFwTimeStamp_t CrFwPcktGetTimeStamp(CrFwPckt_t pckt); + +void CrFwPcktSetTimeStamp(CrFwPckt_t pckt, CrFwTimeStamp_t timeStamp); + +CrFwGroup_t CrIaPcktGetGroup(CrFwPckt_t pckt); + +void CrFwPcktSetGroup(CrFwPckt_t pckt, CrFwGroup_t group); + +void CrFwPcktSetDest(CrFwPckt_t pckt, CrFwDestSrc_t dest); + +CrFwDestSrc_t CrFwPcktGetDest(CrFwPckt_t pckt) ; + +void CrFwPcktSetSrc(CrFwPckt_t pckt, CrFwDestSrc_t src); + +CrFwDestSrc_t CrFwPcktGetSrc(CrFwPckt_t pckt); + +void CrFwPcktSetCmdRepId(CrFwPckt_t pckt, CrFwInstanceId_t id); + +CrFwInstanceId_t CrFwPcktGetCmdRepId(CrFwPckt_t pckt); + +void CrFwPcktSetAckLevel(CrFwPckt_t pckt, CrFwBool_t accept, CrFwBool_t start, CrFwBool_t progress, CrFwBool_t term); + +CrFwBool_t CrFwPcktIsAcceptAck(CrFwPckt_t pckt); + +CrFwBool_t CrFwPcktIsStartAck(CrFwPckt_t pckt); + +CrFwBool_t CrFwPcktIsProgressAck(CrFwPckt_t pckt); + +CrFwBool_t CrFwPcktIsTermAck(CrFwPckt_t pckt); + +char* CrFwPcktGetParStart(CrFwPckt_t pckt); + +CrFwPcktLength_t CrFwPcktGetParLength(CrFwPckt_t pckt); + +/** + * Set the version number of a TM/TC packet. + */ +void CrIaPcktSetVersion(CrFwPckt_t pckt, CrIaPcktVersion_t version); + +/** + * Return the version number of a TM/TC packet. + */ +CrIaPcktVersion_t CrIaPcktGetVersion(CrFwPckt_t pckt); + +/** + * Set the data field header flag of a TM/TC packet. + */ +void CrIaPcktSetDataFieldFlag(CrFwPckt_t pckt, CrFwBool_t flag); + +/** + * Return the data field header flag of a TM/TC packet. + */ +CrFwBool_t CrIaPcktGetDataFieldFlag(CrFwPckt_t pckt); + +/** + * Set the sequence flags of a TC packet. + */ +void CrIaPcktSetSeqFlags(CrFwPckt_t pckt, CrIaPcktSeqFlags_t flags); + +/** + * Return the sequence flags of a TC packet. + */ +CrIaPcktSeqFlags_t CrIaPcktGetSeqFlags(CrFwPckt_t pckt); + +/** + * Set the CCSDS Secondary Header Flag in a TM. + */ +void CrIaPcktSetCCSDSFlag(CrFwPckt_t pckt, CrFwBool_t flag); + +/** + * Return the CCSDS Secondary Header Flag in a TM. + */ +CrFwBool_t CrIaPcktGetCCSDSFlag(CrFwPckt_t pckt); + +/** + * Set the PUS version number of a TC/TM packet. + */ +void CrIaPcktSetPusVersion(CrFwPckt_t pckt, CrIaPcktVersion_t ver); + +/** + * Return the PUS version number of a TC/TM packet. + */ +CrIaPcktVersion_t CrIaPcktGetPusVersion(CrFwPckt_t pckt); + +/** + * Return the Discriminant of a type specific TC/TM packet. + */ +CrFwDiscriminant_t CrFwPcktGetDiscriminant(CrFwPckt_t pckt); + +/** + * Set the CRC for the TC/TM packet. + */ +void CrIaPcktSetCrc(CrFwPckt_t pckt, CrIaPcktCrc_t crc); + +/** + * Return the CRC for the TC/TM packet. + */ +CrIaPcktCrc_t CrIaPcktGetCrc(CrFwPckt_t pckt); + +/** + * Calculates the CRC (Cyclic Redundancy Code) for d. + * + * This is the optimized implementation taken from the ECSS-E-70-41A document. + * The name in the document for this routine is @Crc_opt@, but is renamed here + * since it is the only CRC routine present. + * + * According to the specification, the syndrome must be set to all ones before + * the check. + * + * \param d Byte to be encoded + * \param chk Syndrome + * \param table Look-up table + */ +CrIaPcktCrc_t Crc(unsigned char d, CrIaPcktCrc_t chk, CrIaPcktCrc_t table[]); + +/** + * Initializes the Look-up table used for the Crc calculation. + */ +void InitLtbl(CrIaPcktCrc_t table[]); + +#endif /* CRIA_PCKT_H */ + + diff --git a/CrIa/src/CrIaPrSm/CrIaAcqFullDropCreate.c b/CrIa/src/CrIaPrSm/CrIaAcqFullDropCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..0520afbd483a03e78ef0a9fd260e78158d90c077 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAcqFullDropCreate.c @@ -0,0 +1,138 @@ +/** + * @file CrIaAcqFullDropCreate.c + * @ingroup CrIaPrSci + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Jun 3 2016 19:48:4 + * + * @brief Instanziation of the Acquire Full Drop Procedure. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include "CrIaAcqFullDropCreate.h" + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaAcqFullDrop function definitions */ +#include <stdlib.h> + +/** + * Action for node N7. + * NOP + * @param smDesc the procedure descriptor + */ +static void code15066(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** + * Action for node N9. + * NOP + * @param smDesc the procedure descriptor + */ +static void code91534(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** + * Guard on the Control Flow from DECISION8 to N9. + * <pre> + * Target acquisition + * not yet completed + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code60575(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from N6 to N7. + * Wait 1 Cycle + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code47070(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return (FwPrGetNodeExecCnt(prDesc) == 1); +} + +/** + * Guard on the Control Flow from N9 to N7. + * Wait 1 Cycle + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code53764(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return (FwPrGetNodeExecCnt(prDesc) == 1); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaAcqFullDropCreate(void* prData) +{ + const FwPrCounterU2_t DECISION8 = 1; /* The identifier of decision node DECISION8 in procedure CrIaAcqFullDrop */ + const FwPrCounterU2_t N_OUT_OF_DECISION8 = 3; /* The number of control flows out of decision node DECISION8 in procedure CrIaAcqFullDrop */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 14, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 18, /* N_FLOWS - The number of control flows */ + 14, /* N_ACTIONS - The number of actions */ + 10 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N4, &CrIaAcqFullDropN4); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N5, &CrIaAcqFullDropN5); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N1, &CrIaAcqFullDropN1); + FwPrAddDecisionNode(prDesc, DECISION8, N_OUT_OF_DECISION8); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N10, &CrIaAcqFullDropN10); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N6, &CrIaAcqFullDropN6); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N8, &CrIaAcqFullDropN8); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N7, &code15066); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N9, &code91534); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N12, &CrIaAcqFullDropN12); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N11, &CrIaAcqFullDropN11); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N2, &CrIaAcqFullDropN2); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N3, &CrIaAcqFullDropN3); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N2_1, &CrIaAcqFullDropN2_1); + FwPrAddActionNode(prDesc, CrIaAcqFullDrop_N13, &CrIaAcqFullDropN13); + FwPrAddFlowIniToAct(prDesc, CrIaAcqFullDrop_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N4, CrIaAcqFullDrop_N5, &CrIaAcqFullDropWaitT2); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N5, CrIaAcqFullDrop_N6, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N1, CrIaAcqFullDrop_N2, &CrIaAcqFullDropIsSemInStab); + FwPrAddFlowDecToAct(prDesc, DECISION8, CrIaAcqFullDrop_N10, &CrIaAcqFullDropIsTrgtAcq); + FwPrAddFlowDecToAct(prDesc, DECISION8, CrIaAcqFullDrop_N13, &CrIaAcqFullDropIsTrgtNotAcq); + FwPrAddFlowDecToAct(prDesc, DECISION8, CrIaAcqFullDrop_N9, &code60575); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N10, CrIaAcqFullDrop_N11, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N6, CrIaAcqFullDrop_N7, &code47070); + FwPrAddFlowActToDec(prDesc, CrIaAcqFullDrop_N8, DECISION8, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N7, CrIaAcqFullDrop_N8, &CrIaAcqFullDropIsImgAcq); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N9, CrIaAcqFullDrop_N7, &code53764); + FwPrAddFlowActToFin(prDesc, CrIaAcqFullDrop_N12, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N11, CrIaAcqFullDrop_N12, &CrIaAcqFullDropIsTerm); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N2, CrIaAcqFullDrop_N2_1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N3, CrIaAcqFullDrop_N4, &CrIaAcqFullDropWaitT1); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N2_1, CrIaAcqFullDrop_N3, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcqFullDrop_N13, CrIaAcqFullDrop_N10, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaAcqFullDropCreate.h b/CrIa/src/CrIaPrSm/CrIaAcqFullDropCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..f910accb847d007bc407e4769392c231ada1a540 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAcqFullDropCreate.h @@ -0,0 +1,234 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaAcqFullDrop procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaAcqFullDrop.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:4 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaAcqFullDropCreate_H_ +#define CrIaAcqFullDropCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaAcqFullDrop_N1 (1) /* The identifier of action node N1 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N2 (2) /* The identifier of action node N2 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N2_1 (3) /* The identifier of action node N2_1 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N3 (4) /* The identifier of action node N3 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N4 (5) /* The identifier of action node N4 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N5 (6) /* The identifier of action node N5 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N6 (7) /* The identifier of action node N6 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N7 (8) /* The identifier of action node N7 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N8 (9) /* The identifier of action node N8 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N9 (10) /* The identifier of action node N9 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N10 (11) /* The identifier of action node N10 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N11 (12) /* The identifier of action node N11 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N12 (13) /* The identifier of action node N12 in procedure CrIaAcqFullDrop */ +#define CrIaAcqFullDrop_N13 (14) /* The identifier of action node N13 in procedure CrIaAcqFullDrop */ + +/** User-defined includes */ +#include "FwProfile/FwPrCore.h" + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaAcqFullDropCreate(void* prData); + +/** + * Action for node N4. + * Send cmd (220,11) to SEM + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN4(FwPrDesc_t prDesc); + +/** + * Action for node N5. + * <pre> + * Send command GoToCcdFull + * to SEM Unit State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN5(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * <pre> + * Generate Event Report + * EVT_SC_PR_STRT + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN1(FwPrDesc_t prDesc); + +/** + * Action for node N10. + * Stop Acquisition Algorithms + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN10(FwPrDesc_t prDesc); + +/** + * Action for node N6. + * Start Acquisition Algorithms + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN6(FwPrDesc_t prDesc); + +/** + * Action for node N8. + * <pre> + * Evaluate Pointing Error on data in SIB + * pointed at by sibOut and then increment sibOut + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN8(FwPrDesc_t prDesc); + +/** + * Action for node N12. + * <pre> + * Generate Event Report + * EVT_SC_PR_END with + * outcome equal to: "success" + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN12(FwPrDesc_t prDesc); + +/** + * Action for node N11. + * <pre> + * Send command GoToStabilize + * to SEM Unit State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN11(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Update SEM configuration + * parameters in data pool + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * Send cmd (220,3) to SEM + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN3(FwPrDesc_t prDesc); + +/** + * Action for node N2_1. + * <pre> + * Set data pool variable + * pCcdRdMode to CCD_FULL + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN2_1(FwPrDesc_t prDesc); + +/** + * Action for node N13. + * <pre> + * Load event + * EVT_ACQ_FAIL + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaAcqFullDropN13(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N4 to N5. + * <pre> + * Wait acqFullDropT2 + * cycles + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaAcqFullDropWaitT2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N1 to N2. + * SEM State Machine is in STABILIZE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaAcqFullDropIsSemInStab(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION8 to N10. + * <pre> + * Target acquisition + * successfully completed + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaAcqFullDropIsTrgtAcq(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION8 to N13. + * <pre> + * Target acquisition + * completed unsuccessfully + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaAcqFullDropIsTrgtNotAcq(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N7 to N8. + * Acquisition of an image has completed + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaAcqFullDropIsImgAcq(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N11 to N12. + * <pre> + * (SEM Operational SM is in STABILIZE) && + * (All sporadic activities have terminated) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaAcqFullDropIsTerm(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N3 to N4. + * <pre> + * Wait acqFullDropT1 + * cycles + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaAcqFullDropWaitT1(FwPrDesc_t prDesc); + +#endif /* CrIaAcqFullDropCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaAcqFullDropFunc.c b/CrIa/src/CrIaPrSm/CrIaAcqFullDropFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..872d5f7d5ac0860906a6b358987f4092aa186180 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAcqFullDropFunc.c @@ -0,0 +1,442 @@ +/** + * @file CrIaAcqFullDropFunc.c + * @ingroup CrIaPrSci + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Jun 3 2016 19:48:4 + * + * @brief Implementation of the Acquire Full Drop Procedure nodes and guards. + * Implements an observation of type ACQ/FULL/DROP. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +#include <FwProfile/FwPrCore.h> /* for FwPrGetCurNode() */ + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> + +#/** CrIaAcqFullDrop function definitions */ +#include "CrIaAcqFullDropCreate.h" + +#include <CrIaIasw.h> /* for Event Reporting and extern sm and prDescriptors */ +#include <CrIaPrSm/CrIaSemCreate.h> /* for GoToCcdWindow and GoToStabilize */ +#include <CrIaPrSm/CrIaAlgoCreate.h> /* for Start and Stop */ + +#include <IfswDebug.h> + +#include "EngineeringAlgorithms.h" + + +int nmbIter; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaAcqFullDropN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_ACQ_FULL_DROP; + + /* Generate event report EVT_SC_PR_STRT */ + + evt_data[0] = ProcId; + evt_data[1] = 0; /* NOT USED */ + + DEBUGP("AcqFullDrop N1: Event %d generated to signal start of ACQ FULL DROP PR\n", ProcId); + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_STRT, evt_data, 4); + + return; +} + +/** Action for node N2. */ +void CrIaAcqFullDropN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int utemp32; + unsigned short utemp16; + + /* Update SEM configuration parameters in data pool */ + + /* needed for TC(220/3) CMD_Operation_Parameter */ + + CrIaCopy(ACQFULLDROP_PEXPTIME_ID, &utemp32); + CrIaPaste(PEXPTIME_ID, &utemp32); + + CrIaCopy(ACQFULLDROP_PIMAGEREP_ID, &utemp32); + CrIaPaste(PIMAGEREP_ID, &utemp32); + + /* get Target Acquisition Iterations from data pool and set pAcqNum, assuming that a star map command was sent before (default is 10) */ + CrIaCopy(TAITERATIONS_ID, &utemp16); + utemp16 += 1; + utemp32 = (unsigned int)utemp16; + CrIaPaste(PACQNUM_ID, &utemp32); + + /* Mantis 2252 */ + nmbIter = 0; + + /* pDatOs keeps the default value */ + + /* pCcdRdMode is set in N2_1 */ + + return; +} + +/** Action for node N2_1. */ +void CrIaAcqFullDropN2_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short utemp16; + + /* Set data pool variable pCcdRdMode to CCD_FULL */ + + /* CCD readout mode */ + utemp16 = SEM_CCD_MODE_CCD_FULL; + CrIaPaste(PCCDRDMODE_ID, &utemp16); + + return; +} + +/** Action for node N3. */ +void CrIaAcqFullDropN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* Send cmd (220,3) to SEM */ + /* Changes the SEM Operational Parameter */ + + DEBUGP("SciWin N3: Send cmd (220,3) to SEM\n"); + + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV220, CRSEM_SERV220_CMD_OPER_PARAM, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* NOTE: parameters are set in the cmd update action according to the data pool entries */ + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/** Action for node N4. */ +void CrIaAcqFullDropN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* Send cmd (220,11) to SEM */ + /* Changes the SEM Functional Parameter */ + + DEBUGP("SciWin N4: Send cmd (220,11) to SEM\n"); + + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV220, CRSEM_SERV220_CMD_FUNCT_PARAM, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* NOTE: parameters are set in the cmd update action according to the data pool entries */ + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/** Action for node N5. */ +void CrIaAcqFullDropN5(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send command GoToCcdFull to SEM Unit State Machine */ + FwSmMakeTrans(smDescSem, GoToCcdFull); + + return; +} + +/** Action for node N6. */ +void CrIaAcqFullDropN6(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Start Acquisition Algorithms */ + + FwSmMakeTrans(smDescAlgoAcq1, Start); + + return; +} + +/** Action for node N8. */ +void CrIaAcqFullDropN8(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sibIn, sibOut; + + /* NOTE: The Pointing Error is evaluated in the guard */ + + /* + Mantis 1624 says increment SIBOUT, but Mantis 1779 overrules this. + Basically, sibout is not used for the acquisition, but we want to + use it to have some visibility. We set it to sibin here. + */ + + CrIaCopy(SIBIN_ID, &sibIn); + sibOut = sibIn; + CrIaPaste(SIBOUT_ID, &sibOut); + + return; +} + +/** Action for node N10. */ +void CrIaAcqFullDropN10(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Stop Acquisition Algorithms */ + + FwSmMakeTrans(smDescAlgoAcq1, Stop); + + return; +} + +/** Action for node N11. */ +void CrIaAcqFullDropN11(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send command GoToStabilize to SEM Unit State Machine */ + + FwSmMakeTrans(smDescSem, GoToStabilize); + + return; +} + +/** Action for node N12. */ +void CrIaAcqFullDropN12(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_ACQ_FULL_DROP; + + /* Generate event report EVT_SC_PR_END with outcome "success" */ + + evt_data[0] = ProcId; + evt_data[1] = 1; /* 1 = success */ + + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_END, evt_data, 4); + + return; +} + +/** Action for node N13. */ +void CrIaAcqFullDropN13(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + + /* Load Event EVT_ACQ_FAIL */ + + /* NOTE: this has no parameters, so we don't need to + collect the Target Acquisition Iterations from the data pool */ + + evt_data[0] = 0; /* not used */ + evt_data[1] = 0; /* not used */ + + CrIaEvtRep(3, CRIA_SERV5_EVT_ACQ_FAIL, evt_data, 4); + + return; +} + +/**************/ +/*** GUARDS ***/ +/**************/ + +/** Guard on the Control Flow from N1 to N2. */ +FwPrBool_t CrIaAcqFullDropIsSemInStab(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state; + + /* [ SEM State Machine is in STABILIZE ] */ + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if (sem_oper_state == CrIaSem_STABILIZE) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from N3 to N4. */ +FwPrBool_t CrIaAcqFullDropWaitT1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int acqFullDropT1; + + CrIaCopy(ACQFULLDROPT1_ID, &acqFullDropT1); + + /* Wait sciWinStackT1 cycles */ + if (FwPrGetNodeExecCnt(prDesc) < acqFullDropT1) + { + return 0; + } + else + { + return 1; + } +} + +/** Guard on the Control Flow from N4 to N5. */ +FwPrBool_t CrIaAcqFullDropWaitT2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int acqFullDropT2; + + CrIaCopy(ACQFULLDROPT2_ID, &acqFullDropT2); + + /* Wait sciWinStackT1 cycles */ + if (FwPrGetNodeExecCnt(prDesc) < acqFullDropT2) + { + return 0; + } + else + { + return 1; + } +} + +/** Guard on the Control Flow from N5 to N6/N7 to N8. */ +FwPrBool_t CrIaAcqFullDropIsImgAcq(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int acqImageCnt, imageCycleCnt; + + CrIaCopy(ACQIMAGECNT_ID, &acqImageCnt); + CrIaCopy(IMAGECYCLECNT_ID, &imageCycleCnt); + + if ((acqImageCnt > 0) && (imageCycleCnt==1)) /* first rep of non-first frame */ + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION8 to N10. */ +FwPrBool_t CrIaAcqFullDropIsTrgtAcq(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* NOTE: TRGSTRPOSERRTHD_ID is redundant with TADISTANCETHRD */ + /* NOTE: TRGSTRPOSERRDUR_ID is not used; we use TAITERATIONS instead */ + + unsigned short taDistanceThrd; + int CentOffsetX, CentOffsetY; + double CentOffsetSq, DistSq; + unsigned char validityStatus; + + /* [ Target acquisition successfully completed / Target star acquired ] */ + + /* get Target Acquisition Distance Threshold from data pool */ + CrIaCopy(TADISTANCETHRD_ID, &taDistanceThrd); + DistSq = (double)taDistanceThrd * (double)taDistanceThrd; + + CrIaCopy (OFFSETX_ID, &CentOffsetX); + CrIaCopy (OFFSETY_ID, &CentOffsetY); + + CentOffsetSq = ((double)CentOffsetX * (double)CentOffsetX + (double)CentOffsetY * (double)CentOffsetY)/10000.0f; /* incl. conversion centi-pixel to pixel */ + + CrIaCopy(VALIDITYSTATUS_ID, &validityStatus); + + if (validityStatus != CEN_VAL_FULL) + { + /* invalid -> retry */ + return 0; + } + + if (DistSq > CentOffsetSq) + { + /* Acquisition Successful */ + return 1; + } + else + { + /* too far away -> retry */ + return 0; + } + +} + + +/** Guard on the Control Flow from DECISION8 to N13. */ +FwPrBool_t CrIaAcqFullDropIsTrgtNotAcq(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short taIterations; + + /* [ Target acquisition completely unsuccessfully ] */ + + /* get Target Acquisition Iterations from data pool */ + CrIaCopy(TAITERATIONS_ID, &taIterations); + + /* If iterations = n, we want n+1 images (1 image + n iterations). + In N2 we request N+1 images, but the check here happens AFTER the first image has been + processed, so in the end we have to adjust nmbIter by adding 1 in the comparison beneath */ + if (nmbIter + 1 < taIterations) + { + nmbIter++; + return 0; + } + else + { + nmbIter = 0; + return 1; + } + +} + +/** Guard on the Control Flow from N11 to N12. */ +FwPrBool_t CrIaAcqFullDropIsTerm(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state, Cpu2ProcStatus; + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + /* get state of second CPU */ + CrIaCopy(CPU2PROCSTATUS_ID, &Cpu2ProcStatus); + + DEBUGP("N11->N12: %d %d\n", sem_oper_state, Cpu2ProcStatus); + + if (sem_oper_state == CrIaSem_STABILIZE) /* SEM Operational SM is in STABILIZE */ + { + if (Cpu2ProcStatus == SDP_STATUS_IDLE) /* All sporadic activities have terminated */ + { + return 1; + } + } + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaAcqFullDropInit.txt b/CrIa/src/CrIaPrSm/CrIaAcqFullDropInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..b07786d9b880be675c8b5626fda5f8a5b24edadd --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAcqFullDropInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaAcqFullDropCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaAcqFullDrop is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaAcqFullDrop is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecCreate.c b/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..73573bf4ce137d87d60072bf79ca31c0e329ee70 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecCreate.c @@ -0,0 +1,39 @@ +/** + * @file CrIaAcquAlgoExecCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Sep 21 2016 11:3:44 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaAcquAlgoExec function definitions */ +#include "CrIaAcquAlgoExecCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaAcquAlgoExecCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 2, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 3, /* N_FLOWS - The number of control flows */ + 2, /* N_ACTIONS - The number of actions */ + 1 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaAcquAlgoExec_N1, &CrIaAcquAlgoExecN1); + FwPrAddActionNode(prDesc, CrIaAcquAlgoExec_N2, &CrIaAcquAlgoExecN2); + FwPrAddFlowIniToAct(prDesc, CrIaAcquAlgoExec_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaAcquAlgoExec_N1, CrIaAcquAlgoExec_N2, &CrIaAcquAlgoExecGuard); + FwPrAddFlowActToFin(prDesc, CrIaAcquAlgoExec_N2, NULL); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecCreate.h b/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..fb98c6a608237c8497fc03f140e4901a640930e8 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecCreate.h @@ -0,0 +1,48 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaAcquAlgoExec procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaAcquAlgoExec.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Sep 21 2016 11:3:44 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaAcquAlgoExecCreate_H_ +#define CrIaAcquAlgoExecCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaAcquAlgoExec_N1 1 /* The identifier of action node N1 in procedure CrIaAcquAlgoExec */ +#define CrIaAcquAlgoExec_N2 2 /* The identifier of action node N2 in procedure CrIaAcquAlgoExec */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaAcquAlgoExecCreate(void* prData); + +/** Action for node N1. */ +void CrIaAcquAlgoExecN1(FwPrDesc_t __attribute__((unused)) prDesc); + +/** Action for node N2. */ +void CrIaAcquAlgoExecN2(FwPrDesc_t __attribute__((unused)) prDesc); + +/** Guard on the Control Flow from N1 to N2. */ +FwPrBool_t CrIaAcquAlgoExecGuard(FwPrDesc_t __attribute__((unused)) prDesc); + +#endif /* CrIaAcquAlgoExecCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecFunc.c b/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..15201838d89f0c4cde2077d98326ad23398523a6 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAcquAlgoExecFunc.c @@ -0,0 +1,144 @@ +/** + * @file CrIaAcquAlgoExecFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Sep 21 2016 11:3:44 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +#include "FwProfile/FwSmCore.h" +#include "CrIaAlgoCreate.h" + +/** CrIaAcquAlgoExec function definitions */ +#include "CrIaAcquAlgoExecCreate.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "Services/General/CrIaConstants.h" +#include <IfswDebug.h> + +#include "CrIaIasw.h" /* cpu1_notification, signal_Ta */ + +#ifdef PC_TARGET +/*extern unsigned int requestAcquisition;*/ +extern unsigned int *ShmRequestAcquisitionPTR; /* shared memory for fork() */ +#else +#include "../IBSW/include/ibsw_interface.h" +#endif /* PC_TARGET */ +#include "../../ifsw.h" + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaAcquAlgoExecN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + PRDEBUGP("=== entered ACQAlgoExec\n"); + + /* In Revision 8 this is quasi N2 */ +#ifdef PC_TARGET + DEBUGP("CrIaAcquAlgoExecN1: SDP_STATUS_ACQUISITION = %d\n", cpu1_notification(SDP_STATUS_ACQUISITION)); + if (cpu1_notification(SDP_STATUS_ACQUISITION) == SDP_STATUS_IDLE) + { + DEBUGP("CrIaAcquAlgoExecN1: ... is SDP_STATUS_IDLE\n"); + } +#else + run_rt(RTCONT_ACQ, DEADLINE_ACQ, run_acquisition); +#endif + + return; +} + + +/** Action for node N2. [quasi N3 in Revision 8] */ +void CrIaAcquAlgoExecN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + struct SibCentroid *Centroid; + + int CentOffsetX, CentOffsetY; + unsigned short startIntegFine, endIntegFine, dataCadence; + unsigned int startIntegCoarse, endIntegCoarse; + unsigned char validityStatus; + + PRDEBUGP("=== copy TA results to data pool\n"); + + /* update data pool items + the output from the algorithm was written + back into the SibStruct Centroid section */ + +#ifdef PC_TARGET + Centroid = (struct SibCentroid *)(ShmOutgoingSibInPTR->Centroid); +#else + Centroid = (struct SibCentroid *)(outgoingSibInStruct.Centroid); +#endif + + /* load the report parameters from the data pool and feed into the packet */ + CentOffsetX = Centroid->offsetX; + CrIaPaste (OFFSETX_ID, &CentOffsetX); + + CentOffsetY = Centroid->offsetY; + CrIaPaste (OFFSETY_ID, &CentOffsetY); + + DEBUGP ("== copy from SIB to DP [%d, %d] ==\n", CentOffsetX, CentOffsetY); + + /* NOTE: target location is NOT copied back from the data pool */ + + startIntegCoarse = Centroid->startIntegCoarse; + CrIaPaste(INTEGSTARTTIMECRS_ID, &startIntegCoarse); + + startIntegFine = (unsigned short) (Centroid->startIntegFine); + CrIaPaste(INTEGSTARTTIMEFINE_ID, &startIntegFine); + + endIntegCoarse = Centroid->endIntegCoarse; + CrIaPaste(INTEGENDTIMECRS_ID, &endIntegCoarse); + + endIntegFine = (unsigned short) (Centroid->endIntegFine); + CrIaPaste(INTEGENDTIMEFINE_ID, &endIntegFine); + + dataCadence = (unsigned short) (Centroid->dataCadence); + CrIaPaste(DATACADENCE_ID, &dataCadence); + + validityStatus = (unsigned char) (Centroid->validityStatus); + CrIaPaste(VALIDITYSTATUS_ID, &validityStatus); + + signal_Ta ^= 1; /* toggle signal flag for CrIaServ196AocsRep */ + + return; +} + + +/** Guard on the Control Flow from N1 to N2. [in Rev 8 there would need to be a guard between N2 and N3] */ +FwPrBool_t CrIaAcquAlgoExecGuard(FwPrDesc_t __attribute__((unused)) prDesc) +{ +#ifdef PC_TARGET + unsigned short Cpu2ProcStatus; + + CrIaCopy(CPU2PROCSTATUS_ID, &Cpu2ProcStatus); + + PRDEBUGP("=== waiting to finish\n"); + DEBUGP("CrIaAcquAlgoExecGuard: Cpu2ProcStatus = %d\n", Cpu2ProcStatus); + + /* acquisition has finished */ + if (Cpu2ProcStatus == SDP_STATUS_IDLE) + { + DEBUGP("CrIaAcquAlgoExecGuard: ... is SDP_STATUS_IDLE\n"); + return 1; + } + + return 0; +#else + return 1; +#endif /* PC_TARGET */ +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaAlgoCreate.c b/CrIa/src/CrIaPrSm/CrIaAlgoCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..bac31ee281e42db824fe18c637c63440fa1d335c --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAlgoCreate.c @@ -0,0 +1,46 @@ +/** + * @file CrIaAlgoCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" + +/** CrIaAlgo function definitions */ +#include "CrIaAlgoCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t CrIaAlgoCreate(void* smData) +{ + const FwSmCounterU2_t N_OUT_OF_INACTIVE = 1; /* The number of transitions out of state INACTIVE */ + const FwSmCounterU2_t N_OUT_OF_SUSPENDED = 2; /* The number of transitions out of state SUSPENDED */ + const FwSmCounterU2_t N_OUT_OF_ACTIVE = 2; /* The number of transitions out of state ACTIVE */ + + /** Create state machine smDesc */ + FwSmDesc_t smDesc = FwSmCreate( + 3, /* NSTATES - The number of states */ + 0, /* NCPS - The number of choice pseudo-states */ + 6, /* NTRANS - The number of transitions */ + 3, /* NACTIONS - The number of state and transition actions */ + 1 /* NGUARDS - The number of transition guards */ + ); + + /** Configure the state machine smDesc */ + FwSmSetData(smDesc, smData); + FwSmAddState(smDesc, CrIaAlgo_INACTIVE, N_OUT_OF_INACTIVE, NULL, NULL, NULL, NULL); + FwSmAddState(smDesc, CrIaAlgo_SUSPENDED, N_OUT_OF_SUSPENDED, NULL, NULL, NULL, NULL); + FwSmAddState(smDesc, CrIaAlgo_ACTIVE, N_OUT_OF_ACTIVE, &CrIaAlgoInitialization, &CrIaAlgoFinalization, &CrIaAlgoActiveDoAction, NULL); + FwSmAddTransIpsToSta(smDesc, CrIaAlgo_INACTIVE, NULL); + FwSmAddTransStaToSta(smDesc, Start, CrIaAlgo_INACTIVE, CrIaAlgo_ACTIVE, NULL, &CrIaAlgoIsAlgoEnabled); + FwSmAddTransStaToSta(smDesc, Stop, CrIaAlgo_SUSPENDED, CrIaAlgo_INACTIVE, &CrIaAlgoFinalization, NULL); + FwSmAddTransStaToSta(smDesc, Resume, CrIaAlgo_SUSPENDED, CrIaAlgo_ACTIVE, NULL, NULL); + FwSmAddTransStaToSta(smDesc, Suspend, CrIaAlgo_ACTIVE, CrIaAlgo_SUSPENDED, NULL, NULL); + FwSmAddTransStaToSta(smDesc, Stop, CrIaAlgo_ACTIVE, CrIaAlgo_INACTIVE, NULL, NULL); + + return smDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaAlgoCreate.h b/CrIa/src/CrIaPrSm/CrIaAlgoCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..aaab32a51b49cc59d093f455b3098460321234f5 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAlgoCreate.h @@ -0,0 +1,101 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaAlgo state machine. + * The state machine is configured with a set of function pointers representing the non-default + * actions and guards of the state machine. Some of these functions may also be declared in + * this header file in accordance with the configuration of the state machine in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The state machine created by this file is shown in the figure below. + * + * <b>Note for state ACTIVE</b> + * The algorithm period and phase which are needed to + * evaluate Flag_1 are accessed through the pointers + * stored in the algorithm data structure. + * + * The state actions execute the functions implementing the + * algorithm Initialization Action, Execution Action and Finalization + * Action. The pointers to these functions are retrieved from + * the algorithm data structure. + * + * <b>Note for Transition from INACTIVE to ACTIVE</b> + * The function implementing the guard on this transition + * accesses the enable state of an algorithm through the + * pointer stored in the algorithm data structure. + * + * <b>Note for Transition from SUSPENDED to INACTIVE</b> + * The transition action executes the function which implements the + * Finalization Action for the algorithm. + * The pointer to this function is retrieved from the + * algorithm data structure. + * + * @image html CrIaAlgo.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaAlgoCreate_H_ +#define CrIaAlgoCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" + +/** State identifiers */ +#define CrIaAlgo_OFF 0 /* The identifier of state OFF in State Machine CrIaAlgo */ +#define CrIaAlgo_ACTIVE 1 /* The identifier of state ACTIVE in State Machine CrIaAlgo */ +#define CrIaAlgo_INACTIVE 2 /* The identifier of state INACTIVE in State Machine CrIaAlgo */ +#define CrIaAlgo_SUSPENDED 3 /* The identifier of state SUSPENDED in State Machine CrIaAlgo */ + +/** The identifiers of transition commands (triggers) */ +#define Stop 25 +#define Resume 26 +#define Suspend 27 +#define Start 28 + +/** + * Create a new state machine descriptor. + * This interface creates the state machine descriptor dynamically. + * @param smData the pointer to the state machine data. + * A value of NULL is legal (note that the default value of the pointer + * to the state machine data when the state machine is created is NULL). + * @return the pointer to the state machine descriptor + */ +FwSmDesc_t CrIaAlgoCreate(void* smData); + +/** + * Entry Action for the state ACTIVE. + * Initialization Action + * @param smDesc the state machine descriptor + */ +void CrIaAlgoInitialization(FwSmDesc_t smDesc); + +/** + * Do Action for the state ACTIVE. + * if (Flag_1) Execution Action + * @param smDesc the state machine descriptor + */ +void CrIaAlgoActiveDoAction(FwSmDesc_t smDesc); + +/** + * Guard on the transition from INACTIVE to ACTIVE. + * <pre> + * Algorithm + * is Enabled + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaAlgoIsAlgoEnabled(FwSmDesc_t smDesc); + +/** + * Action on the transition from SUSPENDED to INACTIVE. + * Finalization Action + * @param smDesc the state machine descriptor + */ +void CrIaAlgoFinalization(FwSmDesc_t smDesc); + +#endif /* CrIaAlgoCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaAlgoFunc.c b/CrIa/src/CrIaPrSm/CrIaAlgoFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..90e4457d7ba9f43ba32806dcb9ae62bde0127dcc --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAlgoFunc.c @@ -0,0 +1,482 @@ +/** + * @file CrIaAlgoFunc.c + * @ingroup CrIaSm + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Feb 11 2016 22:56:45 + * + * @brief Implementation of the Algorithm State Machine actions and guards. + * + * Following algorithms are used: + * - Centroiding Algorithms + * - Collection Algorithms [not needed, because it is included in the compression part] + * - Acquisition Algorithms + * - Telescope Temperature Control Algorithms + * - SAA Evaluation Algorithms + * - Compression Algorithms + * - SDS Evaluation Algorithms + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" +#include "FwProfile/FwSmCore.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaAlgo function definitions */ +#include "CrIaAlgoCreate.h" + +#include <CrIaIasw.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#if (__sparc__) +#include <iwf_fpga.h> +#endif + +#include "../IfswUtilities.h" + +#include "../IfswDebug.h" + +CrFwBool_t firstCycleAcqCycTtc2; + +extern float prevDelTemp_Aft, prevDelTemp_Frt; +extern float prevIntTemp_Aft, prevIntTemp_Frt; + +unsigned int CentroidLatch = 0; + +#ifdef PC_TARGET +/*extern unsigned int requestAcquisition;*/ +/*extern unsigned int requestCompression;*/ +extern unsigned int *ShmRequestAcquisitionPTR; /* shared memory for fork() */ +extern unsigned int *ShmRequestCompressionPTR; /* shared memory for fork() */ +#endif /* PC_TARGET */ + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** + * @brief Entry Action for the state ACTIVE. + */ +void CrIaAlgoInitialization(FwSmDesc_t smDesc) +{ + /* initialization actions */ + unsigned int pInitSaaCounter; + + /* Identify Algorithm */ + if ((smDesc == smDescAlgoCent0) | /* ============================================================== ALGO CENT0 === */ + (smDesc == smDescAlgoCent1)) /* =============================================================== ALGO CENT1 === */ + { + /* Initialization is algorithm-specific */ + DEBUGP("AlgoSM: Initialization Action of CENT0/1 ...\n"); + + /* Mantis 2180: reset the latch */ + CentroidLatch = 0; + } + if (smDesc == smDescAlgoAcq1) /* ================================================================== ALGO ACQ1 === */ + { + /* Initialization is algorithm-specific */ + DEBUGP("AlgoSM: Initialization Action of ACQ1 ...\n"); + } + if (smDesc == smDescAlgoCmpr) /* =================================================================== ALGO CMPR === */ + { + /* Initialization as given in CHEOPS-UVIE-INST-TN-001 */ + DEBUGP("AlgoSM: Initialization Action of CMPR ...\n"); + } + if (smDesc == smDescAlgoTtc1) /* =================================================================== ALGO TTC1 === */ + { + /* Request Basic Software to start acquisition of tripleredundant telescope temperature measurements + -> this is done cyclically by the IBSW update DP function */ + DEBUGP("AlgoSM: Initialization Action of TTC1 ...\n"); + } + if (smDesc == smDescAlgoTtc2) /* =================================================================== ALGO TTC2 === */ + { + /* Request Basic Software to start acquisition of tripleredundant telescope temperature measurements + -> this is done cyclically by the IBSW update DP function */ + DEBUGP("AlgoSM: Initialization Action of TTC2 ...\n"); + /* Initialize intTemp to zero */ + prevIntTemp_Aft = 0.0f; + prevIntTemp_Frt = 0.0f; + /* Initialize delTemp to zero */ + prevDelTemp_Aft = 0.0f; + prevDelTemp_Frt = 0.0f; + } + if (smDesc == smDescAlgoSaaEval) /* ================================================================= ALGO SAA === */ + { + /* Initializes saaCounter to pInitSaaCounter and start the procedure */ + DEBUGP("AlgoSM: Initialization Action of SAA Eval ...\n"); + CrIaCopy(PINITSAACOUNTER_ID, &pInitSaaCounter); + CrIaPaste(SAACOUNTER_ID, &pInitSaaCounter); + FwPrStart(prDescSaaEval); + } + if (smDesc == smDescAlgoSdsEval) /* ================================================================= ALGO SDS === */ + { + /* Initializes sdsCounter to pInitSaaCounter and start the procedure */ + DEBUGP("AlgoSM: Initialization Action of SDS Eval ...\n"); + FwPrStart(prDescSdsEval); + } + + return; +} + + +/** + * @brief Do Action for the state ACTIVE. + */ +void CrIaAlgoActiveDoAction(FwSmDesc_t smDesc) +{ + unsigned int imageCycleCnt, iaswCycleCnt; + unsigned int centExecPhase, ttc1ExecPhase, saaExecPhase, sdsExecPhase; + int ttc1ExecPer, ttc2ExecPer, saaExecPer, sdsExecPer; + unsigned char lstpckt; + + /* get current imageCycleCnt */ + CrIaCopy(IMAGECYCLECNT_ID, &imageCycleCnt); + + /* get current iaswCycleCnt */ + iaswCycleCnt = FwSmGetStateExecCnt(smDescIasw); + + /* if (Flag_1) execution action */ + /* Flag 1 depends on the algorithm's period and phase */ + + /*********************************/ + /*** Centroiding Algorithms ***/ + /*********************************/ + /* period = 0 (CENT_EXEC_PER) */ + /* phase = CENT_EXEC_PHASE */ + + if ((smDesc == smDescAlgoCent0) | /* ============================================================== ALGO CENT0 === */ + (smDesc == smDescAlgoCent1)) /* =============================================================== ALGO CENT1 === */ + { + DEBUGP("* Algo: run Execution Action of Centroiding 1 Algorithm ...\n"); + + CrIaCopy(CENT_EXEC_PHASE_ID, ¢ExecPhase); + + DEBUGP("* Algo: imageCycleCnt: %d\n", imageCycleCnt); + + CrIaCopy(LASTSEMPCKT_ID, &lstpckt); + + /* Mantis 2180: run the centroiding in the cycle after the last SEM packet has been received, plus + looking at the phase. + NOTE: the latch is reset in the algo init of this module */ + + if (lstpckt == 1) + { + CentroidLatch = 1; + } + + /* Mantis 2180 NOTE: for the last image of a sequence, the phase will be ignored, so basically like set to 1 */ + if ((lstpckt == 0) && (CentroidLatch == 1) && (centExecPhase <= imageCycleCnt)) + { + CentroidLatch = 0; + + FwPrRun(prDescCentAlgo); + } + + return; + } + + + /*********************************/ + /*** Acquisition Algorithm ***/ + /*********************************/ + /* period = 0 (ACQ_EXEC_PER) */ + /* phase = ACQ_EXEC_PHASE */ + + if (smDesc == smDescAlgoAcq1) /* =================================================================== ALGO ACQ1 === */ + { +#if PC_TARGET + DEBUGP("* Algo: run Execution Action of Acquisition Algorithm ... %d\n", ShmRequestAcquisitionPTR[0]); + + if (ShmRequestAcquisitionPTR[0] > 0) + { + FwPrRun(prDescAcq1AlgoExec); + } +#else + FwPrRun(prDescAcq1AlgoExec); +#endif /* PC_TARGET */ + return; + } + + + /*********************************/ + /*** Compression Algorithm ***/ + /*********************************/ + /* period = -1 */ + /* phase = don't care */ + + if (smDesc == smDescAlgoCmpr) /* =================================================================== ALGO CMPR === */ + { +#if PC_TARGET + DEBUGP("* Algo: run Execution Action of Compression Algorithm ... %d\n", ShmRequestCompressionPTR[0]); + + if (ShmRequestCompressionPTR[0] > 0) + { + FwPrRun(prDescCmprAlgoExec); + } +#else + FwPrRun(prDescCmprAlgoExec); +#endif /* PC_TARGET */ + return; + } + + + /*********************************/ + /*** TTC1 Algorithm ***/ + /*********************************/ + /* period = TTC1_EXEC_PER */ + /* phase = TTC1_EXEC_PHASE */ + + /* NOTE: For Algorithm TTC1: Run the TTC1 Procedure twice, once for the aft thermistors and the aft heaters and + once for the front thermistors and the front heaters. */ + + if (smDesc == smDescAlgoTtc1) /* =================================================================== ALGO TTC1 === */ + { + DEBUGP("* Algo: run Execution Action of TTC1 Algorithm (aft and front) ...\n"); + + CrIaCopy(TTC1_EXEC_PER_ID, &ttc1ExecPer); + CrIaCopy(TTC1_EXEC_PHASE_ID, &ttc1ExecPhase); + + DEBUGP("* Algo: imageCycleCnt: %d\n", imageCycleCnt); + + if ((ttc1ExecPer > 0) && (ttc1ExecPhase == (iaswCycleCnt % ttc1ExecPer))) + { + /* if the period is non-zero, Flag_1 is true in cycles where (iaswCycleCnt MOD period) is equal to phase (cent phase=0) */ + FwPrRun(prDescTtc1aft); + FwPrRun(prDescTtc1front); + + } + + } + + + /*********************************/ + /*** TTC2 Algorithm ***/ + /*********************************/ + /* period = TTC2_EXEC_PER */ + /* phase = TTC2_EXEC_PHASE */ + + /* NOTE: For Algorithm TTC1: Run the TTC1 Procedure twice, once for the aft thermistors and the aft heaters and + once for the front thermistors and the front heaters. */ + + if (smDesc == smDescAlgoTtc2) /* =================================================================== ALGO TTC2 === */ + { + DEBUGP("* Algo: run Execution Action of TTC2 Algorithm (aft and front) ...\n"); + + CrIaCopy(TTC2_EXEC_PER_ID, &ttc2ExecPer); + + if ((FwSmGetStateExecCnt(smDescAlgoTtc2) % ttc2ExecPer) == 1) + { + firstCycleAcqCycTtc2 = 1; /* raise global flag 'first cycle in an acquisition cycle' */ + } + else + { + firstCycleAcqCycTtc2 = 0; /* reset global flag 'first cycle in an acquisition cycle' */ + } + + /* run TTC2 procedure each control cycle */ + FwPrRun(prDescTtc2aft); + FwPrRun(prDescTtc2front); + + } + + + /*********************************/ + /*** SAA Algorithm ***/ + /*********************************/ + /* period = SAA_EXEC_PER */ + /* phase = SAA_EXEC_PHASE */ + + if (smDesc == smDescAlgoSaaEval) /* ================================================================= ALGO SAA === */ + { + DEBUGP("* Algo: run Execution Action of SAA Evaluation Algorithm ...\n"); + + CrIaCopy(SAA_EXEC_PER_ID, &saaExecPer); + CrIaCopy(SAA_EXEC_PHASE_ID, &saaExecPhase); + + DEBUGP("* Algo: imageCycleCnt: %d\n", imageCycleCnt); + + if ((saaExecPer > 0) && (saaExecPhase == (iaswCycleCnt % saaExecPer))) + { + /* if the period is non-zero, Flag_1 is true in cycles where (iaswCycleCnt MOD period) is equal to phase (cent phase=0) */ + FwPrExecute(prDescSaaEval); + + } + + } + + + /*********************************/ + /*** SDS Algorithm ***/ + /*********************************/ + /* period = SDS_EXEC_PER */ + /* phase = SDS_EXEC_PHASE */ + + if (smDesc == smDescAlgoSdsEval) /* ================================================================= ALGO SDS === */ + { + DEBUGP("* Algo: run Execution Action of SDS Evaluation Algorithm ...\n"); + + CrIaCopy(SDS_EXEC_PER_ID, &sdsExecPer); + CrIaCopy(SDS_EXEC_PHASE_ID, &sdsExecPhase); + + DEBUGP("* Algo: imageCycleCnt: %d\n", imageCycleCnt); + + if ((sdsExecPer > 0) && (sdsExecPhase == (iaswCycleCnt % sdsExecPer))) + { + /* if the period is non-zero, Flag_1 is true in cycles where (iaswCycleCnt MOD period) is equal to phase (cent phase=0) */ + FwPrExecute(prDescSdsEval); + + } + + } + + return; +} + +/** + * @brief Finalization Action: (Exit Action for the state ACTIVE.) OR + * (Action on the transition from SUSPENDED to INACTIVE.) + */ +void CrIaAlgoFinalization(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* finalization actions */ + unsigned int saaCounter; + unsigned char isSaaActive, isSdsActive; + + /* Identify Algorithm */ + if ((smDesc == smDescAlgoCent0) | /* ============================================================== ALGO CENT0 === */ + (smDesc == smDescAlgoCent1)) /* =============================================================== ALGO CENT1 === */ + { + DEBUGP("AlgoSM: Finalization Action of CENT1 ...\n"); + } + if (smDesc == smDescAlgoAcq1) /* =================================================================== ALGO ACQ1 === */ + { + DEBUGP("AlgoSM: Finalization Action of ACQ1 ...\n"); + } + if (smDesc == smDescAlgoCmpr) /* =================================================================== ALGO CMPR === */ + { + DEBUGP("AlgoSM: Finalization Action of CMPR ...\n"); + } + if (smDesc == smDescAlgoTtc1) /* =================================================================== ALGO TTC1 === */ + { + /* Request Basic Software to stop acquisition of tripleredundant telescope temperature measurements and to + switch off all heaters */ + DEBUGP("AlgoSM: Finalization Action of TTC1 ...\n"); + + /* switch off heaters */ + CrIaHeaterOff(HEATER_1); + CrIaHeaterOff(HEATER_2); + CrIaHeaterOff(HEATER_3); + CrIaHeaterOff(HEATER_4); + + /* NOTE: the basic software always keeps acquiring measurements such as TEMPOH1A every cycle */ + } + if (smDesc == smDescAlgoTtc2) /* =================================================================== ALGO TTC2 === */ + { + /* Request Basic Software to stop acquisition of tripleredundant telescope temperature measurements and to + switch off all heaters */ + DEBUGP("AlgoSM: Finalization Action of TTC2 ...\n"); + + /* switch off heaters */ + CrIaHeaterOff(HEATER_1); + CrIaHeaterOff(HEATER_2); + CrIaHeaterOff(HEATER_3); + CrIaHeaterOff(HEATER_4); + + /* NOTE: the basic software always keeps acquiring measurements such as TEMPOH1A every cycle */ + } + if (smDesc == smDescAlgoSaaEval) /* ================================================================= ALGO SAA === */ + { + /* Set saaCounter to zero and isSaaActive to true and stop the procedure */ + saaCounter = 0; + CrIaPaste(SAACOUNTER_ID, &saaCounter); + isSaaActive = 1; + CrIaPaste(ISSAAACTIVE_ID, &isSaaActive); + FwPrStop(prDescSaaEval); + } + if (smDesc == smDescAlgoSdsEval) /* ================================================================= ALGO SDS === */ + { + /* Set isSdsActive to true and stop the procedure */ + isSdsActive = 1; + CrIaPaste(ISSDSACTIVE_ID, &isSdsActive); + FwPrStop(prDescSdsEval); + } + + return; +} + +/** + * @brief Guard on the transition from INACTIVE to ACTIVE. + */ +FwSmBool_t CrIaAlgoIsAlgoEnabled(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char algoEnb = 0; + + /* start / algorithm is enabled */ + + /* Identify Algorithm */ + if (smDesc == smDescAlgoCent0) /* ================================================================= ALGO CENT0 === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOCENT0ENABLED_ID, &algoEnb); + } + if (smDesc == smDescAlgoCent1) /* ================================================================= ALGO CENT1 === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOCENT1ENABLED_ID, &algoEnb); + } + if (smDesc == smDescAlgoAcq1) /* =================================================================== ALGO ACQ1 === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOACQ1ENABLED_ID, &algoEnb); + } + if (smDesc == smDescAlgoCmpr) /* =================================================================== ALGO CMPR === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOCCENABLED_ID, &algoEnb); + } + if (smDesc == smDescAlgoTtc1) /* =================================================================== ALGO TTC1 === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOTTC1ENABLED_ID, &algoEnb); + } + if (smDesc == smDescAlgoTtc2) /* =================================================================== ALGO TTC2 === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOTTC2ENABLED_ID, &algoEnb); + } + if (smDesc == smDescAlgoSaaEval) /* ================================================================= ALGO SAA === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOSAAEVALENABLED_ID, &algoEnb); + } + if (smDesc == smDescAlgoSdsEval) /* ================================================================= ALGO SDS === */ + { + /* is algorithm enabled? */ + CrIaCopy(ALGOSDSEVALENABLED_ID, &algoEnb); + } + + if (algoEnb == 1) + return 1; + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaAlgoInit.txt b/CrIa/src/CrIaPrSm/CrIaAlgoInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..1cafb0dbb5bc0d4caaca93efa02835b522a0511b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaAlgoInit.txt @@ -0,0 +1,22 @@ +{ + /** Define the state machine descriptor (SMD) */ + FwSmDesc_t smDesc = CrIaAlgoCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDesc) != smSuccess) { + printf("The state machine CrIaAlgo is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The state machine CrIaAlgo is properly configured ... SUCCESS\n"); + } + + /** Start the SM, send a few transition commands to it, and execute it */ + FwSmStart(smDesc); + FwSmMakeTrans(smDesc, Stop); + FwSmMakeTrans(smDesc, Resume); + FwSmMakeTrans(smDesc, Suspend); + FwSmMakeTrans(smDesc, Start); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCalFullSnapCreate.c b/CrIa/src/CrIaPrSm/CrIaCalFullSnapCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..312ffd07a3cf63ebeaf01bd165c26e6486f180c7 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCalFullSnapCreate.c @@ -0,0 +1,59 @@ +/** + * @file CrIaCalFullSnapCreate.c + * + * @author FW Profile code generator version 5.01 + * @date Created on: Jul 16 2018 16:41:41 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaCalFullSnap function definitions */ +#include "CrIaCalFullSnapCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaCalFullSnapCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 12, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 13, /* N_FLOWS - The number of control flows */ + 12, /* N_ACTIONS - The number of actions */ + 5 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N4, &CrIaCalFullSnapN4); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N1, &CrIaCalFullSnapN1); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N8, &CrIaCalFullSnapN8); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N6, &CrIaCalFullSnapN6); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N9, &CrIaCalFullSnapN9); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N7, &CrIaCalFullSnapN7); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N2, &CrIaCalFullSnapN2); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N3, &CrIaCalFullSnapN3); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N2_1, &CrIaCalFullSnapN2_1); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N5_1, &CrIaCalFullSnapN5_1); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N5_2, &CrIaCalFullSnapN5_2); + FwPrAddActionNode(prDesc, CrIaCalFullSnap_N5, &CrIaCalFullSnapN5); + FwPrAddFlowIniToAct(prDesc, CrIaCalFullSnap_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N4, CrIaCalFullSnap_N5, &CrIaCalFullSnapWaitT2); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N1, CrIaCalFullSnap_N2, &CrIaCalFullSnapIsSemInStab); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N8, CrIaCalFullSnap_N9, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N6, CrIaCalFullSnap_N7, &CrIaCalFullSnapFlag1And2); + FwPrAddFlowActToFin(prDesc, CrIaCalFullSnap_N9, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N7, CrIaCalFullSnap_N8, &CrIaCalFullSnapIsTerm); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N2, CrIaCalFullSnap_N2_1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N3, CrIaCalFullSnap_N4, &CrIaCalFullSnapWaitT1); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N2_1, CrIaCalFullSnap_N3, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N5_1, CrIaCalFullSnap_N5_2, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N5_2, CrIaCalFullSnap_N6, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCalFullSnap_N5, CrIaCalFullSnap_N5_1, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaCalFullSnapCreate.h b/CrIa/src/CrIaPrSm/CrIaCalFullSnapCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..8c5b8f0d78ba3b053d5ca689044e749220cd5a2a --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCalFullSnapCreate.h @@ -0,0 +1,207 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaCalFullSnap procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaCalFullSnap.png + * + * @author FW Profile code generator version 5.01 + * @date Created on: Jul 16 2018 16:41:41 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaCalFullSnapCreate_H_ +#define CrIaCalFullSnapCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaCalFullSnap_N1 (1) /* The identifier of action node N1 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N2 (2) /* The identifier of action node N2 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N2_1 (3) /* The identifier of action node N2_1 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N3 (4) /* The identifier of action node N3 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N4 (5) /* The identifier of action node N4 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N5 (6) /* The identifier of action node N5 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N5_1 (7) /* The identifier of action node N5_1 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N5_2 (8) /* The identifier of action node N5_2 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N6 (9) /* The identifier of action node N6 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N7 (10) /* The identifier of action node N7 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N8 (11) /* The identifier of action node N8 in procedure CrIaCalFullSnap */ +#define CrIaCalFullSnap_N9 (12) /* The identifier of action node N9 in procedure CrIaCalFullSnap */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaCalFullSnapCreate(void* prData); + +/** + * Action for node N4. + * Send cmd (220,11) to the SEM + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN4(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * Generate Event Report EVT_SC_PR_STRT + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN1(FwPrDesc_t prDesc); + +/** + * Action for node N8. + * <pre> + * Stop Compression/Collection + * and Centroid Algorithms + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN8(FwPrDesc_t prDesc); + +/** + * Action for node N6. + * <pre> + * Start Compression/Collection + * Algorithm + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN6(FwPrDesc_t prDesc); + +/** + * Action for node N9. + * <pre> + * Generate Event Report EVT_SC_PR_END + * with outcome equal to: "success" + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN9(FwPrDesc_t prDesc); + +/** + * Action for node N7. + * <pre> + * Send command GoToStabilize + * to SEM Unit State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN7(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Update SEM configuration + * parameters in the data pool + * with procedure parameters + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * Send cmd (220,3) to the SEM + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN3(FwPrDesc_t prDesc); + +/** + * Action for node N2_1. + * <pre> + * Set data pool variable + * pCcdRdMode to CCD_FULL + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN2_1(FwPrDesc_t prDesc); + +/** + * Action for node N5_1. + * <pre> + * Enable the selected + * centroiding algorithm + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN5_1(FwPrDesc_t prDesc); + +/** + * Action for node N5_2. + * Start Centroiding Algorithms + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN5_2(FwPrDesc_t prDesc); + +/** + * Action for node N5. + * <pre> + * Send command GoToCcdFull + * to SEM Unit State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCalFullSnapN5(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N4 to N5. + * <pre> + * Wait calFullSnapT2 + * cycles + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCalFullSnapWaitT2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N1 to N2. + * SEM State Machine is in STABILIZE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCalFullSnapIsSemInStab(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N6 to N7. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCalFullSnapFlag1And2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N7 to N8. + * <pre> + * (SEM Operational SM is in STABILIZE) && + * (All sporadic activities have terminated) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCalFullSnapIsTerm(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N3 to N4. + * <pre> + * Wait calFullSnapT1 + * cycles + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCalFullSnapWaitT1(FwPrDesc_t prDesc); + +#endif /* CrIaCalFullSnapCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaCalFullSnapFunc.c b/CrIa/src/CrIaPrSm/CrIaCalFullSnapFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..6836f0b97e8392c37c5e15480801e2e2b8b18922 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCalFullSnapFunc.c @@ -0,0 +1,360 @@ +/** + * @file CrIaCalFullSnapFunc.c + * @ingroup CrIaPrSci + * @author FW Profile code generator version 5.01; Institute for Astrophysics, 2015-2016 + * @date Created on: Jul 16 2018 16:41:41 + * + * @brief Implementation of the Calibration Full Snap Procedure nodes and guards. + * Implements an observation of type CAL/FULL/SNAP. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwPrConstants.h> +#include <FwProfile/FwPrDCreate.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> /* for FwPrGetCurNode() */ + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> + +/** CrIaCalFullSnap function definitions */ +#include "CrIaCalFullSnapCreate.h" + +#include <CrIaIasw.h> /* for Event Reporting and extern sm and prDescriptors */ +#include <CrIaPrSm/CrIaSemCreate.h> /* for GoToCcdWindow and GoToStabilize */ +#include <CrIaPrSm/CrIaAlgoCreate.h> /* for Start and Stop */ + +#include <IfswDebug.h> + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaCalFullSnapN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_CAL_FULL_SNAP; + + /* Generate event report EVT_SC_PR_STRT */ + + evt_data[0] = ProcId; + evt_data[1] = 0; /* NOT USED */ + + PRDEBUGP("CalFullSnap N1: Event %d generated to signal start of CAL FULL SNAP PR\n", ProcId); + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_STRT, evt_data, 4); + + return; +} + +/** Action for node N2. */ +void CrIaCalFullSnapN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short utemp16; + unsigned int utemp32; + + /* Update SEM configuration parameters in data pool */ + + /* needed for TC(220/3) CMD_Operation_Parameter */ + + CrIaCopy(CALFULLSNAP_PEXPTIME_ID, &utemp32); + CrIaPaste(PEXPTIME_ID, &utemp32); + + CrIaCopy(CALFULLSNAP_PIMAGEREP_ID, &utemp32); + CrIaPaste(PIMAGEREP_ID, &utemp32); + + CrIaCopy(CALFULLSNAP_PNMBIMAGES_ID, &utemp32); + CrIaPaste(PACQNUM_ID, &utemp32); + + /* data oversampling */ + utemp16 = 0; /* means "NO" */ + CrIaPaste(PDATAOS_ID, &utemp16); + + /* pCcdRdMode is set in N2_1 */ + + return; +} + +/** Action for node N2_1. */ +void CrIaCalFullSnapN2_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short utemp16; + + /* Set data pool variable pCcdRdMode to CCD_FULL */ + + /* CCD readout mode */ + utemp16 = SEM_CCD_MODE_CCD_FULL; + CrIaPaste(PCCDRDMODE_ID, &utemp16); + + return; +} + +/** Action for node N3. */ +void CrIaCalFullSnapN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* Send cmd (220,3) to SEM */ + /* Changes the SEM Operational Parameter */ + + DEBUGP("SciWin N3: Send cmd (220,3) to SEM\n"); + + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV220, CRSEM_SERV220_CMD_OPER_PARAM, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* NOTE: parameters are set in the cmd update action according to the data pool entries */ + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/** Action for node N4. */ +void CrIaCalFullSnapN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* Send cmd (220,11) to SEM */ + /* Changes the SEM Functional Parameter */ + + DEBUGP("SciWin N4: Send cmd (220,11) to SEM\n"); + + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV220, CRSEM_SERV220_CMD_FUNCT_PARAM, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* NOTE: parameters are set in the cmd update action according to the data pool entries */ + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/** Action for node N5. */ +void CrIaCalFullSnapN5(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send command GoToCcdFull to SEM Unit State Machine */ + + FwSmMakeTrans(smDescSem, GoToCcdFull); + + return; +} + +/** Action for node N5_1. */ +void CrIaCalFullSnapN5_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char defCentEnabled = 0, dumCentEnabled = 0; + unsigned short pCentSel; + + /* Enable the selected centroiding algorithm */ + + CrIaCopy(CALFULLSNAP_PCENTSEL_ID, &pCentSel); + + if (pCentSel != NO_CENT) + { + if (pCentSel == DUM_CENT) + { + dumCentEnabled = 1; + } + else + { + defCentEnabled = 1; + } + } + + CrIaPaste(ALGOCENT0ENABLED_ID, &dumCentEnabled); + CrIaPaste(ALGOCENT1ENABLED_ID, &defCentEnabled); + + return; +} + +/** Action for node N5_2. */ +void CrIaCalFullSnapN5_2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Start Centroiding Algorithms */ + + FwSmMakeTrans(smDescAlgoCent0, Start); + FwSmMakeTrans(smDescAlgoCent1, Start); + + return; +} + +/** Action for node N6. */ +void CrIaCalFullSnapN6(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Start Compression Algorithm and Collection Algorithm */ + + FwSmMakeTrans(smDescAlgoCmpr, Start); /* NOTE: Clct is part of Cmpr */ + + return; +} + +/** Action for node N7. */ +void CrIaCalFullSnapN7(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send command GoToStabilize to SEM Unit State Machine */ + + FwSmMakeTrans(smDescSem, GoToStabilize); + + return; +} + +/** Action for node N8. */ +void CrIaCalFullSnapN8(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Stop Compression/Collection and Centroiding Algorithms */ + + FwSmMakeTrans(smDescAlgoCmpr, Stop); /* NOTE: Clct is part of Cmpr */ + FwSmMakeTrans(smDescAlgoCent0, Stop); + FwSmMakeTrans(smDescAlgoCent1, Stop); + + return; +} + +/** Action for node N9. */ +void CrIaCalFullSnapN9(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_CAL_FULL_SNAP; + + /* Generate event report EVT_SC_PR_END with outcome "success" */ + + evt_data[0] = ProcId; + evt_data[1] = 1; /* 1 = success */ + + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_END, evt_data, 4); + + return; +} + +/**************/ +/*** GUARDS ***/ +/**************/ + +/** Guard on the Control Flow from N1 to N2. */ +FwPrBool_t CrIaCalFullSnapIsSemInStab(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state; + + /* [ SEM State Machine is in STABILIZE ] */ + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if (sem_oper_state == CrIaSem_STABILIZE) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N3 to N4. */ +FwPrBool_t CrIaCalFullSnapWaitT1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int calFullSnapT1; + + CrIaCopy(CALFULLSNAPT1_ID, &calFullSnapT1); + + /* [ Wait calFullSnapT1 cycles ] */ + if (FwPrGetNodeExecCnt(prDesc) < calFullSnapT1) + { + return 0; + } + else + { + return 1; + } +} + +/** Guard on the Control Flow from N4 to N5. */ +FwPrBool_t CrIaCalFullSnapWaitT2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int calFullSnapT2; + + CrIaCopy(CALFULLSNAPT2_ID, &calFullSnapT2); + + /* [ Wait calFullSnapT2 cycles ] */ + if (FwPrGetNodeExecCnt(prDesc) < calFullSnapT2) + { + return 0; + } + else + { + return 1; + } +} + +/** Guard on the Control Flow from N6 to N7. */ +FwPrBool_t CrIaCalFullSnapFlag1And2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int AcqImageCnt; + unsigned int CalFullSnap_pNmbImages; + unsigned char lstpckt; + + /* [ Flag_1 ] */ + /* Flag_1 is true in the cycle in which (acqImageCnt+1) is equal to pNmbImages and LastSemPckt is true */ + + CrIaCopy(ACQIMAGECNT_ID, &AcqImageCnt); + CrIaCopy(CALFULLSNAP_PNMBIMAGES_ID, &CalFullSnap_pNmbImages); + CrIaCopy(LASTSEMPCKT_ID, &lstpckt); + + if (((AcqImageCnt+1) == CalFullSnap_pNmbImages) && (lstpckt == 1)) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N7 to N8. */ +FwPrBool_t CrIaCalFullSnapIsTerm(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state, Cpu2ProcStatus; + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + /* get state of second CPU */ + CrIaCopy(CPU2PROCSTATUS_ID, &Cpu2ProcStatus); + + DEBUGP("N11->N12: %d %d\n", sem_oper_state, Cpu2ProcStatus); + + if (sem_oper_state == CrIaSem_STABILIZE) /* SEM Operational SM is in STABILIZE */ + if (Cpu2ProcStatus == SDP_STATUS_IDLE) /* All sporadic activities have terminated */ + return 1; + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaCalFullSnapInit.txt b/CrIa/src/CrIaPrSm/CrIaCalFullSnapInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..5359feb399bdaccd4ecebbb48d6a70c93578311e --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCalFullSnapInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaCalFullSnapCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaCalFullSnap is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaCalFullSnap is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCentAlgoCreate.c b/CrIa/src/CrIaPrSm/CrIaCentAlgoCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..b713eb0dd6bac2caa69283b3a1761b7be3ce2fe3 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentAlgoCreate.c @@ -0,0 +1,41 @@ +/** + * @file CrIaCentAlgoCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaCentAlgo function definitions */ +#include "CrIaCentAlgoCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaCentAlgoCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 3, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 4, /* N_FLOWS - The number of control flows */ + 3, /* N_ACTIONS - The number of actions */ + 0 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaCentAlgo_N1, &CrIaCentAlgoN1); + FwPrAddActionNode(prDesc, CrIaCentAlgo_N2, &CrIaCentAlgoN2); + FwPrAddActionNode(prDesc, CrIaCentAlgo_N4, &CrIaCentAlgoN4); + FwPrAddFlowIniToAct(prDesc, CrIaCentAlgo_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCentAlgo_N1, CrIaCentAlgo_N2, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCentAlgo_N2, CrIaCentAlgo_N4, NULL); + FwPrAddFlowActToFin(prDesc, CrIaCentAlgo_N4, NULL); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCentAlgoCreate.h b/CrIa/src/CrIaPrSm/CrIaCentAlgoCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..7c1a556dda861177700f517c24cf2db06e7fcec6 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentAlgoCreate.h @@ -0,0 +1,67 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaCentAlgo procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaCentAlgo.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaCentAlgoCreate_H_ +#define CrIaCentAlgoCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaCentAlgo_N1 1 /* The identifier of action node N1 in procedure CrIaCentAlgo */ +#define CrIaCentAlgo_N2 2 /* The identifier of action node N2 in procedure CrIaCentAlgo */ +#define CrIaCentAlgo_N4 3 /* The identifier of action node N4 in procedure CrIaCentAlgo */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaCentAlgoCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * Select the SIB to be used as input + * for the Centroiding Algorithm + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCentAlgoN1(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Compute centroiding data + * for data in the selected input buffer + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCentAlgoN2(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * Write algorithm output to the data pool + * @param smDesc the procedure descriptor + */ +void CrIaCentAlgoN4(FwPrDesc_t prDesc); + +#endif /* CrIaCentAlgoCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCentAlgoFunc.c b/CrIa/src/CrIaPrSm/CrIaCentAlgoFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..673de863d89e6dbe3bcdf738fa8ad9f8c25e2b12 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentAlgoFunc.c @@ -0,0 +1,136 @@ +/** + * @file CrIaCentAlgoFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +#include <FwProfile/FwSmCore.h> /* for FwSmGetCurState() */ + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/** CrIaCentAlgo function definitions */ +#include "CrIaCentAlgoCreate.h" + +/** the actual centroiding algorithm */ +#include "EngineeringAlgorithms.h" + +#include "IfswDebug.h" +#include "CrIaIasw.h" + +#include <CrIaPrSm/CrIaAlgoCreate.h> + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaCentAlgoN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* select the SIB to be used as input for the centroiding algorithm */ + + /* NOTE: We use the current sib in and via the centroiding phase the user needs to make sure that it is complete. + Alternatively, we could add a (toggle)flag in the sci data upd function (or in the S21) because the + number of expected reports is given in the SEM data. */ + + return; +} + + +/** Action for node N2. */ +void CrIaCentAlgoN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + struct CrIaSib *p_outgoingSibIn; + +#ifdef PC_TARGET + p_outgoingSibIn = ShmOutgoingSibInPTR; +#else + p_outgoingSibIn = &outgoingSibInStruct; +#endif + + /* compute centroiding data for data in the selected input buffer */ + + PRDEBUGP("** Centr SIB: %u", (unsigned int) GET_SDB_OFFSET_FROM_ADDR(p_outgoingSibIn->Base)); + + if (p_outgoingSibIn->UsedSize != 0) /* protection to start on invalid Sib */ + { + if (FwSmGetCurState(smDescAlgoCent0) == CrIaAlgo_ACTIVE) /* if Dummy Centroiding is active */ + { + PrepareSibCentroid (p_outgoingSibIn, CEN_INV_ALGO, 0.0f, 0.0f); /* Mantis 2197 */ + } + else + { + Centroiding (p_outgoingSibIn); + } + + /* Mantis 2180 */ + S196Flag = 1; + } + else + { + /* no data, nothing calculated, nothing to report ;) */ + PRDEBUGP("CEN: no data!\n"); + } + + return; +} + +/** Action for node N4. */ +void CrIaCentAlgoN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + struct SibCentroid *Centroid; + int offsetX, offsetY; + unsigned short startIntegFine, endIntegFine, dataCadence; + unsigned int startIntegCoarse, endIntegCoarse; + unsigned char validityStatus; + + /* The output of Centroiding was written back into the SibStruct Centroid section + Here we write the algorithm output to the data pool */ + +#ifdef PC_TARGET + Centroid = (struct SibCentroid *)(ShmOutgoingSibInPTR->Centroid); +#else + Centroid = (struct SibCentroid *)(outgoingSibInStruct.Centroid); +#endif + + /* load the report parameters from the data pool and feed into the packet */ + offsetX = Centroid->offsetX; + CrIaPaste (OFFSETX_ID, &offsetX); + + offsetY = Centroid->offsetY; + CrIaPaste (OFFSETY_ID, &offsetY); + + /* NOTE: target location is NOT copied back from the data pool */ + + startIntegCoarse = Centroid->startIntegCoarse; + CrIaPaste(INTEGSTARTTIMECRS_ID, &startIntegCoarse); + + startIntegFine = (unsigned short) (Centroid->startIntegFine); + CrIaPaste(INTEGSTARTTIMEFINE_ID, &startIntegFine); + + endIntegCoarse = Centroid->endIntegCoarse; + CrIaPaste(INTEGENDTIMECRS_ID, &endIntegCoarse); + + endIntegFine = (unsigned short) (Centroid->endIntegFine); + CrIaPaste(INTEGENDTIMEFINE_ID, &endIntegFine); + + dataCadence = (unsigned short) (Centroid->dataCadence); + CrIaPaste(DATACADENCE_ID, &dataCadence); + + validityStatus = (unsigned char) (Centroid->validityStatus); + CrIaPaste(VALIDITYSTATUS_ID, &validityStatus); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaCentAlgoInit.txt b/CrIa/src/CrIaPrSm/CrIaCentAlgoInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..c6dd058fb5f47fba3f00db8b41ae71b99a675641 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentAlgoInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaCentAlgoCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaCentAlgo is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaCentAlgo is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCentValProcCreate.c b/CrIa/src/CrIaPrSm/CrIaCentValProcCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..31dac1bf32402ce003eed531a673165196bc1e14 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentValProcCreate.c @@ -0,0 +1,89 @@ +/** + * @file CrIaCentValProcCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaCentValProc function definitions */ +#include "CrIaCentValProcCreate.h" + +/** + * Guard on the Control Flow from DECISION2 to DECISION3. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code55002(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION3 to DECISION4. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code31035(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION4 to N2. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code57742(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaCentValProcCreate(void* prData) +{ + const FwPrCounterU2_t DECISION2 = 1; /* The identifier of decision node DECISION2 in procedure CrIaCentValProc */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaCentValProc */ + const FwPrCounterU2_t DECISION3 = 2; /* The identifier of decision node DECISION3 in procedure CrIaCentValProc */ + const FwPrCounterU2_t N_OUT_OF_DECISION3 = 2; /* The number of control flows out of decision node DECISION3 in procedure CrIaCentValProc */ + const FwPrCounterU2_t DECISION4 = 3; /* The identifier of decision node DECISION4 in procedure CrIaCentValProc */ + const FwPrCounterU2_t N_OUT_OF_DECISION4 = 2; /* The number of control flows out of decision node DECISION4 in procedure CrIaCentValProc */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 3, /* N_ANODES - The number of action nodes */ + 3, /* N_DNODES - The number of decision nodes */ + 10, /* N_FLOWS - The number of control flows */ + 3, /* N_ACTIONS - The number of actions */ + 6 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaCentValProc_N1, &CrIaCentValProcN1); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddDecisionNode(prDesc, DECISION3, N_OUT_OF_DECISION3); + FwPrAddDecisionNode(prDesc, DECISION4, N_OUT_OF_DECISION4); + FwPrAddActionNode(prDesc, CrIaCentValProc_N2, &CrIaCentValProcN2); + FwPrAddActionNode(prDesc, CrIaCentValProc_N3, &CrIaCentValProcN3); + FwPrAddFlowIniToDec(prDesc, DECISION2, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCentValProc_N1, CrIaCentValProc_N3, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaCentValProc_N1, &CrIaCentValProcIsOutFOV); + FwPrAddFlowDecToDec(prDesc, DECISION2, DECISION3, &code55002); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaCentValProc_N1, &CrIaCentValProcIsDistLarge); + FwPrAddFlowDecToDec(prDesc, DECISION3, DECISION4, &code31035); + FwPrAddFlowDecToAct(prDesc, DECISION4, CrIaCentValProc_N1, &CrIaCentValProcIsFrozen); + FwPrAddFlowDecToAct(prDesc, DECISION4, CrIaCentValProc_N2, &code57742); + FwPrAddFlowActToFin(prDesc, CrIaCentValProc_N2, NULL); + FwPrAddFlowActToFin(prDesc, CrIaCentValProc_N3, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaCentValProcCreate.h b/CrIa/src/CrIaPrSm/CrIaCentValProcCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..fdff23bad167b6797c6ec3e7cd5a87f8fd514168 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentValProcCreate.h @@ -0,0 +1,105 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaCentValProc procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaCentValProc.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaCentValProcCreate_H_ +#define CrIaCentValProcCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaCentValProc_N1 1 /* The identifier of action node N1 in procedure CrIaCentValProc */ +#define CrIaCentValProc_N2 2 /* The identifier of action node N2 in procedure CrIaCentValProc */ +#define CrIaCentValProc_N3 3 /* The identifier of action node N3 in procedure CrIaCentValProc */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaCentValProcCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * Set centValProcOutput to + * indicate that the centroid is invalid + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCentValProcN1(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Set centValProcOutput to + * the same value as ValidityStatus + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCentValProcN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Generate event + * EVT_INV_CENT + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCentValProcN3(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N1. + * <pre> + * The position of the target is outside + * the instrument field of view + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCentValProcIsOutFOV(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION3 to N1. + * <pre> + * Distance between desired and measured position + * of target is greater than CENT_OFFSET_LIM + * of size of instrument field of view + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCentValProcIsDistLarge(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION4 to N1. + * <pre> + * (More than CENT_FROZEN_LIM centroids have been + * computed since IASW was started) && + * (Last CENT_FROZEN_LIM centroids are identical) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCentValProcIsFrozen(FwPrDesc_t prDesc); + +#endif /* CrIaCentValProcCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCentValProcFunc.c b/CrIa/src/CrIaPrSm/CrIaCentValProcFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..713b4ef217fa5ba3a6c81d41436d7196d3b713c9 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentValProcFunc.c @@ -0,0 +1,210 @@ +/** + * @file CrIaCentValProcFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaCentValProc function definitions */ +#include "CrIaCentValProcCreate.h" + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> +#include <EngineeringAlgorithms.h> +#include <IfswDebug.h> + + +#define CENTCONSCHECKFAIL 0xee + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaCentValProcN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char centValProcOutput; + + /* Set centValProcOutput to indicate that the centroid is invalid */ + + /* Validity Status: + VAL_CCD_WINDOW = 0x00 + VAL_CCD_FULL = 0x01 + INV_IN_DATA = 0xFF + NO_TARGET = 0xFE + LARGE_SMEARING = 0xFD + ALGO_FAILED = 0xFC + OBT_NOT_SYNC = 0xFB + */ + + centValProcOutput = CENTCONSCHECKFAIL; + CrIaPaste(CENTVALPROCOUTPUT_ID, ¢ValProcOutput); + + return; +} + +/** Action for node N2. */ +void CrIaCentValProcN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char validityStatus; + + /* Set centValProcOutput to the same value as ValidityStatus */ + + CrIaCopy(VALIDITYSTATUS_ID, &validityStatus); + CrIaPaste(CENTVALPROCOUTPUT_ID, &validityStatus); + + return; +} + +/** Action for node N3. */ +void CrIaCentValProcN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + + /* Generate event EVT_INV_CENT */ + + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_INV_CENT, evt_data, 4); + + return; +} + +/********** + * GUARDS * + **********/ + +/** Guard on the Control Flow from DECISION2 to N1. */ +FwPrBool_t CrIaCentValProcIsOutFOV(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char validityStatus; + int CentOffsetX, CentOffsetY; + double fovSize, CentOffsetSq; + + /* SPEC: [ The position of the target is outside the instrument field of view - NO_TARGET ] */ + + /* get the size of the current image from the current SIB, which was used to calculate the centroid */ +#ifdef PC_TARGET + fovSize = (ShmOutgoingSibInPTR->Xdim * ShmOutgoingSibInPTR->Xdim + ShmOutgoingSibInPTR->Ydim * ShmOutgoingSibInPTR->Ydim) * 0.25f; +#else + fovSize = (outgoingSibInStruct.Xdim * outgoingSibInStruct.Xdim + outgoingSibInStruct.Ydim * outgoingSibInStruct.Ydim) * 0.25f; +#endif + + CrIaCopy (OFFSETX_ID, &CentOffsetX); + CrIaCopy (OFFSETY_ID, &CentOffsetY); + + CentOffsetSq = ((double)CentOffsetX * (double)CentOffsetX + (double)CentOffsetY * (double)CentOffsetY) / 10000.0; /* incl. conversion centi-pixel to pixel */ + + CrIaCopy(VALIDITYSTATUS_ID, &validityStatus); + + if ((validityStatus == CEN_VAL_WINDOW) || (validityStatus == CEN_VAL_FULL)) + { + if (CentOffsetSq > fovSize) + { + return 1; /* declare inconsistency */ + } + } + + return 0; + +} + + +/** Guard on the Control Flow from DECISION3 to N1. */ +FwPrBool_t CrIaCentValProcIsDistLarge(FwPrDesc_t __attribute__((unused)) prDesc) +{ + float centOffsetLim; + int CentOffsetX, CentOffsetY; + double fovSizeLimit, CentOffsetSq; + + /* [ Distance between desired and measured position of target is greater than CENT_OFFSET_LIM of + size of instrument field of view ] */ + + DEBUGP("CrIaCentValProcIsDistLarge\n"); + + /* get Target Acquisition Distance Threshold from data pool */ + CrIaCopy(CENT_OFFSET_LIM_ID, ¢OffsetLim); + + /* get the size of the current image from the current SIB, which was used to calculate the centroid */ +#ifdef PC_TARGET + fovSizeLimit = (ShmOutgoingSibInPTR->Xdim * ShmOutgoingSibInPTR->Xdim + ShmOutgoingSibInPTR->Ydim * ShmOutgoingSibInPTR->Ydim) * 0.25f; +#else + fovSizeLimit = (outgoingSibInStruct.Xdim * outgoingSibInStruct.Xdim + outgoingSibInStruct.Ydim * outgoingSibInStruct.Ydim) * 0.25f; +#endif + fovSizeLimit *= centOffsetLim * centOffsetLim; /* radius squared in pixel */ + + CrIaCopy (OFFSETX_ID, &CentOffsetX); + CrIaCopy (OFFSETY_ID, &CentOffsetY); + + CentOffsetSq = ((double)CentOffsetX * (double)CentOffsetX + (double)CentOffsetY * (double)CentOffsetY) / 10000.0; /* incl. conversion centi-pixel to pixel */ + + if (CentOffsetSq < fovSizeLimit) + { + return 0; + } + else + { + return 1; + } + +} + +/** Guard on the Control Flow from DECISION4 to N1. */ +FwPrBool_t CrIaCentValProcIsFrozen(FwPrDesc_t __attribute__((unused)) prDesc) +{ + int CentOffsetX, CentOffsetY; + unsigned int IntegStartTimeCrs; + static int CentOffsetXOld, CentOffsetYOld; + static unsigned int IntegStartTimeCrsOld; + static unsigned int centFrozenNmb = 0; + static unsigned int centFrozenNmbOld = 0; + float centFrozenLim; + + /* [ (More than CENT_FROZEN_LIM centroids have been computed since IASW has started) && + (Last CENT_FROZEN_LIM centroids are identical) ] */ + + DEBUGP("CrIaCentValProcIsFrozen\n"); + + CrIaCopy(CENT_FROZEN_LIM_ID, ¢FrozenLim); + + CrIaCopy (OFFSETX_ID, &CentOffsetX); + CrIaCopy (OFFSETY_ID, &CentOffsetY); + CrIaCopy (INTEGSTARTTIMECRS_ID, &IntegStartTimeCrs); + + if (CentOffsetX == CentOffsetXOld) + { + if (CentOffsetY == CentOffsetYOld) + { + if (IntegStartTimeCrs == IntegStartTimeCrsOld) + { + /* values frozen -> increment counter */ + centFrozenNmb++; + } + } + } + + if (centFrozenNmb >= (unsigned int)centFrozenLim) + { + return 1; + } + + if (centFrozenNmbOld == centFrozenNmb) + centFrozenNmb = 0; /* Last centroid is not frozen, reset counter */ + + CentOffsetXOld = CentOffsetX; + CentOffsetYOld = CentOffsetY; + IntegStartTimeCrsOld = IntegStartTimeCrs; + centFrozenNmbOld = centFrozenNmb; + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaCentValProcInit.txt b/CrIa/src/CrIaPrSm/CrIaCentValProcInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..a331c4f9497651c734f48ba41d6d5b82b8fa9d47 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCentValProcInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaCentValProcCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaCentValProc is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaCentValProc is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecCreate.c b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..404c52f412722279034d3bd9391e97f65d0ff6e4 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecCreate.c @@ -0,0 +1,39 @@ +/** + * @file CrIaCmprAlgoExecCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Sep 21 2016 11:3:28 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaCmprAlgoExec function definitions */ +#include "CrIaCmprAlgoExecCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaCmprAlgoExecCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 2, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 3, /* N_FLOWS - The number of control flows */ + 2, /* N_ACTIONS - The number of actions */ + 1 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaCmprAlgoExec_N1, &CrIaCmprAlgoExecN1); + FwPrAddActionNode(prDesc, CrIaCmprAlgoExec_N2, &CrIaCmprAlgoExecN2); + FwPrAddFlowIniToAct(prDesc, CrIaCmprAlgoExec_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCmprAlgoExec_N1, CrIaCmprAlgoExec_N2, &CrIaCmprAlgoExecGuard); + FwPrAddFlowActToFin(prDesc, CrIaCmprAlgoExec_N2, NULL); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecCreate.h b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..561539a0576234a627445dbd2a5cf4170b2d01f1 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecCreate.h @@ -0,0 +1,48 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaCmprAlgoExec procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaCmprAlgoExec.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Sep 21 2016 11:3:28 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaCmprAlgoExecCreate_H_ +#define CrIaCmprAlgoExecCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaCmprAlgoExec_N1 1 /* The identifier of action node N1 in procedure CrIaCmprAlgoExec */ +#define CrIaCmprAlgoExec_N2 2 /* The identifier of action node N2 in procedure CrIaCmprAlgoExec */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaCmprAlgoExecCreate(void* prData); + +/** Action for node N1. */ +void CrIaCmprAlgoExecN1(FwPrDesc_t __attribute__((unused)) prDesc); + +/** Action for node N2. */ +void CrIaCmprAlgoExecN2(FwPrDesc_t __attribute__((unused)) prDesc); + +/** Guard on the Control Flow from N1 to N2. */ +FwPrBool_t CrIaCmprAlgoExecGuard(FwPrDesc_t __attribute__((unused)) prDesc); + +#endif /* CrIaCmprAlgoExecCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecFunc.c b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..cff3923d5be9addaa883687194615f0bc4922242 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecFunc.c @@ -0,0 +1,92 @@ +/** + * @file CrIaCmprAlgoExecFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Sep 8 2016 18:9:49 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaCmprAlgoExec function definitions */ +#include "CrIaCmprAlgoExecCreate.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "Services/General/CrIaConstants.h" + + +#include <IfswDebug.h> +#include "CrIaIasw.h" + +#ifdef PC_TARGET +/*extern unsigned int requestCompression;*/ +extern unsigned int *ShmRequestCompressionPTR; /* shared memory for fork() */ +#else +#include "../IBSW/include/ibsw_interface.h" +#endif /* PC_TARGET */ +#include "../../ifsw.h" + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaCmprAlgoExecN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ +#ifdef PC_TARGET + DEBUGP("CrIaCmprAlgoExecN1: SDP_STATUS_SCIENCE = %d\n", cpu1_notification(SDP_STATUS_SCIENCE)); + if (cpu1_notification(SDP_STATUS_SCIENCE) == SDP_STATUS_IDLE) + { + DEBUGP("CrIaCmprAlgoExecN1: ... is SDP_STATUS_IDLE\n"); + } + + /*PRDEBUGP("Cmpr Algo exec.: requestCompression = %d\n", requestCompression);*/ + PRDEBUGP("Cmpr Algo exec.: requestCompression = %d\n", ShmRequestCompressionPTR[0]); +#else + run_rt(RTCONT_CMPR, DEADLINE_CMPR, run_compression); +#endif /* PC_TARGET */ + + return; +} + +/** Action for node N2. */ +void CrIaCmprAlgoExecN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + PRDEBUGP("exiting Cmpr Algo exec.\n"); + + return; +} + +/** Guard on the Control Flow from N1 to N2. */ +FwPrBool_t CrIaCmprAlgoExecGuard(FwPrDesc_t __attribute__((unused)) prDesc) +{ +#ifdef PC_TARGET + unsigned short Cpu2ProcStatus; + + CrIaCopy(CPU2PROCSTATUS_ID, &Cpu2ProcStatus); + + PRDEBUGP("Cmpr Algo exec.: Check Cpu2ProcStatus = %d\n", Cpu2ProcStatus); + DEBUGP("CrIaCmprAlgoExecGuard: Cpu2ProcStatus = %d\n", Cpu2ProcStatus); + + /* compression has finished */ + if (Cpu2ProcStatus == SDP_STATUS_IDLE) + { + DEBUGP("CrIaCmprAlgoExecGuard: ... is SDP_STATUS_IDLE\n"); + return 1; + } + + return 0; +#else + return 1; +#endif /* PC_TARGET */ +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecInit.txt b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..c3cf33010a3c64b6b9ad9deda6c4865a508f582b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCmprAlgoExecInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaCmprAlgoExecCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaCmprAlgoExec is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaCmprAlgoExec is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffCreate.c b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..9af77d8980b2116ef9fbd04c69f70e8f5d1045a9 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffCreate.c @@ -0,0 +1,39 @@ +/** + * @file CrIaCtrldSwitchOffCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaCtrldSwitchOff function definitions */ +#include "CrIaCtrldSwitchOffCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaCtrldSwitchOffCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 2, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 3, /* N_FLOWS - The number of control flows */ + 2, /* N_ACTIONS - The number of actions */ + 1 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaCtrldSwitchOff_N1, &CrIaCtrldSwitchOffStopSem); + FwPrAddActionNode(prDesc, CrIaCtrldSwitchOff_N2, &CrIaCtrldSwitchOffDisErrLog); + FwPrAddFlowIniToAct(prDesc, CrIaCtrldSwitchOff_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaCtrldSwitchOff_N1, CrIaCtrldSwitchOff_N2, NULL); + FwPrAddFlowActToFin(prDesc, CrIaCtrldSwitchOff_N2, &CrIaCtrldSwitchOffWaitT1); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffCreate.h b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..f6f8aca2625ff8a0bf377169cd998f5d9dd52b6c --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffCreate.h @@ -0,0 +1,67 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaCtrldSwitchOff procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaCtrldSwitchOff.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaCtrldSwitchOffCreate_H_ +#define CrIaCtrldSwitchOffCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaCtrldSwitchOff_N1 1 /* The identifier of action node N1 in procedure CrIaCtrldSwitchOff */ +#define CrIaCtrldSwitchOff_N2 2 /* The identifier of action node N2 in procedure CrIaCtrldSwitchOff */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaCtrldSwitchOffCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * Send StopSem Command + * to IASW State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCtrldSwitchOffStopSem(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Disable Error Log by + * setting ERR_LOG_ENB to false + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaCtrldSwitchOffDisErrLog(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N2 to Final Node. + * Wait CTRLD_SWITCH_OFF_T1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaCtrldSwitchOffWaitT1(FwPrDesc_t prDesc); + +#endif /* CrIaCtrldSwitchOffCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffFunc.c b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..5e431e156312b1d5abd7683236dcfda9dca2d987 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffFunc.c @@ -0,0 +1,72 @@ +/** + * @file CrIaCtrldSwitchOffFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +/** CrIaCtrldSwitchOff function definitions */ +#include "CrIaCtrldSwitchOffCreate.h" + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaPrSm/CrIaIaswCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <stdlib.h> + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaCtrldSwitchOffStopSem(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send StopSem Command to IASW State Machine */ + + FwSmMakeTrans(smDescIasw, StopSem); + + return; +} + +/** Action for node N2. */ +void CrIaCtrldSwitchOffDisErrLog(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char Enabled; + + /* Disable Error Log by setting ERR_LOG_ENB to false */ + + Enabled = 0; + CrIaPaste(ERR_LOG_ENB_ID, &Enabled); + + return; +} + +/** Guard on the Control Flow from N2 to Final Node. */ +FwPrBool_t CrIaCtrldSwitchOffWaitT1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short ctrldSwitchOffT1; + + CrIaCopy(CTRLD_SWITCH_OFF_T1_ID, &ctrldSwitchOffT1); + + /* [ Wait CTRLD_SWITCH_OFF_T1 ] */ + if (FwPrGetNodeExecCnt(prDesc) < ctrldSwitchOffT1) + { + return 0; + } + else + { + return 1; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffInit.txt b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..5f2a1477bc25a5f1a99937dfd5d6b463ba5ecf7e --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaCtrldSwitchOffInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaCtrldSwitchOffCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaCtrldSwitchOff is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaCtrldSwitchOff is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaFbfLoadCreate.c b/CrIa/src/CrIaPrSm/CrIaFbfLoadCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..2da72d514c7173ecc074dc68a730a5df6623176c --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfLoadCreate.c @@ -0,0 +1,76 @@ +/** + * @file CrIaFbfLoadCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: May 4 2016 8:24:50 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaFbfLoad function definitions */ +#include "CrIaFbfLoadCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to N2. + * <pre> + * Not all requested blocks + * have been read + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code42261(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION2 to N3. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code97591(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaFbfLoadCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaFbfLoad */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaFbfLoad */ + const FwPrCounterU2_t DECISION2 = 2; /* The identifier of decision node DECISION2 in procedure CrIaFbfLoad */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaFbfLoad */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 3, /* N_ANODES - The number of action nodes */ + 2, /* N_DNODES - The number of decision nodes */ + 8, /* N_FLOWS - The number of control flows */ + 3, /* N_ACTIONS - The number of actions */ + 5 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaFbfLoad_N1, &CrIaFbfLoadN1); + FwPrAddActionNode(prDesc, CrIaFbfLoad_N2, &CrIaFbfLoadN2); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddActionNode(prDesc, CrIaFbfLoad_N3, &CrIaFbfLoadN3); + FwPrAddFlowIniToDec(prDesc, DECISION2, NULL); + FwPrAddFlowActToDec(prDesc, CrIaFbfLoad_N1, DECISION1, NULL); + FwPrAddFlowActToDec(prDesc, CrIaFbfLoad_N2, DECISION1, &CrIaWaitFbfBlckRdDur); + FwPrAddFlowDecToFin(prDesc, DECISION1, &CrIaFbfLoadAreAllBlocksRead); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaFbfLoad_N2, &code42261); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaFbfLoad_N1, &CrIaFbfLoadFlag1); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaFbfLoad_N3, &code97591); + FwPrAddFlowActToAct(prDesc, CrIaFbfLoad_N3, CrIaFbfLoad_N1, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaFbfLoadCreate.h b/CrIa/src/CrIaPrSm/CrIaFbfLoadCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..af3581d8eaccff09eb11646fed63527ba7790188 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfLoadCreate.h @@ -0,0 +1,99 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaFbfLoad procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaFbfLoad.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: May 4 2016 8:24:50 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaFbfLoadCreate_H_ +#define CrIaFbfLoadCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaFbfLoad_N1 1 /* The identifier of action node N1 in procedure CrIaFbfLoad */ +#define CrIaFbfLoad_N2 2 /* The identifier of action node N2 in procedure CrIaFbfLoad */ +#define CrIaFbfLoad_N3 3 /* The identifier of action node N3 in procedure CrIaFbfLoad */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaFbfLoadCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * Call IBSW operation to read + * the first block from the Target FBF + * and write it to the RAM Data Area + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfLoadN1(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Call IBSW operation to read + * the next block from the Target FBF + * and write it to the RAM Data Area + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfLoadN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Load EVT_FBF_LOAD_RISK + * with FBF identifier as parameter + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfLoadN3(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N1 to DECISION1. + * Wait FBF_BLCK_RD_DUR Cycles + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaWaitFbfBlckRdDur(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to Final Node. + * <pre> + * All requested blocks + * have been read + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaFbfLoadAreAllBlocksRead(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N1. + * ! Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaFbfLoadFlag1(FwPrDesc_t prDesc); + +#endif /* CrIaFbfLoadCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaFbfLoadFunc.c b/CrIa/src/CrIaPrSm/CrIaFbfLoadFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..94b883f8c7f860a3b58a4d3b5cb329051d4e3ce8 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfLoadFunc.c @@ -0,0 +1,196 @@ +/** + * @file CrIaFbfLoadFunc.c + * @ingroup CrIaPr + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: May 4 2016 8:24:50 + * + * @brief Implementation of the FBF Load Procedure + * + * Load number of blocks from a FBF into a RAM data area. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaFbfSave function definitions */ +#include "CrIaFbfSaveCreate.h" + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + +#if (__sparc__) +#include <ibsw_interface.h> +#endif + +#if (__sparc__) +#include <wrap_malloc.h> /* for SRAM1_FLASH_ADDR */ +#include <iwf_flash.h> +#else +#define SRAM1_FLASH_ADDR 0 +#define FLASH_BLOCKSIZE 0 +#endif + +#include <IfswDebug.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** + * @brief Node 1 of the FBF Load Procedure + * + * @note Deviations from the specifications are given due to differing FLASH handling. Therefore reading a first block + * do not need a different handling as consecutive blocks. + * + */ + +/** Action for node N1. */ +void CrIaFbfLoadN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char readblocks = 0; + + CrIaPaste(FBFLOADBLOCKCOUNTER_ID, &readblocks); + + /* NOTE: the first block is read by the loop in N2 */ + + return; +} + +/** Action for node N2. */ +void CrIaFbfLoadN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId, fbfIndex, fbfNBlocks, readblocks; + unsigned int fbfRamAddr; + + int readStatus; + + CrIaCopy(FBFLOAD_PFBFNBLOCKS_ID, &fbfNBlocks); + + if (fbfNBlocks == 0) + return; + + CrIaCopy(FBFLOAD_PFBFID_ID, &fbfId); + fbfIndex = fbfId - 1; + + CrIaCopy(FBFLOAD_PFBFRAMADDR_ID, &fbfRamAddr); + + CrIaCopy(FBFLOADBLOCKCOUNTER_ID, &readblocks); + + DEBUGP("Trigger Read, file %d blocks left: %d to %x\n", fbfId, fbfNBlocks, (unsigned int)fbfRamAddr); + + fbfRamAddr += FLASH_BLOCKSIZE * readblocks; + + readStatus = CrIbFlashTriggerRead(fbfIndex, readblocks, (void *) fbfRamAddr); + + if (readStatus != 0) + { + DEBUGP("Error: CrIbFlashTriggerRead returns a nonzero value!\n"); + } + + DEBUGP("read one block to %x\n", (unsigned int)fbfRamAddr); + + readblocks++; + + CrIaPaste(FBFLOADBLOCKCOUNTER_ID, &readblocks); + + DEBUGP("LF action finished \n"); + + return; +} + + +/** Action for node N3. */ +void CrIaFbfLoadN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId; + unsigned short evt_data[2]; + + /* Load EVT_FBF_LOAD_RISK with FBF identifier as parameter*/ + DEBUGP("LF load risk\n"); + + CrIaCopy(FBFLOAD_PFBFID_ID, &fbfId); + + /* Load EVT_SEM_TR */ + evt_data[0] = fbfId; /* FbfId */ + evt_data[1] = 0; /* NOT USED */ + + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FBF_LOAD_RISK, evt_data, 4); + + return; +} + +/** Guard on the Control Flow from N1 to DECISION1. */ +FwPrBool_t CrIaWaitFbfBlckRdDur(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int fbf_blck_rd_dur; + + CrIaCopy(FBF_BLCK_RD_DUR_ID, &fbf_blck_rd_dur); + + /* Mantis 1581: Wait until FLASH is ready, but at least FBF_BLCK_RD_DUR cycles */ + if ((FwPrGetNodeExecCnt(prDesc) >= fbf_blck_rd_dur) && CrIbFlashIsReady()) + return 1; + + return 0; +} + +/** Guard on the Control Flow from DECISION1 to Final Node. */ +FwPrBool_t CrIaFbfLoadAreAllBlocksRead(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfNBlocks, readblocks; + + DEBUGP("CrIaFbfLoadFunc: Check if all requested blocks have been read\n"); + + CrIaCopy(FBFLOAD_PFBFNBLOCKS_ID, &fbfNBlocks); + + CrIaCopy(FBFLOADBLOCKCOUNTER_ID, &readblocks); + + if (fbfNBlocks == readblocks) + { + return 1; /* done */ + } + + return 0; +} + +/** Guard on the Control Flow from DECISION2 to N1. */ +FwPrBool_t CrIaFbfLoadFlag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* raise flag if fbf is invalid or disabled */ + unsigned char fbfId, fbfIndex, fbfValid, fbfEnb; + + CrIaCopy(FBFLOAD_PFBFID_ID, &fbfId); + fbfIndex = fbfId - 1; + CrIaCopyArrayItem (ISFBFVALID_ID, &fbfValid, fbfIndex); + CrIaCopyArrayItem (FBF_ENB_ID, &fbfEnb, fbfIndex); + + DEBUGP("LF: id %d v %d e %d\n", fbfId, fbfValid, fbfEnb); + + if ((fbfValid == 0) || (fbfEnb == 0)) + return 0; + /* + NOTE: + 0 goes to N3 (risk) + 1 goes to N1 (go on) + */ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaFbfLoadInit.txt b/CrIa/src/CrIaPrSm/CrIaFbfLoadInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..2baee6a919896f5f428d982308899d38bd940f04 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfLoadInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaFbfLoadCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaFbfLoad is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaFbfLoad is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaFbfSaveCreate.c b/CrIa/src/CrIaPrSm/CrIaFbfSaveCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..dc10a64e2da7b239164ce3a698ffeeb35441ef87 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfSaveCreate.c @@ -0,0 +1,98 @@ +/** + * @file CrIaFbfSaveCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: May 4 2016 8:24:50 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaFbfSave function definitions */ +#include "CrIaFbfSaveCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to DECISION3. + * <pre> + * (All requested blocks + * have been written) || Flag_1 + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code11311(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION2 to N5. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code64383(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION3 to N6. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code2535(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaFbfSaveCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaFbfSave */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaFbfSave */ + const FwPrCounterU2_t DECISION2 = 2; /* The identifier of decision node DECISION2 in procedure CrIaFbfSave */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaFbfSave */ + const FwPrCounterU2_t DECISION3 = 3; /* The identifier of decision node DECISION3 in procedure CrIaFbfSave */ + const FwPrCounterU2_t N_OUT_OF_DECISION3 = 2; /* The number of control flows out of decision node DECISION3 in procedure CrIaFbfSave */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 6, /* N_ANODES - The number of action nodes */ + 3, /* N_DNODES - The number of decision nodes */ + 13, /* N_FLOWS - The number of control flows */ + 6, /* N_ACTIONS - The number of actions */ + 6 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaFbfSave_N2, &CrIaFbfSaveN2); + FwPrAddActionNode(prDesc, CrIaFbfSave_N3, &CrIaFbfSaveN3); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaFbfSave_N1, &CrIaFbfSaveN1); + FwPrAddActionNode(prDesc, CrIaFbfSave_N4, &CrIaFbfSaveN4); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddActionNode(prDesc, CrIaFbfSave_N5, &CrIaFbfSaveN5); + FwPrAddDecisionNode(prDesc, DECISION3, N_OUT_OF_DECISION3); + FwPrAddActionNode(prDesc, CrIaFbfSave_N6, &CrIaFbfSaveN6); + FwPrAddFlowIniToDec(prDesc, DECISION2, NULL); + FwPrAddFlowActToDec(prDesc, CrIaFbfSave_N2, DECISION1, NULL); + FwPrAddFlowActToDec(prDesc, CrIaFbfSave_N3, DECISION1, &CrIaFbfSaveWaitFbfBlckWrDur); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaFbfSave_N3, &CrIaFbfSaveToN3); + FwPrAddFlowDecToDec(prDesc, DECISION1, DECISION3, &code11311); + FwPrAddFlowActToAct(prDesc, CrIaFbfSave_N1, CrIaFbfSave_N2, NULL); + FwPrAddFlowActToFin(prDesc, CrIaFbfSave_N4, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaFbfSave_N1, &CrIaFbfSaveFlag1); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaFbfSave_N5, &code64383); + FwPrAddFlowActToFin(prDesc, CrIaFbfSave_N5, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaFbfSave_N4, &CrIaFbfSaveFlag1); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaFbfSave_N6, &code2535); + FwPrAddFlowActToAct(prDesc, CrIaFbfSave_N6, CrIaFbfSave_N4, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaFbfSaveCreate.h b/CrIa/src/CrIaPrSm/CrIaFbfSaveCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..f2a3e64310a325a284d92910590e81867e848b7c --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfSaveCreate.h @@ -0,0 +1,133 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaFbfSave procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaFbfSave.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: May 4 2016 8:24:50 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaFbfSaveCreate_H_ +#define CrIaFbfSaveCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaFbfSave_N1 1 /* The identifier of action node N1 in procedure CrIaFbfSave */ +#define CrIaFbfSave_N2 2 /* The identifier of action node N2 in procedure CrIaFbfSave */ +#define CrIaFbfSave_N3 3 /* The identifier of action node N3 in procedure CrIaFbfSave */ +#define CrIaFbfSave_N4 4 /* The identifier of action node N4 in procedure CrIaFbfSave */ +#define CrIaFbfSave_N5 5 /* The identifier of action node N5 in procedure CrIaFbfSave */ +#define CrIaFbfSave_N6 6 /* The identifier of action node N6 in procedure CrIaFbfSave */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaFbfSaveCreate(void* prData); + +/** + * Action for node N2. + * <pre> + * Call IBSW operation to transfer + * the first block from RAM Data Area + * to the Target FBF + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfSaveN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Call IBSW operation to transfer + * the next block from RAM Data Area + * to the Target FBF + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfSaveN3(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * <pre> + * Call IBSW operation + * to open the Target FBF + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfSaveN1(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * <pre> + * Call IBSW operation + * to close the Target FBF + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfSaveN4(FwPrDesc_t prDesc); + +/** + * Action for node N5. + * <pre> + * Load EVT_FBF_SAVE_DENIED + * with FBF identifier as parameter + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfSaveN5(FwPrDesc_t prDesc); + +/** + * Action for node N6. + * <pre> + * Load EVT_FBF_SAVE_ABRT + * with FBF identifier and number + * of blocks written as parameters + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaFbfSaveN6(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N2 to DECISION1. + * Wait FBF_BLCK_WR_DUR Cycles + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaFbfSaveWaitFbfBlckWrDur(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N3. + * <pre> + * (Not all requested blocks + * have been written) && !Flag_1 + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaFbfSaveToN3(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N1. + * ! Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaFbfSaveFlag1(FwPrDesc_t prDesc); + +#endif /* CrIaFbfSaveCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaFbfSaveFunc.c b/CrIa/src/CrIaPrSm/CrIaFbfSaveFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..99618454b3b38d6cb1ccebbae011f03cee5d7be9 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfSaveFunc.c @@ -0,0 +1,248 @@ +/** + * @file CrIaFbfSaveFunc.c + * @ingroup CrIaPr + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: May 4 2016 8:24:50 + * + * @brief Implementation of the FBF Save Procedure + * + * Transfer a number of blocks from a RAM data area to a FBF. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaFbfSave function definitions */ +#include "CrIaFbfSaveCreate.h" + +#include <CrIaIasw.h> +#include <Services/General/CrIaConstants.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#if (__sparc__) +#include <ibsw_interface.h> +#endif + +#if (__sparc__) +#include <wrap_malloc.h> /* for SRAM1_FLASH_ADDR */ +#include <iwf_flash.h> +#else +#define FLASH_BLOCKSIZE 0 +#endif + +#include <IfswDebug.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** + * @brief Node 1 of the FBF Save Procedure + * + * @note Deviations from the specifications are given due to differing FLASH handling. Therefore transfering a first block + * do not need a different handling as consecutive blocks. + * + */ + +/** Action for node N1. */ +void CrIaFbfSaveN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId, fbfIndex, writtenblocks; + + writtenblocks = 0; + CrIaPaste(FBFSAVEBLOCKCOUNTER_ID, &writtenblocks); + + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + fbfIndex = fbfId - 1; + + CrIbFbfOpen ((unsigned int)fbfIndex); + + return; +} + +/** Action for node N2. */ +void CrIaFbfSaveN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* No operation */ + return; +} + +/** Action for node N3. */ +void CrIaFbfSaveN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId, fbfIndex, writtenblocks; + unsigned int fbfRamAddr; + + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + fbfIndex = fbfId - 1; + + CrIaCopy(FBFSAVE_PFBFRAMADDR_ID, &fbfRamAddr); + CrIaCopy(FBFSAVEBLOCKCOUNTER_ID, &writtenblocks); + + fbfRamAddr += FLASH_BLOCKSIZE * writtenblocks; + + DEBUGP("Trigger Write, file %d to %x\n", fbfId, (unsigned int)fbfRamAddr); + + CrIbFlashTriggerWrite(fbfIndex, (void *) fbfRamAddr); + + /* Mantis 2127: this instruction was erroneously removed in commit 558472984 */ + writtenblocks++; + CrIaPaste(FBFSAVEBLOCKCOUNTER_ID, &writtenblocks); + + DEBUGP("SF action finished\n"); + + return; +} + + +/** Action for node N4. */ +void CrIaFbfSaveN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Call IBSW operation to close the Target FBF */ + unsigned char fbfId, fbfIndex; + + DEBUGP("CrIaFbfSaveFunc N4: Call IBSW operation to close the Target FBF ...\n"); + + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + fbfIndex = fbfId - 1; + + CrIbFbfClose(fbfIndex); + + return; +} + +/** Action for node N5. */ +void CrIaFbfSaveN5(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId; + unsigned short evt_data[2]; + + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + + /* Load EVT_FBF_SAVE_DENIED with FBF identifier as parameter */ + DEBUGP("Save denied for ID %d\n", fbfId); + + /* Load EVT_SEM_TR */ + evt_data[0] = fbfId; /* FbfId */ + evt_data[1] = 0; /* NOT USED */ + + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FBF_SAVE_DENIED, evt_data, 4); + + return; +} + +/** Action for node N6. */ +void CrIaFbfSaveN6(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId, writtenblocks; + unsigned short evt_data[2]; + + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + CrIaCopy(FBFSAVEBLOCKCOUNTER_ID, &writtenblocks); + + /* Load EVT_FBF_SAVE_ABRT with FBF identifier and number of blocks written as parameter */ + DEBUGP("Save aborted for ID %d after %d written blocks\n", fbfId, writtenblocks); + + /* Load EVT_SEM_TR */ + evt_data[0] = fbfId; + evt_data[1] = writtenblocks; + + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_FBF_SAVE_ABRT, evt_data, 4); + + return; +} + +/** Guard on the Control Flow from N2 to DECISION1. */ +FwPrBool_t CrIaFbfSaveWaitFbfBlckWrDur(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int fbf_blck_wr_dur; + + CrIaCopy(FBF_BLCK_WR_DUR_ID, &fbf_blck_wr_dur); + + /* Mantis 1582: Wait until FLASH is ready, but at least FBF_BLCK_WR_DUR cycles */ + if ((FwPrGetNodeExecCnt(prDesc) >= fbf_blck_wr_dur) && CrIbFlashIsReady()) + return 1; + + return 0; +} + +/** Guard on the Control Flow from DECISION1 to N3. */ +FwPrBool_t CrIaFbfSaveToN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Check if all requested blocks have been written || Flag_1 */ + + unsigned char fbfId, fbfIndex, fbfNBlocks, isSaaActive, fbfValid, fbfEnb, writtenblocks; + + CrIaCopy(FBFSAVE_PFBFNBLOCKS_ID, &fbfNBlocks); + + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + fbfIndex = fbfId - 1; + + CrIaCopyArrayItem (ISFBFVALID_ID, &fbfValid, fbfIndex); + CrIaCopyArrayItem (FBF_ENB_ID, &fbfEnb, fbfIndex); + + CrIaCopy(ISSAAACTIVE_ID, &isSaaActive); + + CrIaCopy(FBFSAVEBLOCKCOUNTER_ID, &writtenblocks); + + if (writtenblocks == fbfNBlocks) + return 0; /* done */ + + if (isSaaActive == 1) + return 0; /* this aborts the transfer */ + + if (fbfValid == 0) + return 0; /* abort */ + + if (fbfEnb == 0) + return 0; /* abort */ + + /* else move on to N3 */ + return 1; +} + +/** Guard on the Control Flow from DECISION2 to N1/N4. */ +FwPrBool_t CrIaFbfSaveFlag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Flag_1 is true if the FBF is disabled, or invalid, or if the spacecraft is crossing the SAA (i.e. isSaaActive is true) */ + + unsigned char fbfId, fbfIndex, isSaaActive, fbfValid, fbfEnb; + + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + fbfIndex = fbfId - 1; + + CrIaCopyArrayItem (ISFBFVALID_ID, &fbfValid, fbfIndex); + CrIaCopyArrayItem (FBF_ENB_ID, &fbfEnb, fbfIndex); + + CrIaCopy(ISSAAACTIVE_ID, &isSaaActive); + + if (isSaaActive == 1) + return 0; /* this aborts the transfer */ + + if (fbfValid == 0) + return 0; /* abort */ + + if (fbfEnb == 0) + return 0; /* abort */ + + /* else move on to N1/N4 */ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaFbfSaveInit.txt b/CrIa/src/CrIaPrSm/CrIaFbfSaveInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..054c77aa541ff1bfd68d342b140d924d2100c404 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFbfSaveInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaFbfSaveCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaFbfSave is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaFbfSave is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaFdCheckCreate.c b/CrIa/src/CrIaPrSm/CrIaFdCheckCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..3ed44890cc79f1c771ec37f00ec3bc18c7f65029 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFdCheckCreate.c @@ -0,0 +1,67 @@ +/** + * @file CrIaFdCheckCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: May 25 2016 8:50:47 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" + +/** CrIaFdCheck function definitions */ +#include "CrIaFdCheckCreate.h" + +/** + * Guard on the transition from CHOICE1 to FAILED. + * (Anomaly Detected) && (FdCheckCnt == FdCheckCntThr) + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwSmBool_t code89795(FwSmDesc_t __attribute__((unused)) smDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t CrIaFdCheckCreate(void* smData) +{ + const FwSmCounterU2_t N_OUT_OF_NOMINAL = 2; /* The number of transitions out of state NOMINAL */ + const FwSmCounterU2_t N_OUT_OF_SUSPECTED = 2; /* The number of transitions out of state SUSPECTED */ + const FwSmCounterU2_t N_OUT_OF_FAILED = 2; /* The number of transitions out of state FAILED */ + const FwSmCounterU2_t N_OUT_OF_DISABLED = 1; /* The number of transitions out of state DISABLED */ + const FwSmCounterU2_t CHOICE1 = 1; /* The identifier of choice pseudo-state CHOICE1 in State Machine CrIaFdCheck */ + const FwSmCounterU2_t N_OUT_OF_CHOICE1 = 3; /* The number of transitions out of the choice-pseudo state CHOICE1 */ + + /** Create state machine smDesc */ + FwSmDesc_t smDesc = FwSmCreate( + 4, /* NSTATES - The number of states */ + 1, /* NCPS - The number of choice pseudo-states */ + 11, /* NTRANS - The number of transitions */ + 10, /* NACTIONS - The number of state and transition actions */ + 6 /* NGUARDS - The number of transition guards */ + ); + + /** Configure the state machine smDesc */ + FwSmSetData(smDesc, smData); + FwSmAddState(smDesc, CrIaFdCheck_NOMINAL, N_OUT_OF_NOMINAL, &CrIaFdCheckNominalEntry, NULL, &CrIaFdCheckNominalDo, NULL); + FwSmAddState(smDesc, CrIaFdCheck_SUSPECTED, N_OUT_OF_SUSPECTED, &CrIaFdCheckSuspectedEntry, NULL, &CrIaFdCheckSuspectedDo, NULL); + FwSmAddState(smDesc, CrIaFdCheck_FAILED, N_OUT_OF_FAILED, &CrIaFdCheckFailedEntry, NULL, &CrIaFdCheckFailedDo, NULL); + FwSmAddState(smDesc, CrIaFdCheck_DISABLED, N_OUT_OF_DISABLED, NULL, &CrIaFdCheckDisabledExit, NULL, NULL); + FwSmAddChoicePseudoState(smDesc, CHOICE1, N_OUT_OF_CHOICE1); + FwSmAddTransStaToSta(smDesc, Execute, CrIaFdCheck_NOMINAL, CrIaFdCheck_DISABLED, NULL, &CrIaFdCheckIsNotEnabled); + FwSmAddTransStaToCps(smDesc, Execute, CrIaFdCheck_NOMINAL, CHOICE1, NULL, &CrIaFdCheckIsEnabled); + FwSmAddTransStaToSta(smDesc, Execute, CrIaFdCheck_SUSPECTED, CrIaFdCheck_DISABLED, NULL, &CrIaFdCheckIsNotEnabled); + FwSmAddTransStaToCps(smDesc, Execute, CrIaFdCheck_SUSPECTED, CHOICE1, NULL, &CrIaFdCheckIsEnabled); + FwSmAddTransStaToSta(smDesc, Execute, CrIaFdCheck_FAILED, CrIaFdCheck_DISABLED, NULL, &CrIaFdCheckIsNotEnabled); + FwSmAddTransStaToCps(smDesc, Execute, CrIaFdCheck_FAILED, CHOICE1, NULL, &CrIaFdCheckIsAnomalyAndEnabled); + FwSmAddTransStaToCps(smDesc, Execute, CrIaFdCheck_DISABLED, CHOICE1, &CrIaFdCheckAnomalyDetCheck, &CrIaFdCheckIsEnabled); + FwSmAddTransIpsToSta(smDesc, CrIaFdCheck_DISABLED, &CrIaFdCheckResetSpCnt); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaFdCheck_SUSPECTED, NULL, &CrIaFdCheckIsAnomalyAndSmallCnt); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaFdCheck_NOMINAL, NULL, &CrIaFdCheckIsNoAnomaly); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaFdCheck_FAILED, &CrIaFdCheckEvtFailed, &code89795); + + return smDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaFdCheckCreate.h b/CrIa/src/CrIaPrSm/CrIaFdCheckCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..f2fbcef67c5ecce0e91cbe1a8b9f15cd0ee86805 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFdCheckCreate.h @@ -0,0 +1,169 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaFdCheck state machine. + * The state machine is configured with a set of function pointers representing the non-default + * actions and guards of the state machine. Some of these functions may also be declared in + * this header file in accordance with the configuration of the state machine in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The state machine created by this file is shown in the figure below. + * @image html CrIaFdCheck.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: May 25 2016 8:50:47 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaFdCheckCreate_H_ +#define CrIaFdCheckCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" + +/** State identifiers */ +#define CrIaFdCheck_DISABLED (1) /* The identifier of state DISABLED in State Machine CrIaFdCheck */ +#define CrIaFdCheck_FAILED (4) /* NOTE: wrong identifier! The identifier of state FAILED in State Machine CrIaFdCheck */ +#define CrIaFdCheck_NOMINAL (2) /* NOTE: wrong identifier! The identifier of state NOMINAL in State Machine CrIaFdCheck */ +#define CrIaFdCheck_SUSPECTED (3) /* NOTE: wrong identifier! The identifier of state SUSPECTED in State Machine CrIaFdCheck */ + +/** The identifiers of transition commands (triggers) */ +#define Execute (0) + +/** + * Create a new state machine descriptor. + * This interface creates the state machine descriptor dynamically. + * @param smData the pointer to the state machine data. + * A value of NULL is legal (note that the default value of the pointer + * to the state machine data when the state machine is created is NULL). + * @return the pointer to the state machine descriptor + */ +FwSmDesc_t CrIaFdCheckCreate(void* smData); + +/** + * Entry Action for the state NOMINAL. + * Set FdCheckCnt to 1 + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckNominalEntry(FwSmDesc_t smDesc); + +/** + * Do Action for the state NOMINAL. + * Anomaly Detection Check + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckNominalDo(FwSmDesc_t smDesc); + +/** + * Entry Action for the state SUSPECTED. + * <pre> + * Increment FdCheckCnt + * Increment FdCheckSpCnt + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckSuspectedEntry(FwSmDesc_t smDesc); + +/** + * Do Action for the state SUSPECTED. + * Anomaly Detection Check + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckSuspectedDo(FwSmDesc_t smDesc); + +/** + * Entry Action for the state FAILED. + * Try Recovery + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckFailedEntry(FwSmDesc_t smDesc); + +/** + * Do Action for the state FAILED. + * <pre> + * Anomaly Detection Check; + * if (Anomaly Detected) TryRecovery + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckFailedDo(FwSmDesc_t smDesc); + +/** + * Exit Action for the state DISABLED. + * <pre> + * FdCheckCounter = 0; + * Initialize Anomaly Detection Check + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckDisabledExit(FwSmDesc_t smDesc); + +/** + * Guard on the transition from NOMINAL to DISABLED. + * <pre> + * FdCheck is + * not Enabled + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaFdCheckIsNotEnabled(FwSmDesc_t smDesc); + +/** + * Guard on the transition from FAILED to CHOICE1. + * (FdCheck is Enabled) && (No Anomaly) + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaFdCheckIsAnomalyAndEnabled(FwSmDesc_t smDesc); + +/** + * Action on the transition from DISABLED to CHOICE1. + * Do Anomaly Detection Check + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckAnomalyDetCheck(FwSmDesc_t smDesc); + +/** + * Guard on the transition from DISABLED to CHOICE1. + * FdCheck is Enabled + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaFdCheckIsEnabled(FwSmDesc_t smDesc); + +/** + * Action on the transition from Initial State to DISABLED. + * FdCheckSpCnt = 0 + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckResetSpCnt(FwSmDesc_t smDesc); + +/** + * Guard on the transition from CHOICE1 to SUSPECTED. + * <pre> + * (Anomaly Detected) && + * (FdCheckCnt < FdCheckCntThr) + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaFdCheckIsAnomalyAndSmallCnt(FwSmDesc_t smDesc); + +/** + * Guard on the transition from CHOICE1 to NOMINAL. + * No Anomaly + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaFdCheckIsNoAnomaly(FwSmDesc_t smDesc); + +/** + * Action on the transition from CHOICE1 to FAILED. + * Generate evt rep. EVT_FD_FAILED + * @param smDesc the state machine descriptor + */ +void CrIaFdCheckEvtFailed(FwSmDesc_t smDesc); + +#endif /* CrIaFdCheckCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaFdCheckFunc.c b/CrIa/src/CrIaPrSm/CrIaFdCheckFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..5937afd64de7c922904a38b96edfa54b37ce52c2 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFdCheckFunc.c @@ -0,0 +1,2051 @@ +/** + * @file CrIaFdCheckFunc.c + * @ingroup CrIaSm + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: May 25 2016 8:50:47 + * + * @brief Implementation of the FdCheck State Machine actions and guards. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" +#include "FwProfile/FwSmCore.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaFdCheck function definitions */ +#include "CrIaFdCheckCreate.h" + +#include <CrIaIasw.h> +#include <CrIaSemEvents.h> /* for flags of type CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_xxx_SET */ + +#include <CrIaPrSm/CrIaIaswCreate.h> /* for StopSem transition of the IASW state machine (SEM Alive Check Recovery Procedure) */ +#include <CrIaPrSm/CrIaSemConsCheckCreate.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <IfswUtilities.h> /* for sort4float(), convertToTempEngVal() */ + +#include <EngineeringAlgorithms.h> + +#include <IfswDebug.h> + +/* local counters for FdCheck SEM Mode Time-Out */ +unsigned int CMD_MODE_TRANSITION_TO_POWERON_Cnt; +unsigned int CMD_MODE_TRANSITION_TO_SAFE_Cnt; +unsigned int CMD_MODE_TRANSITION_TO_STAB_Cnt; +unsigned int CMD_MODE_TRANSITION_TO_TEMP_Cnt; +unsigned int CMD_MODE_TRANSITION_TO_CCDWIN_Cnt; +unsigned int CMD_MODE_TRANSITION_TO_CCDFULL_Cnt; +unsigned int CMD_MODE_TRANSITION_TO_DIAG_Cnt; +unsigned int CMD_MODE_TRANSITION_TO_STANDBY_Cnt; + +/* global handles which signals that the command was sent */ +CrFwBool_t CMD_MODE_TRANSITION_TO_POWERON_Flag; +CrFwBool_t CMD_MODE_TRANSITION_TO_SAFE_Flag; +CrFwBool_t CMD_MODE_TRANSITION_TO_STAB_Flag; +CrFwBool_t CMD_MODE_TRANSITION_TO_TEMP_Flag; +CrFwBool_t CMD_MODE_TRANSITION_TO_CCDWIN_Flag; +CrFwBool_t CMD_MODE_TRANSITION_TO_CCDFULL_Flag; +CrFwBool_t CMD_MODE_TRANSITION_TO_DIAG_Flag; +CrFwBool_t CMD_MODE_TRANSITION_TO_STANDBY_Flag; + +/* set global specific variable to signal other procedures, if an anomaly exist */ +FwSmBool_t AnomalyTelescopeTempMonitorCheck = 0; +FwSmBool_t AnomalyIncorrectSDSCntrCheck = 0; +FwSmBool_t AnomalySemCommErrCheck = 0; +FwSmBool_t AnomalySemModeTimeOutCheck = 0; +FwSmBool_t AnomalySemSafeModeCheck = 0; +FwSmBool_t AnomalySemAliveCheck = 0; +FwSmBool_t AnomalySemAnomalyEventCheck = 0; +FwSmBool_t AnomalySemLimitCheck = 0; +FwSmBool_t AnomalyDpuHousekeepingCheck = 0; +FwSmBool_t AnomalyCentroidConsistencyCheck = 0; +FwSmBool_t AnomalyResourceCheck = 0; +FwSmBool_t AnomalySemModeConsistencyCheck = 0; + +/* Flag_1 for each FdCheck to signal, if recovery procedure is not already executed in state FAILED */ +FwSmBool_t Flag_1_TTM, Flag_1_SDSC, Flag_1_COMERR, Flag_1_TIMEOUT, Flag_1_SAFEMODE, Flag_1_ALIVE, Flag_1_SEMANOEVT; +FwSmBool_t Flag_1_SEMLIMIT, Flag_1_DPUHK, Flag_1_CENTCONS, Flag_1_RES, Flag_1_SEMCONS; + +/* imported global variables */ +extern unsigned short SemHkIaswStateExecCnt; +extern FwSmBool_t flagDelayedSemHkPacket; +extern unsigned int warnLimitDefCnt, alarmLimitDefCnt; +extern unsigned int warnLimitExtCnt, alarmLimitExtCnt; +extern unsigned int semAliveStatusDefCnt, semAliveStatusExtCnt; +extern unsigned short SemAnoEvtId; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** + * Execution of Recovery Procedures + * - Procedure 1: Switch Off SEM + * - Procedure 2: Do nothing + * - Procedure 3: Terminate Science + * - Procedure 4: Stop Heartbeat + * - Procedure 5: Handle SEM Anomaly Event + */ +void executeRecoveryProc(unsigned short recProcId) +{ + unsigned char HeartbeatEnabled = 0; + unsigned short semShutdownT12; + + switch (recProcId) + { + case 1: /* Recovery Procedure 1: Switch Off SEM */ + /* Command the IASW State Machine in state STANDBY (this switches off the SEM) */ + /* Copy "long" time-out SEM_SHUTDOWN_T12 into SEM_SHUTDOWN_T1 */ + /* NOTE: will be restored to default time-out SEM_SHUTDOWN_T11 in SEM Shutdown Procedure */ + CrIaCopy(SEM_SHUTDOWN_T12_ID, &semShutdownT12); + CrIaPaste(SEM_SHUTDOWN_T1_ID, &semShutdownT12); + FwSmMakeTrans(smDescIasw, StopSem); + break; + case 2: /* Recovery Procedure 2: Do nothing */ + break; + case 3: /* Recovery Procedure 3: Terminate Science */ + /* Command the IASW State Machine in state PRE_SCIENCE (this commands the SEM into STABILIZE and + terminates science operation.) */ + FwSmMakeTrans(smDescIasw, StopScience); + break; + case 4: /* Recovery Procedure 4: Stop Heartbeat */ + /* Command the IASW in state STANDBY (this switches off the SEM) and + terminate generation of heartbeat report to request a switch off of the DPU itself */ + FwSmMakeTrans(smDescIasw, StopSem); + CrIaPaste(HEARTBEAT_ENABLED_ID, &HeartbeatEnabled); + break; + case 5: /* Recovery Procedure 5: Handle SEM Anomaly Event */ + /* Run SEM Anomaly Event Recovery Procedure */ + FwPrRun(prDescSemAnoEvtRP); + break; + default: /* Do nothing */ + break; + } + + return; +} + +/** + * @brief Performs the Anomaly Detection Check to check or monitor failure conditions of ... + * + * - Telescope Temperature Monitor + * - Incorrect Science Data Counter + * - SEM Communication Error + * - SEM Mode Time-Out + * - SEM Safe Mode + * - SEM Alive Check + * - SEM Anomaly Event + * - SEM Limit Check + * - DPU Housekeeping Check + * - Centroid Consistency Check + * - Resource Check + * - SEM Mode Consistency Check + * + * @note The anomaly detection for the SEM Communication Error is realized by implemented through the use of counter + * fdSemCommErrCnt which is maintained in module CrIaIasw according to the following logic: + * - The counter is incremented when one of the following events is reported: EVT_SPW_ERR_L, EVT_SPW_ERR_M, EVT_SPW_ERR_H + * - The counter is reset at the end of each cycle + * An anomaly is declared for the SEM Communication Error FdCheck whenever the value of counter fdSemCommErrCnt is greater than zero. + * + * @note The SEM Alive Check will be started automatically by the SEM Unit State Machine in the exit action of the INIT state. + * The first SEM Housekeeping packets arrive later than the pre-defined default period to be checked and therefore an + * additional period is added once. + * + */ + +FwSmBool_t AnomalyDetectionCheck(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* runs Anomaly Detection Check and gives back result 1 (anomaly detected) or 0 (no anomaly detected) */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) /* =========================== Telescope Temperature Monitor ==== */ + { + float Temp1=0, Temp2=0, Temp3=0, Temp4=0; /* initialize variables with default values */ + float Temp[4]; + float median_Temp_Aft_EngVal; + float median_Temp_Frt_EngVal; + float lowerLevel_Temp, upperLevel_Temp, ttm_lim; + float lowerLevel_Temp_Lim, upperLevel_Temp_Lim; + + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for Telescope Temp. Monitor Check ...\n"); + + /* Get temperature measurements from data pool */ + /* AFT Temperatures */ + CrIaCopy(ADC_TEMPOH1B_ID, &Temp1); + CrIaCopy(ADC_TEMPOH2B_ID, &Temp2); + CrIaCopy(ADC_TEMPOH3B_ID, &Temp3); + CrIaCopy(ADC_TEMPOH4B_ID, &Temp4); + + /* Copy engineering values in array */ + Temp[0] = Temp1; + Temp[1] = Temp2; + Temp[2] = Temp3; + Temp[3] = Temp4; + + /* Acquire temperature using majority voting mechanism */ + sort4float (Temp); + + /* Calculate the average of the two middle temperature values */ + median_Temp_Aft_EngVal = (Temp[1] + Temp[2])*0.5; + + /* Get temperature measurements from data pool */ + /* FRT Temperatures */ + CrIaCopy(ADC_TEMPOH1A_ID, &Temp1); + CrIaCopy(ADC_TEMPOH2A_ID, &Temp2); + CrIaCopy(ADC_TEMPOH3A_ID, &Temp3); + CrIaCopy(ADC_TEMPOH4A_ID, &Temp4); + + /* Copy engineering values in array */ + Temp[0] = Temp1; + Temp[1] = Temp2; + Temp[2] = Temp3; + Temp[3] = Temp4; + + /* Acquire temperature using majority voting mechanism */ + sort4float (Temp); + + /* Calculate the average of the two middle temperature values */ + median_Temp_Frt_EngVal = (Temp[1] + Temp[2])*0.5; + + /* Get all temperature limits from data pool */ + CrIaCopy(TTC_LL_ID, &lowerLevel_Temp); + CrIaCopy(TTC_UL_ID, &upperLevel_Temp); + CrIaCopy(TTM_LIM_ID, &ttm_lim); + + /* Calculate total upper and lower temperature limit */ + upperLevel_Temp_Lim = upperLevel_Temp + ttm_lim; + lowerLevel_Temp_Lim = lowerLevel_Temp - ttm_lim; + + DEBUGP("FdCheck TTM: median_Temp_Aft_EngVal = %f°C, median_Temp_Frt_EngVal = %f°C\n", median_Temp_Aft_EngVal, median_Temp_Frt_EngVal); + DEBUGP("FdCheck TTM: temperature range: %f°C < T < %f°C\n", lowerLevel_Temp_Lim, upperLevel_Temp_Lim); + + /* Check if temperatures are in nominal range [ TTC_LL-TTM_LIM < T < TTC_UL+TTM_LIM ] */ + if ((median_Temp_Aft_EngVal > upperLevel_Temp_Lim) || + (median_Temp_Frt_EngVal > upperLevel_Temp_Lim) || + (median_Temp_Aft_EngVal < lowerLevel_Temp_Lim) || + (median_Temp_Frt_EngVal < lowerLevel_Temp_Lim)) + { + AnomalyTelescopeTempMonitorCheck = 1; + return 1; + } + + AnomalyTelescopeTempMonitorCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdIncorrectSDSCntrCheck) /* ===================== Incorrect Science Data Sequence Counter ==== */ + { + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for Incorrect Science Data Sequence Counter Check ...\n"); + + if (FD_SDSC_ILL_Flag || FD_SDSC_OOS_Flag) + { + FD_SDSC_ILL_Flag = 0; + FD_SDSC_OOS_Flag = 0; + AnomalyIncorrectSDSCntrCheck = 1; + return 1; + } + + AnomalyIncorrectSDSCntrCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdSemCommErrCheck) /* =========================================== SEM Communication Error ==== */ + { + if (fdSemCommErrCnt > 0) + { + AnomalySemCommErrCheck = 1; + return 1; + } + + AnomalySemCommErrCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdSemModeTimeOutCheck) /* ============================================= SEM Mode Time-Out ==== */ + { + unsigned int semToPoweronThr, semToSafeThr, semToStabThr, semToTempThr, semToCcdThr, semToDiagThr, semToStandbyThr; + + /* Get Counter Thresholds */ + CrIaCopy(SEM_TO_POWERON_ID, &semToPoweronThr); + CrIaCopy(SEM_TO_SAFE_ID, &semToSafeThr); + CrIaCopy(SEM_TO_STAB_ID, &semToStabThr); + CrIaCopy(SEM_TO_TEMP_ID, &semToTempThr); + CrIaCopy(SEM_TO_CCD_ID, &semToCcdThr); + CrIaCopy(SEM_TO_DIAG_ID, &semToDiagThr); + CrIaCopy(SEM_TO_STANDBY_ID, &semToStandbyThr); + + /* ### POWERON ### */ + + if (CMD_MODE_TRANSITION_TO_POWERON_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_FD_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_POWERON_Cnt = 0; + CMD_MODE_TRANSITION_TO_POWERON_Flag = 0; + CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_FD_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_POWERON_Cnt++; + } + + if (CMD_MODE_TRANSITION_TO_POWERON_Cnt < semToPoweronThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_POWERON_Cnt = 0; + CMD_MODE_TRANSITION_TO_POWERON_Flag = 0; + CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_FD_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + /* ### SAFE ### */ + + if (CMD_MODE_TRANSITION_TO_SAFE_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_FD_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_SAFE_Cnt = 0; + CMD_MODE_TRANSITION_TO_SAFE_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_FD_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_SAFE_Cnt++; + } + + if (CMD_MODE_TRANSITION_TO_SAFE_Cnt < semToSafeThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_SAFE_Cnt = 0; + CMD_MODE_TRANSITION_TO_SAFE_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_FD_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + /* ### STABILIZE ### */ + + if (CMD_MODE_TRANSITION_TO_STAB_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STAB_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_STAB_Cnt = 0; + CMD_MODE_TRANSITION_TO_STAB_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STAB_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_STAB_Cnt++; + } + + if (CMD_MODE_TRANSITION_TO_STAB_Cnt < semToStabThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_STAB_Cnt = 0; + CMD_MODE_TRANSITION_TO_STAB_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STAB_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + /* ### TEMPERATURE STABLE ### */ + + if (CMD_MODE_TRANSITION_TO_TEMP_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_FD_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_TEMP_Cnt = 0; + CMD_MODE_TRANSITION_TO_TEMP_Flag = 0; + CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_FD_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_TEMP_Cnt++; + } + + if (CMD_MODE_TRANSITION_TO_TEMP_Cnt < semToTempThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_TEMP_Cnt = 0; + CMD_MODE_TRANSITION_TO_TEMP_Flag = 0; + CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_FD_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + /* ### CCD WIN ### */ + + if (CMD_MODE_TRANSITION_TO_CCDWIN_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDWIN_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_CCDWIN_Cnt = 0; + CMD_MODE_TRANSITION_TO_CCDWIN_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDWIN_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_CCDWIN_Cnt++; + } + + + if (CMD_MODE_TRANSITION_TO_CCDWIN_Cnt < semToCcdThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_CCDWIN_Cnt = 0; + CMD_MODE_TRANSITION_TO_CCDWIN_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDWIN_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + /* ### CCD FULL ### */ + + if (CMD_MODE_TRANSITION_TO_CCDFULL_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDFULL_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_CCDFULL_Cnt = 0; + CMD_MODE_TRANSITION_TO_CCDFULL_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDFULL_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_CCDFULL_Cnt++; + } + + if (CMD_MODE_TRANSITION_TO_CCDFULL_Cnt < semToCcdThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_CCDFULL_Cnt = 0; + CMD_MODE_TRANSITION_TO_CCDFULL_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDFULL_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + /* ### DIAG ### */ + + if (CMD_MODE_TRANSITION_TO_DIAG_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_DIAG_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_DIAG_Cnt = 0; + CMD_MODE_TRANSITION_TO_DIAG_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_DIAG_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_DIAG_Cnt++; + } + + if (CMD_MODE_TRANSITION_TO_DIAG_Cnt < semToDiagThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_DIAG_Cnt = 0; + CMD_MODE_TRANSITION_TO_DIAG_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_DIAG_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + /* ### STANDBY ### */ + + if (CMD_MODE_TRANSITION_TO_STANDBY_Flag) + { + if (CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET) + { + /* expected Event was received: reset all counters and flags */ + CMD_MODE_TRANSITION_TO_STANDBY_Cnt = 0; + CMD_MODE_TRANSITION_TO_STANDBY_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET = 0; + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* no expected Event was received so far: increment counter */ + CMD_MODE_TRANSITION_TO_STANDBY_Cnt++; + } + + if (CMD_MODE_TRANSITION_TO_STANDBY_Cnt < semToStandbyThr) + { + AnomalySemModeTimeOutCheck = 0; + } + else + { + /* reset all counters and flags and return Anomaly */ + CMD_MODE_TRANSITION_TO_STANDBY_Cnt = 0; + CMD_MODE_TRANSITION_TO_STANDBY_Flag = 0; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET = 0; + AnomalySemModeTimeOutCheck = 1; + return 1; + } + } + + AnomalySemModeTimeOutCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdSemSafeModeCheck) /* ============================================== SEM Safe Mode Check ==== */ + { + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for SEM Safe Mode Check ...\n"); + + /* check if event signals the entry of SEM in SAFE mode */ + if (CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_SET != 0) + { + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_SET = 0; + AnomalySemSafeModeCheck = 1; + return 1; + } + + AnomalySemSafeModeCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdSemAliveCheck) /* ===================================================== SEM Alive Check ==== */ + { + unsigned short SemHkDefPer, SemHkDelay; + unsigned short IaswStateExecCnt, IaswStateExecCntDiff = 0; + + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for SEM Alive Check ...\n"); + + /* get parameter SEM HK Defined Period */ + CrIaCopy(SEM_HK_DEF_PER_ID, &SemHkDefPer); + if (flagDelayedSemHkPacket) + { + CrIaCopy(SEMALIVE_DELAYEDSEMHK_ID, &SemHkDelay); + SemHkDefPer += SemHkDelay; + } + + /* get actual IASW cycle counter information */ + IaswStateExecCnt = FwSmGetExecCnt(smDescIasw); + + /* check, if counter reset occured in the meantime */ + if (IaswStateExecCnt >= SemHkIaswStateExecCnt) + { + IaswStateExecCntDiff = IaswStateExecCnt - SemHkIaswStateExecCnt; + } + else /* counter reset occured in the meantime ! */ + { + IaswStateExecCntDiff = 65535 - SemHkIaswStateExecCnt + IaswStateExecCnt; + } + + if (IaswStateExecCntDiff >= SemHkDefPer) + { + AnomalySemAliveCheck = 1; + return 1; + } + + AnomalySemAliveCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdSemAnomalyEventCheck) /* ============================================ SEM Anomaly Event ==== */ + { + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for SEM Anomaly Event ...\n"); + + if (SemAnoEvtId > 0) + { + AnomalySemAnomalyEventCheck = 1; + return 1; + } + + AnomalySemAnomalyEventCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdSemLimitCheck) /* ===================================================== SEM Limit Check ==== */ + { + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for SEM Limit Check ...\n"); + + /* Mantis 2182 */ + if (((semAliveStatusDefCnt == 0) && (alarmLimitDefCnt > 0) && (warnLimitDefCnt > 1)) || + ((semAliveStatusExtCnt == 0) && (alarmLimitExtCnt > 0) && (warnLimitExtCnt > 1))) + { + AnomalySemLimitCheck = 1; + return 1; + } + + AnomalySemLimitCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdDpuHousekeepingCheck) /* ======================================= DPU Housekeeping Check ==== */ + { + unsigned short dpuHkLimits; + + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for DPU Housekeeping Check ...\n"); + + dpuHkLimits = checkDpuHkLimits(); + + if (dpuHkLimits > 0) + { + AnomalyDpuHousekeepingCheck = 1; + return 1; + } + + AnomalyDpuHousekeepingCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdCentroidConsistencyCheck) /* =============================== Centroid Consistency Check ==== */ + { + unsigned short iaswState; + unsigned int acqImageCnt; + unsigned char validityStatus, centValProcOutput; + + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for Centroid Consistency Check ...\n"); + + CrIaCopy(IASWSTATE_ID, &iaswState); + CrIaCopy(ACQIMAGECNT_ID, &acqImageCnt); + CrIaCopy(VALIDITYSTATUS_ID, &validityStatus); + CrIaCopy(CENTVALPROCOUTPUT_ID, ¢ValProcOutput); + + /* Mantis 2174: only check consistency in valid states */ + if ((validityStatus == CEN_VAL_WINDOW) || (validityStatus == CEN_VAL_FULL)) + { + /* NOTE: centValProcOutput is assigned the same value as validityStatus in the CentValProc, + but if an inconsistency is found it will become 0xEE, thus be != to the validityStatus */ + if ((iaswState == CrIaIasw_SCIENCE) && (acqImageCnt > 0) && (validityStatus != centValProcOutput)) + { + AnomalyCentroidConsistencyCheck = 1; + return 1; + } + } + + AnomalyCentroidConsistencyCheck = 0; + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdResourceCheck) /* ====================================================== Resource Check ==== */ + { + unsigned short resources; + + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for Resource Check ...\n"); + + resources = checkResources(); + + if (resources > 0) + { + AnomalyResourceCheck = 1; + return 1; + } + + AnomalyResourceCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + if (smDesc == smDescFdSemModeConsistencyCheck) /* ================================ SEM Mode Consistency Check ==== */ + { + prDescSemConsFdCheck_t prData; + prDescSemConsFdCheck_t* prDataPtr; + + DEBUGP("FdCheck-AnomalyDetectionCheck: run Anomaly Detection Check for Resource Check ...\n"); + + /* Set prData of procedure */ + /* initial setting of prData */ + prData.anomaly = 0; + FwPrSetData(prDescSemModeConsistencyCheck, &prData); + + FwPrRun(prDescSemModeConsistencyCheck); + + prDataPtr = (prDescSemConsFdCheck_t*)FwPrGetData(prDescSemModeConsistencyCheck); + + if (prDataPtr->anomaly == 1) + { + AnomalySemModeConsistencyCheck = 1; + return 1; + } + + AnomalySemModeConsistencyCheck = 0; + + return 0; + } /* =========================================================================================================== */ + + DEBUGP("FdCheck-AnomalyDetectionCheck: Anomaly Detection Check can not be done for unknown FdCheckId!\n"); + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** + * @brief Performs Recovery Procedures associated to the Failure Detection Checks, which are ... + * + * - Switch Off SEM + * - Terminate Science + * - Stop Heartbeat + * - Handle SEM Anomaly Event [not implemented yet] + * + */ + +void TryRecovery(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char RecProcGlbEn, RecProcIntEn, RecProcExtEn; + unsigned short evt_data[2]; + + /* try specific recovery with predefined procedures */ + /* if (Recovery Procedure associated to FdCheck is enabled) { */ + /* Generate event report EVT_RP_STARTED; */ + /* FdIntEnabled=FALSE; // This disables the FdCheck */ + /* Start Recovery Procedure associated to the FdCheck */ + /* } */ + + CrIaCopy(RPGLBENABLE_ID, &RecProcGlbEn); + + if (RecProcGlbEn == 1) + { + + if (smDesc == smDescFdTelescopeTempMonitorCheck) /* ======================= Telescope Temperature Monitor ==== */ + { + CrIaCopy(RPTTMINTEN_ID, &RecProcIntEn); + CrIaCopy(RPTTMEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_TTM) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for Telescope Temp. Monitor Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_TS_TEMP; /* FdCheckId */ + evt_data[1] = REP_STOP_HB; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 4: Stop Heartbeat */ + /* Command the IASW in state STANDBY (this switches off the SEM) and + terminate generation of heartbeat report to request a switch off of the DPU itself */ + executeRecoveryProc(4); + + /* Set Flag_1 to zero */ + Flag_1_TTM = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdIncorrectSDSCntrCheck) /* ================= Incorrect Science Data Sequence Counter ==== */ + { + CrIaCopy(RPSDSCINTEN_ID, &RecProcIntEn); + CrIaCopy(RPSDSCEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_SDSC) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for Incorrect Science Data Seqeunce Counter ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_ILL_CNT; /* FdCheckId */ + evt_data[1] = REP_TERM_SCI; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 3: Terminate Science */ + /* Command the IASW State Machine in state PRE_SCIENCE (this commands the SEM into STABILIZE and + terminates science operation.) */ + executeRecoveryProc(3); + + /* Set Flag_1 to zero */ + Flag_1_SDSC = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdSemCommErrCheck) /* ======================================= SEM Communication Error ==== */ + { + CrIaCopy(RPCOMERRINTEN_ID, &RecProcIntEn); + CrIaCopy(RPCOMERREXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_COMERR) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for SEM Communication Error ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_SEM_COMM; /* FdCheckId */ + evt_data[1] = REP_SEM_OFF; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 1: Switch Off SEM */ + /* Command the IASW State Machine in state STANDBY (this switches off the SEM) */ + executeRecoveryProc(1); + + /* Set Flag_1 to zero */ + Flag_1_COMERR = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdSemModeTimeOutCheck) /* ========================================= SEM Mode Time-Out ==== */ + { + CrIaCopy(RPTIMEOUTINTEN_ID, &RecProcIntEn); + CrIaCopy(RPTIMEOUTEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_TIMEOUT) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for SEM Mode Time-Out ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_SEM_TO; /* FdCheckId */ + evt_data[1] = REP_SEM_OFF; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 1: Switch Off SEM */ + /* Command the IASW State Machine in state STANDBY (this switches off the SEM) */ + executeRecoveryProc(1); + + /* Set Flag_1 to zero */ + Flag_1_TIMEOUT = 0; + + } + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdSemSafeModeCheck) /* ========================================== SEM Safe Mode Check ==== */ + { + CrIaCopy(RPSAFEMODEINTEN_ID, &RecProcIntEn); + CrIaCopy(RPSAFEMODEEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_SAFEMODE) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for SEM Safe Mode Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_SEM_SM; /* FdCheckId */ + evt_data[1] = REP_TERM_SCI; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 3: Terminate Science */ + /* Command the IASW State Machine in state PRE_SCIENCE (this commands the SEM into STABILIZE and + terminates science operation.) */ + executeRecoveryProc(3); + + /* Set Flag_1 to zero */ + Flag_1_SAFEMODE = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdSemAliveCheck) /* ================================================= SEM Alive Check ==== */ + { + CrIaCopy(RPALIVEINTEN_ID, &RecProcIntEn); + CrIaCopy(RPALIVEEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_ALIVE) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for SEM Alive Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_SEM_ALIVE; /* FdCheckId */ + evt_data[1] = REP_SEM_OFF; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 1: Switch Off SEM */ + /* Command the IASW State Machine in state STANDBY (this switches off the SEM) */ + executeRecoveryProc(1); + + /* Set Flag_1 to zero */ + Flag_1_ALIVE = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdSemAnomalyEventCheck) /* ======================================== SEM Anomaly Event ==== */ + { + CrIaCopy(RPSEMANOEVTINTEN_ID, &RecProcIntEn); + CrIaCopy(RPSEMANOEVTEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_SEMANOEVT) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for SEM Anomaly Event ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_EVT1; /* FdCheckId */ + evt_data[1] = REP_SEM_AE; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 5: Handle SEM Anomaly Event */ + /* Run SEM Anomaly Event Recovery Procedure */ + executeRecoveryProc(5); + + /* Set Flag_1 to zero */ + Flag_1_SEMANOEVT = 0; + + }; + + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdSemLimitCheck) /* ================================================= SEM Limit Check ==== */ + { + CrIaCopy(RPSEMLIMITINTEN_ID, &RecProcIntEn); + CrIaCopy(RPSEMLIMITEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_SEMLIMIT) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for SEM Limit Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_SEM_OOL; /* FdCheckId */ + evt_data[1] = REP_SEM_OFF; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 1: Switch Off SEM */ + /* Command the IASW State Machine in state STANDBY (this switches off the SEM) */ + executeRecoveryProc(1); + + /* Set Flag_1 to zero */ + Flag_1_SEMLIMIT = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdDpuHousekeepingCheck) /* =================================== DPU Housekeeping Check ==== */ + { + CrIaCopy(RPDPUHKINTEN_ID, &RecProcIntEn); + CrIaCopy(RPDPUHKEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_DPUHK) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for DPU Housekeeping Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_PSDU_OOL; /* FdCheckId */ + evt_data[1] = REP_STOP_HB; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 4: Stop Heartbeat */ + /* Command the IASW in state STANDBY (this switches off the SEM) and + terminate generation of heartbeat report to request a switch off of the DPU itself */ + executeRecoveryProc(4); + + /* Set Flag_1 to zero */ + Flag_1_DPUHK = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdCentroidConsistencyCheck) /* =========================== Centroid Consistency Check ==== */ + { + CrIaCopy(RPCENTCONSINTEN_ID, &RecProcIntEn); + CrIaCopy(RPCENTCONSEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_CENTCONS) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for Centroid Consistency Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_CENT_CONS; /* FdCheckId */ + evt_data[1] = REP_STOP_HB; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 4: Stop Heartbeat */ + /* Command the IASW in state STANDBY (this switches off the SEM) and + terminate generation of heartbeat report to request a switch off of the DPU itself */ + executeRecoveryProc(4); + + /* Set Flag_1 to zero */ + Flag_1_CENTCONS = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdResourceCheck) /* ================================================== Resource Check ==== */ + { + CrIaCopy(RPRESINTEN_ID, &RecProcIntEn); + CrIaCopy(RPRESEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_RES) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for Centroid Consistency Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_RES; /* FdCheckId */ + evt_data[1] = REP_STOP_HB; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 4: Stop Heartbeat */ + /* Command the IASW in state STANDBY (this switches off the SEM) and + terminate generation of heartbeat report to request a switch off of the DPU itself */ + executeRecoveryProc(4); + + /* Set Flag_1 to zero */ + Flag_1_RES = 0; + + }; + return; + } /* ======================================================================================================= */ + + if (smDesc == smDescFdSemModeConsistencyCheck) /* ============================ SEM Mode Consistency Check ==== */ + { + CrIaCopy(RPSEMCONSINTEN_ID, &RecProcIntEn); + CrIaCopy(RPSEMCONSEXTEN_ID, &RecProcExtEn); + if ((RecProcIntEn == 1) && (RecProcExtEn == 1) && Flag_1_SEMCONS) + { + + DEBUGP("FdCheck-TryRecovery: Try Recovery for SEM Mode Consistency Check ...\n"); + + /* Generate event report EVT_RP_STARTED */ + evt_data[0] = FDC_SEM_CONS; /* FdCheckId */ + evt_data[1] = REP_SEM_OFF; /* RecovProcId */ + + CrIaEvtRep(4, CRIA_SERV5_EVT_RP_STARTED, evt_data, 4); + + /* Recovery Procedure 1: Switch Off SEM */ + /* Command the IASW State Machine in state STANDBY (this switches off the SEM) */ + executeRecoveryProc(1); + + /* Set Flag_1 to zero */ + Flag_1_SEMCONS = 0; + + }; + return; + } /* ======================================================================================================= */ + + DEBUGP("FdCheck-TryRecovery: Try Recovery can not be done for unknown FdCheckId!\n"); + + } + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Entry Action for the state NOMINAL. */ +void CrIaFdCheckNominalEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short FdCheckCnt = 1; + + /* Set FdCheckCnt to 1 */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + CrIaPaste(FDCHECKTTMCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + CrIaPaste(FDCHECKSDSCCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdSemCommErrCheck) + CrIaPaste(FDCHECKCOMERRCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdSemModeTimeOutCheck) + CrIaPaste(FDCHECKTIMEOUTCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdSemSafeModeCheck) + CrIaPaste(FDCHECKSAFEMODECNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdSemAliveCheck) + CrIaPaste(FDCHECKALIVECNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdSemAnomalyEventCheck) + CrIaPaste(FDCHECKSEMANOEVTCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdSemLimitCheck) + CrIaPaste(FDCHECKSEMLIMITCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdDpuHousekeepingCheck) + CrIaPaste(FDCHECKDPUHKCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdCentroidConsistencyCheck) + CrIaPaste(FDCHECKCENTCONSCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdResourceCheck) + CrIaPaste(FDCHECKRESCNT_ID, &FdCheckCnt); + + if (smDesc == smDescFdSemModeConsistencyCheck) + CrIaPaste(FDCHECKSEMCONSCNT_ID, &FdCheckCnt); + + return; +} + +/** Do Action for the state NOMINAL. */ +void CrIaFdCheckNominalDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Anomaly Detection Check */ + + AnomalyDetectionCheck(smDesc); + + return; +} + +/** Entry Action for the state SUSPECTED. */ +void CrIaFdCheckSuspectedEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short FdCheckCnt, FdCheckSpCnt; + + /* Increment FdCheckCnt */ + /* Increment FdCheckSpCnt */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + { + CrIaCopy(FDCHECKTTMCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKTTMCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (Telescope Temperature Monitor) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKTTMSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKTTMSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (Telescope Temperature Monitor) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + { + CrIaCopy(FDCHECKSDSCCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKSDSCCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (Incorrect Science Data Sequence Counter) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKSDSCSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKSDSCSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (Incorrect Science Data Sequence Counter) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdSemCommErrCheck) + { + CrIaCopy(FDCHECKCOMERRCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKCOMERRCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (SEM Communication Error) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKCOMERRSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKCOMERRSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (SEM Communication Error) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdSemModeTimeOutCheck) + { + CrIaCopy(FDCHECKTIMEOUTCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKTIMEOUTCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (SEM Mode Time-Out) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKTIMEOUTSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKTIMEOUTSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (SEM Mode Time-Out) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdSemSafeModeCheck) + { + CrIaCopy(FDCHECKSAFEMODECNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKSAFEMODECNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (SEM Safe Mode) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKSAFEMODESPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKSAFEMODESPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (SEM Safe Mode) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdSemAliveCheck) + { + CrIaCopy(FDCHECKALIVECNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKALIVECNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (SEM Alive) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKALIVESPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKALIVESPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (SEM Alive) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdSemAnomalyEventCheck) + { + CrIaCopy(FDCHECKSEMANOEVTCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKSEMANOEVTCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (SEM Anomaly Event) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKSEMANOEVTSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKSEMANOEVTSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (SEM Anomaly Event) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdSemLimitCheck) + { + CrIaCopy(FDCHECKSEMLIMITCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKSEMLIMITCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (SEM Limit) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKSEMLIMITSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKSEMLIMITSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (SEM Limit) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdDpuHousekeepingCheck) + { + CrIaCopy(FDCHECKDPUHKCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKDPUHKCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (DPU Housekeeping) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKDPUHKSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKDPUHKSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (DPU Housekeeping) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdCentroidConsistencyCheck) + { + CrIaCopy(FDCHECKCENTCONSCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKCENTCONSCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (Centroid Consistency) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKCENTCONSSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKCENTCONSSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (Centroid Consistency) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdResourceCheck) + { + CrIaCopy(FDCHECKRESCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKRESCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (Resource) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKRESSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKRESSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (Resource) = %d\n", FdCheckSpCnt); + }; + + if (smDesc == smDescFdSemModeConsistencyCheck) + { + CrIaCopy(FDCHECKSEMCONSCNT_ID, &FdCheckCnt); + FdCheckCnt++; + CrIaPaste(FDCHECKSEMCONSCNT_ID, &FdCheckCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckCnt (Resource) = %d\n", FdCheckCnt); + CrIaCopy(FDCHECKSEMCONSSPCNT_ID, &FdCheckSpCnt); + FdCheckSpCnt++; + CrIaPaste(FDCHECKSEMCONSSPCNT_ID, &FdCheckSpCnt); + DEBUGP("FdCheck-CrIaFdCheckSuspectedEntry: FdCheckSpCnt (Resource) = %d\n", FdCheckSpCnt); + }; + + return; +} + +/** Do Action for the state SUSPECTED. */ +void CrIaFdCheckSuspectedDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Anomaly Detection Check */ + + AnomalyDetectionCheck(smDesc); + + return; +} + +/** Entry Action for the state FAILED. */ +void CrIaFdCheckFailedEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Try Recovery */ + + Flag_1_TTM = 1; + Flag_1_SDSC = 1; + Flag_1_COMERR = 1; + Flag_1_TIMEOUT = 1; + Flag_1_SAFEMODE = 1; + Flag_1_ALIVE = 1; + Flag_1_SEMANOEVT = 1; + Flag_1_SEMLIMIT = 1; + Flag_1_DPUHK = 1; + Flag_1_CENTCONS = 1; + Flag_1_RES = 1; + Flag_1_SEMCONS = 1; + + DEBUGP("FdCheck-CrIaFdCheckFailedEntry: Try Recovery\n"); + TryRecovery(smDesc); + + return; +} + +/** Do Action for the state FAILED. */ +void CrIaFdCheckFailedDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmBool_t Anomaly; + + /* Anomaly Detection Check */ + /* If (Anomaly Detected) Try Recovery */ + + Anomaly = AnomalyDetectionCheck(smDesc); + + if (Anomaly == 1) + { + DEBUGP("FdCheck-CrIaFdCheckFailedDo: Try Recovery\n"); + TryRecovery(smDesc); + }; + + return; +} + +/** Exit Action for the state DISABLED. */ +void CrIaFdCheckDisabledExit(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short FdCheckCnt = 0; + + /* FdCheckCounter = 0 */ + /* Initialize Anomaly Detection Check */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + { + CrIaPaste(FDCHECKTTMCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + { + CrIaPaste(FDCHECKSDSCCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdSemCommErrCheck) + { + CrIaPaste(FDCHECKCOMERRCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdSemModeTimeOutCheck) + { + CrIaPaste(FDCHECKTIMEOUTCNT_ID, &FdCheckCnt); + + /* Initialization */ + /* Mantis 2076: Reset all counters for FdCheck SEM Mode Time-Out */ + CMD_MODE_TRANSITION_TO_POWERON_Cnt = 0; + CMD_MODE_TRANSITION_TO_SAFE_Cnt = 0; + CMD_MODE_TRANSITION_TO_STAB_Cnt = 0; + CMD_MODE_TRANSITION_TO_TEMP_Cnt = 0; + CMD_MODE_TRANSITION_TO_CCDWIN_Cnt = 0; + CMD_MODE_TRANSITION_TO_CCDFULL_Cnt = 0; + CMD_MODE_TRANSITION_TO_DIAG_Cnt = 0; + CMD_MODE_TRANSITION_TO_STANDBY_Cnt = 0; + }; + + if (smDesc == smDescFdSemSafeModeCheck) + { + CrIaPaste(FDCHECKSAFEMODECNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdSemAliveCheck) + { + CrIaPaste(FDCHECKALIVECNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdSemAnomalyEventCheck) + { + CrIaPaste(FDCHECKSEMANOEVTCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdSemLimitCheck) + { + CrIaPaste(FDCHECKSEMLIMITCNT_ID, &FdCheckCnt); + + /* Initialization */ + /* Mantis 2182 */ + ClearWarnLimit(); + + alarmLimitDefCnt = 0; + warnLimitDefCnt = 0; + + alarmLimitExtCnt = 0; + warnLimitExtCnt = 0; + + ClearAliveLimit(); + + semAliveStatusDefCnt = 0; + semAliveStatusExtCnt = 0; + }; + + if (smDesc == smDescFdDpuHousekeepingCheck) + { + CrIaPaste(FDCHECKDPUHKCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdCentroidConsistencyCheck) + { + CrIaPaste(FDCHECKCENTCONSCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdResourceCheck) + { + CrIaPaste(FDCHECKRESCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + if (smDesc == smDescFdSemModeConsistencyCheck) + { + CrIaPaste(FDCHECKRESCNT_ID, &FdCheckCnt); + + /* Initialization */ + + }; + + return; +} + +/** Guard on the transition from NOMINAL to DISABLED. */ +FwSmBool_t CrIaFdCheckIsNotEnabled(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char FdCheckGlbEn, FdCheckIntEn = 0, FdCheckExtEn = 0; + + /* Execute [ FdCheck is not Enabled ] */ + + CrIaCopy(FDGLBENABLE_ID, &FdCheckGlbEn); + + if (FdCheckGlbEn == 1) + { + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + { + CrIaCopy(FDCHECKTTMINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKTTMEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + { + CrIaCopy(FDCHECKSDSCINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSDSCEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemCommErrCheck) + { + CrIaCopy(FDCHECKCOMERRINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKCOMERREXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemModeTimeOutCheck) + { + CrIaCopy(FDCHECKTIMEOUTINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKTIMEOUTEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemSafeModeCheck) + { + CrIaCopy(FDCHECKSAFEMODEINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSAFEMODEEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemAliveCheck) + { + CrIaCopy(FDCHECKALIVEINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKALIVEEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemAnomalyEventCheck) + { + CrIaCopy(FDCHECKSEMANOEVTINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMANOEVTEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemLimitCheck) + { + CrIaCopy(FDCHECKSEMLIMITINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMLIMITEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdDpuHousekeepingCheck) + { + CrIaCopy(FDCHECKDPUHKINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKDPUHKEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdCentroidConsistencyCheck) + { + CrIaCopy(FDCHECKCENTCONSINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKCENTCONSEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdResourceCheck) + { + CrIaCopy(FDCHECKRESINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKRESEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemModeConsistencyCheck) + { + CrIaCopy(FDCHECKSEMCONSINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMCONSEXTEN_ID, &FdCheckExtEn); + }; + + if ((FdCheckIntEn == 1) && (FdCheckExtEn == 1)) + return 0; + + }; + + return 1; +} + +/** Guard on the transition from FAILED to CHOICE1. */ +FwSmBool_t CrIaFdCheckIsAnomalyAndEnabled(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmBool_t Anomaly = 0; + unsigned char FdCheckGlbEn, FdCheckIntEn = 0, FdCheckExtEn = 0; + + /* Execute [ (FdCheck is Enabled) && (No Anomaly) ] */ + + CrIaCopy(FDGLBENABLE_ID, &FdCheckGlbEn); + + if (FdCheckGlbEn == 1) + { + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + { + CrIaCopy(FDCHECKTTMINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKTTMEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalyTelescopeTempMonitorCheck; + }; + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + { + CrIaCopy(FDCHECKSDSCINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSDSCEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalyIncorrectSDSCntrCheck; + }; + + if (smDesc == smDescFdSemCommErrCheck) + { + CrIaCopy(FDCHECKCOMERRINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKCOMERREXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalySemCommErrCheck; + }; + + if (smDesc == smDescFdSemModeTimeOutCheck) + { + CrIaCopy(FDCHECKTIMEOUTINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKTIMEOUTEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalySemModeTimeOutCheck; + }; + + if (smDesc == smDescFdSemSafeModeCheck) + { + CrIaCopy(FDCHECKSAFEMODEINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSAFEMODEEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalySemSafeModeCheck; + }; + + if (smDesc == smDescFdSemAliveCheck) + { + CrIaCopy(FDCHECKALIVEINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKALIVEEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalySemAliveCheck; + }; + + if (smDesc == smDescFdSemAnomalyEventCheck) + { + CrIaCopy(FDCHECKSEMANOEVTINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMANOEVTEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalySemAnomalyEventCheck; + }; + + if (smDesc == smDescFdSemLimitCheck) + { + CrIaCopy(FDCHECKSEMLIMITINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMLIMITEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalySemLimitCheck; + }; + + if (smDesc == smDescFdDpuHousekeepingCheck) + { + CrIaCopy(FDCHECKDPUHKINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKDPUHKEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalyDpuHousekeepingCheck; + }; + + if (smDesc == smDescFdCentroidConsistencyCheck) + { + CrIaCopy(FDCHECKCENTCONSINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKCENTCONSEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalyCentroidConsistencyCheck; + }; + + if (smDesc == smDescFdResourceCheck) + { + CrIaCopy(FDCHECKRESINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKRESEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalyResourceCheck; + }; + + if (smDesc == smDescFdSemModeConsistencyCheck) + { + CrIaCopy(FDCHECKSEMCONSINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMCONSEXTEN_ID, &FdCheckExtEn); + Anomaly = AnomalySemModeConsistencyCheck; + }; + + if ((FdCheckIntEn == 1) && (FdCheckExtEn == 1) && (Anomaly == 0)) + return 1; + + }; + + return 0; +} + +/** Action on the transition from DISABLED to CHOICE1. */ +void CrIaFdCheckAnomalyDetCheck(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Do Anomaly Detection Check */ + + AnomalyDetectionCheck(smDesc); + + return; +} + +/** Guard on the transition from DISABLED to CHOICE1. */ +FwSmBool_t CrIaFdCheckIsEnabled(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char FdCheckGlbEn, FdCheckIntEn = 0, FdCheckExtEn = 0; + + /* Execute [ FdCheck is Enabled ] */ + + CrIaCopy(FDGLBENABLE_ID, &FdCheckGlbEn); + + if (FdCheckGlbEn == 1) + { + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + { + CrIaCopy(FDCHECKTTMINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKTTMEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + { + CrIaCopy(FDCHECKSDSCINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSDSCEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemCommErrCheck) + { + CrIaCopy(FDCHECKCOMERRINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKCOMERREXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemModeTimeOutCheck) + { + CrIaCopy(FDCHECKTIMEOUTINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKTIMEOUTEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemSafeModeCheck) + { + CrIaCopy(FDCHECKSAFEMODEINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSAFEMODEEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemAliveCheck) + { + CrIaCopy(FDCHECKALIVEINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKALIVEEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemAnomalyEventCheck) + { + CrIaCopy(FDCHECKSEMANOEVTINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMANOEVTEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemLimitCheck) + { + CrIaCopy(FDCHECKSEMLIMITINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMLIMITEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdDpuHousekeepingCheck) + { + CrIaCopy(FDCHECKDPUHKINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKDPUHKEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdCentroidConsistencyCheck) + { + CrIaCopy(FDCHECKCENTCONSINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKCENTCONSEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdResourceCheck) + { + CrIaCopy(FDCHECKRESINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKRESEXTEN_ID, &FdCheckExtEn); + }; + + if (smDesc == smDescFdSemModeConsistencyCheck) + { + CrIaCopy(FDCHECKSEMCONSINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMCONSEXTEN_ID, &FdCheckExtEn); + }; + + if ((FdCheckIntEn == 1) && (FdCheckExtEn == 1)) + return 1; + + }; + + return 0; +} + +/** Action on the transition from Initial State to DISABLED. */ +void CrIaFdCheckResetSpCnt(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short FdCheckSpCnt = 0; + + /* FdCheckSpCnt = 0 */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + CrIaPaste(FDCHECKTTMSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + CrIaPaste(FDCHECKSDSCSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdSemCommErrCheck) + CrIaPaste(FDCHECKCOMERRSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdSemModeTimeOutCheck) + CrIaPaste(FDCHECKTIMEOUTSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdSemSafeModeCheck) + CrIaPaste(FDCHECKSAFEMODESPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdSemAliveCheck) + CrIaPaste(FDCHECKALIVESPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdSemAnomalyEventCheck) + CrIaPaste(FDCHECKSEMANOEVTSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdSemLimitCheck) + CrIaPaste(FDCHECKSEMLIMITSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdDpuHousekeepingCheck) + CrIaPaste(FDCHECKDPUHKSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdCentroidConsistencyCheck) + CrIaPaste(FDCHECKCENTCONSSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdResourceCheck) + CrIaPaste(FDCHECKRESSPCNT_ID, &FdCheckSpCnt); + + if (smDesc == smDescFdSemModeConsistencyCheck) + CrIaPaste(FDCHECKSEMCONSSPCNT_ID, &FdCheckSpCnt); + + return; +} + +/** Guard on the transition from CHOICE1 to SUSPECTED. */ +FwSmBool_t CrIaFdCheckIsAnomalyAndSmallCnt(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmBool_t Anomaly = 0; + unsigned short FdCheckCnt = 0, FdCheckCntThr = 0; + + /* [ (Anomaly Detected) && (FdCheckCnt < FdCheckCntThr) ] */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + { + Anomaly = AnomalyTelescopeTempMonitorCheck; + CrIaCopy(FDCHECKTTMCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKTTMCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + { + Anomaly = AnomalyIncorrectSDSCntrCheck; + CrIaCopy(FDCHECKSDSCCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKSDSCCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdSemCommErrCheck) + { + Anomaly = AnomalySemCommErrCheck; + CrIaCopy(FDCHECKCOMERRCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKCOMERRCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdSemModeTimeOutCheck) + { + Anomaly = AnomalySemModeTimeOutCheck; + CrIaCopy(FDCHECKTIMEOUTCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKTIMEOUTCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdSemSafeModeCheck) + { + Anomaly = AnomalySemSafeModeCheck; + CrIaCopy(FDCHECKSAFEMODECNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKSAFEMODECNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdSemAliveCheck) + { + Anomaly = AnomalySemAliveCheck; + CrIaCopy(FDCHECKALIVECNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKALIVECNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdSemAnomalyEventCheck) + { + Anomaly = AnomalySemAnomalyEventCheck; + CrIaCopy(FDCHECKSEMANOEVTCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKSEMANOEVTCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdSemLimitCheck) + { + Anomaly = AnomalySemLimitCheck; + CrIaCopy(FDCHECKSEMLIMITCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKSEMLIMITCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdDpuHousekeepingCheck) + { + Anomaly = AnomalyDpuHousekeepingCheck; + CrIaCopy(FDCHECKDPUHKCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKDPUHKCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdCentroidConsistencyCheck) + { + Anomaly = AnomalyCentroidConsistencyCheck; + CrIaCopy(FDCHECKCENTCONSCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKCENTCONSCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdResourceCheck) + { + Anomaly = AnomalyResourceCheck; + CrIaCopy(FDCHECKRESCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKRESCNTTHR_ID, &FdCheckCntThr); + } + + if (smDesc == smDescFdSemModeConsistencyCheck) + { + Anomaly = AnomalySemModeConsistencyCheck; + CrIaCopy(FDCHECKSEMCONSCNT_ID, &FdCheckCnt); + CrIaCopy(FDCHECKSEMCONSCNTTHR_ID, &FdCheckCntThr); + } + + if ((Anomaly == 1) && (FdCheckCnt < FdCheckCntThr)) + return 1; + + return 0; +} + +/** Guard on the transition from CHOICE1 to NOMINAL. */ +FwSmBool_t CrIaFdCheckIsNoAnomaly(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmBool_t Anomaly = 0; + + /* [ No Anomaly ] */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + Anomaly = AnomalyTelescopeTempMonitorCheck; + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + Anomaly = AnomalyIncorrectSDSCntrCheck; + + if (smDesc == smDescFdSemCommErrCheck) + Anomaly = AnomalySemCommErrCheck; + + if (smDesc == smDescFdSemModeTimeOutCheck) + Anomaly = AnomalySemModeTimeOutCheck; + + if (smDesc == smDescFdSemSafeModeCheck) + Anomaly = AnomalySemSafeModeCheck; + + if (smDesc == smDescFdSemAliveCheck) + Anomaly = AnomalySemAliveCheck; + + if (smDesc == smDescFdSemAnomalyEventCheck) + Anomaly = AnomalySemAnomalyEventCheck; + + if (smDesc == smDescFdSemLimitCheck) + Anomaly = AnomalySemLimitCheck; + + if (smDesc == smDescFdDpuHousekeepingCheck) + Anomaly = AnomalyDpuHousekeepingCheck; + + if (smDesc == smDescFdCentroidConsistencyCheck) + Anomaly = AnomalyCentroidConsistencyCheck; + + if (smDesc == smDescFdResourceCheck) + Anomaly = AnomalyResourceCheck; + + if (smDesc == smDescFdSemModeConsistencyCheck) + Anomaly = AnomalySemModeConsistencyCheck; + + if (Anomaly == 0) + return 1; + + return 0; +} + +/** Action on the transition from CHOICE1 to FAILED. */ +void CrIaFdCheckEvtFailed(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short evt_data[2]; + unsigned short FdCheckId = 0; + + /* Generate event report EVT_FD_FAILED */ + + if (smDesc == smDescFdTelescopeTempMonitorCheck) + FdCheckId = FDC_TS_TEMP; + + if (smDesc == smDescFdIncorrectSDSCntrCheck) + FdCheckId = FDC_ILL_CNT; + + if (smDesc == smDescFdSemCommErrCheck) + FdCheckId = FDC_SEM_COMM; + + if (smDesc == smDescFdSemModeTimeOutCheck) + FdCheckId = FDC_SEM_TO; + + if (smDesc == smDescFdSemSafeModeCheck) + FdCheckId = FDC_SEM_SM; + + if (smDesc == smDescFdSemAliveCheck) + FdCheckId = FDC_SEM_ALIVE; + + if (smDesc == smDescFdSemAnomalyEventCheck) + FdCheckId = FDC_EVT1; + /* + FDC EVT2=8 + */ + if (smDesc == smDescFdSemLimitCheck) + FdCheckId = FDC_SEM_OOL; + + if (smDesc == smDescFdDpuHousekeepingCheck) + FdCheckId = FDC_PSDU_OOL; + + if (smDesc == smDescFdCentroidConsistencyCheck) + FdCheckId = FDC_CENT_CONS; + + if (smDesc == smDescFdResourceCheck) + FdCheckId = FDC_RES; + + if (smDesc == smDescFdSemModeConsistencyCheck) + FdCheckId = FDC_SEM_CONS; + + evt_data[0] = FdCheckId; + evt_data[1] = 0; /* not used */ + + CrIaEvtRep(3, CRIA_SERV5_EVT_FD_FAILED, evt_data, 4); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ diff --git a/CrIa/src/CrIaPrSm/CrIaFdCheckInit.txt b/CrIa/src/CrIaPrSm/CrIaFdCheckInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..c52bdaac35dcf4c6fa279fae8d10176568b6e3ee --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaFdCheckInit.txt @@ -0,0 +1,19 @@ +{ + /** Define the state machine descriptor (SMD) */ + FwSmDesc_t smDesc = CrIaFdCheckCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDesc) != smSuccess) { + printf("The state machine CrIaFdCheck is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The state machine CrIaFdCheck is properly configured ... SUCCESS\n"); + } + + /** Start the SM, send a few transition commands to it, and execute it */ + FwSmStart(smDesc); + FwSmMakeTrans(smDesc, Execute); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaHbSemMonCreate.c b/CrIa/src/CrIaPrSm/CrIaHbSemMonCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..a37350f1e4288273a5210830ddedb3dcefde3482 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaHbSemMonCreate.c @@ -0,0 +1,125 @@ +/** + * @file CrIaHbSemMonCreate.c + * + * @author FW Profile code generator version 5.01 + * @date Created on: Sep 22 2017 14:47:10 + */ + +#include "CrIaHbSemMonCreate.h" + +/** CrFramework function definitions */ +#include "CrFramework/CrFwConstants.h" + +/** FW Profile function definitions */ +#include "FwPrDCreate.h" +#include "FwPrConfig.h" + +/** CrIaHbSemMon function definitions */ +#include <stdlib.h> + +/** + * Guard on the Control Flow from DECISION1 to N3. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code30324(FwPrDesc_t prDesc) +{ + CRFW_UNUSED(prDesc); + + return 1; +} + +/** + * Guard on the Control Flow from DECISION2 to DECISION4. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code41924(FwPrDesc_t prDesc) +{ + CRFW_UNUSED(prDesc); + + return 1; +} + +/** + * Guard on the Control Flow from DECISION3 to N7. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code66539(FwPrDesc_t prDesc) +{ + CRFW_UNUSED(prDesc); + + return 1; +} + +/** + * Guard on the Control Flow from DECISION4 to N2. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code68683(FwPrDesc_t prDesc) +{ + CRFW_UNUSED(prDesc); + + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaHbSemMonCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaHbSemMon */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaHbSemMon */ + const FwPrCounterU2_t DECISION2 = 2; /* The identifier of decision node DECISION2 in procedure CrIaHbSemMon */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 3; /* The number of control flows out of decision node DECISION2 in procedure CrIaHbSemMon */ + const FwPrCounterU2_t DECISION3 = 3; /* The identifier of decision node DECISION3 in procedure CrIaHbSemMon */ + const FwPrCounterU2_t N_OUT_OF_DECISION3 = 2; /* The number of control flows out of decision node DECISION3 in procedure CrIaHbSemMon */ + const FwPrCounterU2_t DECISION4 = 4; /* The identifier of decision node DECISION4 in procedure CrIaHbSemMon */ + const FwPrCounterU2_t N_OUT_OF_DECISION4 = 2; /* The number of control flows out of decision node DECISION4 in procedure CrIaHbSemMon */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 7, /* N_ANODES - The number of action nodes */ + 4, /* N_DNODES - The number of decision nodes */ + 17, /* N_FLOWS - The number of control flows */ + 7, /* N_ACTIONS - The number of actions */ + 10 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaHbSemMon_N1, &CrIaHbSemMonN1); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaHbSemMon_N2, &CrIaHbSemMonN2); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddActionNode(prDesc, CrIaHbSemMon_N3, &CrIaHbSemMonN3); + FwPrAddActionNode(prDesc, CrIaHbSemMon_N4, &CrIaHbSemMonN4); + FwPrAddDecisionNode(prDesc, DECISION3, N_OUT_OF_DECISION3); + FwPrAddActionNode(prDesc, CrIaHbSemMon_N7, &CrIaHbSemMonN7); + FwPrAddDecisionNode(prDesc, DECISION4, N_OUT_OF_DECISION4); + FwPrAddActionNode(prDesc, CrIaHbSemMon_N8, &CrIaHbSemMonN8); + FwPrAddActionNode(prDesc, CrIaHbSemMon_N9, &CrIaHbSemMonN9); + FwPrAddFlowActToAct(prDesc, CrIaHbSemMon_N1, CrIaHbSemMon_N8, NULL); + FwPrAddFlowIniToAct(prDesc, CrIaHbSemMon_N1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaHbSemMon_N2, &CrIaHbSemMonG2); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaHbSemMon_N3, &code30324); + FwPrAddFlowActToAct(prDesc, CrIaHbSemMon_N2, CrIaHbSemMon_N8, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaHbSemMon_N4, &CrIaHbSemMonG21); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaHbSemMon_N2, &CrIaHbSemMonG22); + FwPrAddFlowDecToDec(prDesc, DECISION2, DECISION4, &code41924); + FwPrAddFlowActToDec(prDesc, CrIaHbSemMon_N3, DECISION2, NULL); + FwPrAddFlowActToDec(prDesc, CrIaHbSemMon_N4, DECISION3, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaHbSemMon_N8, &CrIaHbSemMonG4); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaHbSemMon_N7, &code66539); + FwPrAddFlowActToAct(prDesc, CrIaHbSemMon_N7, CrIaHbSemMon_N9, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION4, CrIaHbSemMon_N4, &CrIaHbSemMonG3); + FwPrAddFlowDecToAct(prDesc, DECISION4, CrIaHbSemMon_N2, &code68683); + FwPrAddFlowActToDec(prDesc, CrIaHbSemMon_N8, DECISION1, &CrIaHbSemMonG1); + FwPrAddFlowActToFin(prDesc, CrIaHbSemMon_N9, NULL); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaHbSemMonCreate.h b/CrIa/src/CrIaPrSm/CrIaHbSemMonCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..b20d70c2e015bccdf35bdc6c6782902dadb3b512 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaHbSemMonCreate.h @@ -0,0 +1,176 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaHbSemMon procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaHbSemMon.png + * + * @author FW Profile code generator version 5.01 + * @date Created on: Sep 22 2017 14:47:10 + */ + +/** Make sure to include this header file only once */ +#ifndef CRIAHBSEMMON_H_ +#define CRIAHBSEMMON_H_ + +/** FW Profile function definitions */ +#include "FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaHbSemMon_N1 (1) /* The identifier of action node N1 in procedure CrIaHbSemMon */ +#define CrIaHbSemMon_N2 (2) /* The identifier of action node N2 in procedure CrIaHbSemMon */ +#define CrIaHbSemMon_N3 (3) /* The identifier of action node N3 in procedure CrIaHbSemMon */ +#define CrIaHbSemMon_N4 (4) /* The identifier of action node N4 in procedure CrIaHbSemMon */ +#define CrIaHbSemMon_N7 (5) /* The identifier of action node N7 in procedure CrIaHbSemMon */ +#define CrIaHbSemMon_N8 (6) /* The identifier of action node N8 in procedure CrIaHbSemMon */ +#define CrIaHbSemMon_N9 (7) /* The identifier of action node N9 in procedure CrIaHbSemMon */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaHbSemMonCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * Set hbSemPassword + * and hbSemCounter to zero + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaHbSemMonN1(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Set hbSemCounter + * to zero + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaHbSemMonN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Read SEM ON/OFF status + * from DPU Status Register + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaHbSemMonN3(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * <pre> + * Increment + * hbSemCounter + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaHbSemMonN4(FwPrDesc_t prDesc); + +/** + * Action for node N7. + * <pre> + * Make entry + * HBSEM_ALARM + * in Error Log + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaHbSemMonN7(FwPrDesc_t prDesc); + +/** + * Action for node N8. + * NOP + * @param smDesc the procedure descriptor + */ +void CrIaHbSemMonN8(FwPrDesc_t prDesc); + +/** + * Action for node N9. + * <pre> + * Trigger + * DPU Reset + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaHbSemMonN9(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N2. + * <pre> + * hbSemPassword is + * equal to 0xAA55 + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaHbSemMonG2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N4. + * <pre> + * (hbSem is equal to FALSE) && + * (SEM ON/OFF flag is equal to OFF) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaHbSemMonG21(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N2. + * <pre> + * HbSem is + * equal to TRUE + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaHbSemMonG22(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION3 to N8. + * <pre> + * hbSemCounter is + * smaller than HBSEM_MON_LIM + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaHbSemMonG4(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION4 to N4. + * <pre> + * (SEM Mode as given by data pool variables + * echoing SEM telemetry is STANDBY or SAFE) && + * (HbSem is equal to FALSE) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaHbSemMonG3(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N8 to DECISION1. + * Wait 1 Cycle + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaHbSemMonG1(FwPrDesc_t prDesc); + +#endif /* CrIaHbSemMonCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaHbSemMonFunc.c b/CrIa/src/CrIaPrSm/CrIaHbSemMonFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..77fa1fbd428eb1838e5194da1fa842127971936f --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaHbSemMonFunc.c @@ -0,0 +1,273 @@ +/** + * @file CrIaHbSemMonFunc.c + * + * @author FW Profile code generator version 5.01 + * @date Created on: Sep 22 2017 14:47:10 + */ + +/** CrIaHbSemMon function definitions */ +#include "CrIaHbSemMonCreate.h" + +/** CrFramework function definitions */ +#include "CrFramework/CrFwConstants.h" + +/** FW Profile function definitions */ +#include "FwPrConstants.h" +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <IfswUtilities.h> +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> + +#if (__sparc__) +#include <error_log.h> /* for ERROR_LOG_INFO_SIZE */ +#include <ibsw_interface.h> +#include <exchange_area.h> +#endif /* __sparc__ */ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#define HBSEM_ALARM 0xFFAA + +CrFwBool_t semStatus; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaHbSemMonN1(FwPrDesc_t prDesc) +{ + unsigned short hbSemPassword; + unsigned int hbSemCounter; + + /* Set hbSemPassword and hbSemCounter to zero */ + + CRFW_UNUSED(prDesc); + + hbSemPassword = 0; + CrIaPaste(HBSEMPASSWORD_ID, &hbSemPassword); + + hbSemCounter = 0; + CrIaPaste(HBSEMCOUNTER_ID, &hbSemCounter); + + return; +} + +/** Action for node N2. */ +void CrIaHbSemMonN2(FwPrDesc_t prDesc) +{ + unsigned int hbSemCounter; + + /* Set hbSemCounter to zero */ + + CRFW_UNUSED(prDesc); + + hbSemCounter = 0; + CrIaPaste(HBSEMCOUNTER_ID, &hbSemCounter); + + return; +} + +/** Action for node N3. */ +void CrIaHbSemMonN3(FwPrDesc_t prDesc) +{ + /* Read SEM ON/OFF status from DPU Status Register */ + + CRFW_UNUSED(prDesc); + +#if (__sparc__) + semStatus = CrIbSemLowLevelOp(GET_STATUS_ON); +#else + semStatus = 0; +#endif /* __sparc__ */ + + return; +} + +/** Action for node N4. */ +void CrIaHbSemMonN4(FwPrDesc_t prDesc) +{ + unsigned int hbSemCounter; + + /* Increment hbSemCounter */ + + CRFW_UNUSED(prDesc); + + CrIaCopy(HBSEMCOUNTER_ID, &hbSemCounter); + hbSemCounter++; + CrIaPaste(HBSEMCOUNTER_ID, &hbSemCounter); + + return; +} + +/** Action for node N7. */ +void CrIaHbSemMonN7(FwPrDesc_t prDesc) +{ + unsigned short evt_data[2] = {0, 0}; + + /* Make entry HBSEM_ALARM in Error Log */ + + CRFW_UNUSED(prDesc); + + /* Entry in Error Log with ID HBSEM_ALARM */ + CrIaErrRep(CRIA_SERV5_EVT_ERR_HIGH_SEV, HBSEM_ALARM, evt_data, 2); + + return; +} + +/** Action for node N8. */ +void CrIaHbSemMonN8(FwPrDesc_t prDesc) +{ + /* NOP */ + + CRFW_UNUSED(prDesc); + + return; +} + +/** Action for node N9. */ +void CrIaHbSemMonN9(FwPrDesc_t prDesc) +{ + /* Trigger DPU Reset */ + + CRFW_UNUSED(prDesc); + +#if (__sparc__) + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_UN); +#endif /* __sparc__ */ + + return; +} + +/**************/ +/*** GUARDS ***/ +/**************/ + +/** Guard on the Control Flow from DECISION1 to N2. */ +FwPrBool_t CrIaHbSemMonG2(FwPrDesc_t prDesc) +{ + unsigned short hbSemPassword; + + /* [ hbSemPassword is equal to 0xAA55 ] */ + + CRFW_UNUSED(prDesc); + + CrIaCopy(HBSEMPASSWORD_ID, &hbSemPassword); + + if (hbSemPassword == 0xAA55) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION2 to N4. */ +FwPrBool_t CrIaHbSemMonG21(FwPrDesc_t prDesc) +{ + unsigned char hbSem; + + /* [ (hbSem is equal to FALSE) && (SEM ON/OFF flag is equal to OFF) ] */ + + CRFW_UNUSED(prDesc); + + CrIaCopy(HBSEM_ID, &hbSem); + + if ((hbSem == 0) && (semStatus == 0)) /* thermal control is ON && status_OFF */ + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION2 to N2. */ +FwPrBool_t CrIaHbSemMonG22(FwPrDesc_t prDesc) +{ + unsigned char hbSem; + + /* [ hbSem is equal to TRUE ] */ + + CRFW_UNUSED(prDesc); + + CrIaCopy(HBSEM_ID, &hbSem); + + if (hbSem == 1) /* thermal control is OFF */ + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION3 to N8. */ +FwPrBool_t CrIaHbSemMonG4(FwPrDesc_t prDesc) +{ + unsigned int hbSemCounter; + + /* [ hbSemCounter is smaller than HBSEM_MON_LIM ] */ + + CRFW_UNUSED(prDesc); + + CrIaCopy(HBSEMCOUNTER_ID, &hbSemCounter); + + if (hbSemCounter < HBSEM_MON_LIM) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION4 to N4. */ +FwPrBool_t CrIaHbSemMonG3(FwPrDesc_t prDesc) +{ + unsigned char hbSem; + unsigned short hkStatMode; + + /* [ (SEM Mode as given by data pool variables echoing SEM telemetry is + STANDBY or SAFE) && (hbSem is equal to FALSE) ] */ + + CRFW_UNUSED(prDesc); + + /* Get HK_STAT_MODE from data pool echoing SEM telemetry */ + CrIaCopy(STAT_MODE_ID, &hkStatMode); + + /* Get HbSem Flag from data pool */ + CrIaCopy(HBSEM_ID, &hbSem); + + if (((hkStatMode == SEM_STATE_STANDBY) || (hkStatMode == SEM_STATE_SAFE)) && (hbSem == 0)) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from N8 to DECISION1. */ +FwPrBool_t CrIaHbSemMonG1(FwPrDesc_t prDesc) +{ + /* [ Wait 1 Cycle ] */ + + return (FwPrGetNodeExecCnt(prDesc) == 1); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaIaswCreate.c b/CrIa/src/CrIaPrSm/CrIaIaswCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..d70df4097517c06c45fef472a7aa9c02fc74d6ef --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaIaswCreate.c @@ -0,0 +1,55 @@ +/** + * @file CrIaIaswCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" + +/** CrIaIasw function definitions */ +#include "CrIaIaswCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t CrIaIaswCreate(void* smData) +{ + const FwSmCounterU2_t N_OUT_OF_STANDBY = 2; /* The number of transitions out of state STANDBY */ + const FwSmCounterU2_t N_OUT_OF_PRE_SCIENCE = 2; /* The number of transitions out of state PRE_SCIENCE */ + const FwSmCounterU2_t N_OUT_OF_SCIENCE = 3; /* The number of transitions out of state SCIENCE */ + const FwSmCounterU2_t N_OUT_OF_SEM_OFFLINE = 1; /* The number of transitions out of state SEM_OFFLINE */ + const FwSmCounterU2_t CHOICE1 = 1; /* The identifier of choice pseudo-state CHOICE1 in State Machine CrIaIasw */ + const FwSmCounterU2_t N_OUT_OF_CHOICE1 = 1; /* The number of transitions out of the choice-pseudo state CHOICE1 */ + + /** Create state machine smDesc */ + FwSmDesc_t smDesc = FwSmCreate( + 4, /* NSTATES - The number of states */ + 1, /* NCPS - The number of choice pseudo-states */ + 10, /* NTRANS - The number of transitions */ + 8, /* NACTIONS - The number of state and transition actions */ + 2 /* NGUARDS - The number of transition guards */ + ); + + /** Configure the state machine smDesc */ + FwSmSetData(smDesc, smData); + FwSmAddState(smDesc, CrIaIasw_STANDBY, N_OUT_OF_STANDBY, &CrIaIaswSwitchOffSem, NULL, NULL, NULL); + FwSmAddState(smDesc, CrIaIasw_PRE_SCIENCE, N_OUT_OF_PRE_SCIENCE, &CrIaIaswStartPrepSci, NULL, &CrIaIaswExecPrepSci, NULL); + FwSmAddState(smDesc, CrIaIasw_SCIENCE, N_OUT_OF_SCIENCE, &CrIaIaswLoad196s1, &CrIaIaswScienceExit, &CrIaIaswExecAllSciPr, NULL); + FwSmAddState(smDesc, CrIaIasw_SEM_OFFLINE, N_OUT_OF_SEM_OFFLINE, &CrIaIaswSwitchOnSem, NULL, NULL, NULL); + FwSmAddChoicePseudoState(smDesc, CHOICE1, N_OUT_OF_CHOICE1); + FwSmAddTransIpsToSta(smDesc, CrIaIasw_STANDBY, NULL); + FwSmAddTransStaToSta(smDesc, PrepareScience, CrIaIasw_STANDBY, CrIaIasw_PRE_SCIENCE, NULL, NULL); + FwSmAddTransStaToSta(smDesc, StartOffline, CrIaIasw_STANDBY, CrIaIasw_SEM_OFFLINE, NULL, NULL); + FwSmAddTransStaToCps(smDesc, StopSem, CrIaIasw_PRE_SCIENCE, CHOICE1, &CrIaIaswSMAction1, NULL); + FwSmAddTransStaToSta(smDesc, StartScience, CrIaIasw_PRE_SCIENCE, CrIaIasw_SCIENCE, NULL, &CrIaIaswFlag1); + FwSmAddTransStaToCps(smDesc, StopSem, CrIaIasw_SCIENCE, CHOICE1, NULL, NULL); + FwSmAddTransStaToSta(smDesc, Execute, CrIaIasw_SCIENCE, CrIaIasw_PRE_SCIENCE, NULL, &CrIaIaswAreSciPrTerm); + FwSmAddTransStaToSta(smDesc, StopScience, CrIaIasw_SCIENCE, CrIaIasw_PRE_SCIENCE, NULL, NULL); + FwSmAddTransStaToCps(smDesc, StopSem, CrIaIasw_SEM_OFFLINE, CHOICE1, NULL, NULL); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaIasw_STANDBY, NULL, NULL); + + return smDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaIaswCreate.h b/CrIa/src/CrIaPrSm/CrIaIaswCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..97f078de2040047189cc73591d6c6d060f1786dd --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaIaswCreate.h @@ -0,0 +1,151 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaIasw state machine. + * The state machine is configured with a set of function pointers representing the non-default + * actions and guards of the state machine. Some of these functions may also be declared in + * this header file in accordance with the configuration of the state machine in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The state machine created by this file is shown in the figure below. + * @image html CrIaIasw.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaIaswCreate_H_ +#define CrIaIaswCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" + +/** State identifiers */ +#define CrIaIasw_STOPPED (0) +#define CrIaIasw_PRE_SCIENCE (1) /* The identifier of state PRE_SCIENCE in State Machine CrIaIasw */ +#define CrIaIasw_SCIENCE (2) /* The identifier of state SCIENCE in State Machine CrIaIasw */ +#define CrIaIasw_SEM_OFFLINE (3) /* The identifier of state SEM_OFFLINE in State Machine CrIaIasw */ +#define CrIaIasw_STANDBY (4) /* The identifier of state STANDBY in State Machine CrIaIasw */ + +/** The identifiers of transition commands (triggers) */ +#define Execute (0) +#define StopSem (3) +#define PrepareScience (4) +#define StartOffline (6) +#define StartScience (7) +#define StopScience (5) + +/** + * Create a new state machine descriptor. + * This interface creates the state machine descriptor dynamically. + * @param smData the pointer to the state machine data. + * A value of NULL is legal (note that the default value of the pointer + * to the state machine data when the state machine is created is NULL). + * @return the pointer to the state machine descriptor + */ +FwSmDesc_t CrIaIaswCreate(void* smData); + +/** + * Entry Action for the state STANDBY. + * <pre> + * Load EVT_IASW_TR + * Send SwitchOff command + * to SEM Unit State Machine + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaIaswSwitchOffSem(FwSmDesc_t smDesc); + +/** + * Entry Action for the state PRE_SCIENCE. + * <pre> + * Load EVT_IASW_TR + * Start Prepare + * Science Procedure + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaIaswStartPrepSci(FwSmDesc_t smDesc); + +/** + * Do Action for the state PRE_SCIENCE. + * <pre> + * Execute Prepare + * Science Procedure + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaIaswExecPrepSci(FwSmDesc_t smDesc); + +/** + * Entry Action for the state SCIENCE. + * <pre> + * Load EVT_IASW_TR + * Load (196,1) Report + * Enable Centroid Cons. FdCheck + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaIaswLoad196s1(FwSmDesc_t smDesc); + +/** + * Exit Action for the state SCIENCE. + * <pre> + * Stop all Science Procedures + * Stop all Science Algorithms + * Disable Centroid Cons. FdCheck + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaIaswScienceExit(FwSmDesc_t smDesc); + +/** + * Do Action for the state SCIENCE. + * Execute all Science Procedures + * but the Save Images and Transfer + * FBFs to Ground Procedures + * @param smDesc the state machine descriptor + */ +void CrIaIaswExecAllSciPr(FwSmDesc_t smDesc); + +/** + * Entry Action for the state SEM_OFFLINE. + * <pre> + * Load EVT_IASW_TR + * Send SwitchOn command + * to SEM Unit State Machine + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaIaswSwitchOnSem(FwSmDesc_t smDesc); + +/** + * Action on the transition from PRE_SCIENCE to CHOICE1. + * Action_1 + * @param smDesc the state machine descriptor + */ +void CrIaIaswSMAction1(FwSmDesc_t smDesc); + +/** + * Guard on the transition from PRE_SCIENCE to SCIENCE. + * Flag_1 + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaIaswFlag1(FwSmDesc_t smDesc); + +/** + * Guard on the transition from SCIENCE to PRE_SCIENCE. + * <pre> + * All Science Procedures controlled + * by do-action of SCIENCE have + * terminated execution + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaIaswAreSciPrTerm(FwSmDesc_t smDesc); + +#endif /* CrIaIaswCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaIaswFunc.c b/CrIa/src/CrIaPrSm/CrIaIaswFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..2a0c8af5034a93696a6cdafc130fe4f7a8482a1b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaIaswFunc.c @@ -0,0 +1,282 @@ +/** + * @file CrIaIaswFunc.c + * @ingroup CrIaSm + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Feb 11 2016 22:56:45 + * + * @brief Implementation of the IASW State Machine actions and guards. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <unistd.h> /* sleep() */ + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConstants.h> +#include <FwProfile/FwSmDCreate.h> +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwSmCore.h> + +#include <FwProfile/FwPrConstants.h> +#include <FwProfile/FwPrDCreate.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +/** CrIaIasw function definitions */ +#include <CrIaPrSm/CrIaIaswCreate.h> + +/** CrIaSem function definitions */ +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <CrIaPrSm/CrIaAlgoCreate.h> + +#include <CrIaIasw.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <IfswDebug.h> + + +/** Entry Action for the state STANDBY. */ +void CrIaIaswSwitchOffSem(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short iasw_state_prev; + unsigned short iasw_state; + + unsigned short evt_data[2]; + + /* get current state */ + iasw_state = FwSmGetCurState(smDescIasw); + + /* get previous state from data pool */ + CrIaCopy(IASWSTATE_ID, &iasw_state_prev); + + /* update state in data pool */ + CrIaPaste(IASWSTATE_ID, &iasw_state); + + DEBUGP("IASW previous state: %d\n", iasw_state_prev); + DEBUGP("IASW state: %d\n", iasw_state); + + /* Load EVT_IASW_SM_TRANS */ + evt_data[0] = iasw_state_prev; + evt_data[1] = iasw_state; + + CrIaEvtRep(1, CRIA_SERV5_EVT_IASW_TR, evt_data, 4); + + /* Send SwitchOff command to SEM Unit SM */ + FwSmMakeTrans(smDescSem, SwitchOff); + + return; +} + + +/** Entry Action for the state PRE_SCIENCE. */ +void CrIaIaswStartPrepSci(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short iasw_state_prev; + unsigned short iasw_state; + + unsigned short evt_data[2]; + + /* get current state */ + iasw_state = FwSmGetCurState(smDescIasw); + + /* get previous state from data pool */ + CrIaCopy(IASWSTATE_ID, &iasw_state_prev); + + /* update state in data pool */ + CrIaPaste(IASWSTATE_ID, &iasw_state); + + /* Load EVT_IASW_SM_TRANS */ + evt_data[0] = iasw_state_prev; + evt_data[1] = iasw_state; + + CrIaEvtRep(1, CRIA_SERV5_EVT_IASW_TR, evt_data, 4); + + /* Start Prepare Science Procedure */ + FwPrStart(prDescPrepSci); + + return; +} + + +/** Do Action for the state PRE_SCIENCE. */ +void CrIaIaswExecPrepSci(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Execute Prepare Science Procedure */ + FwPrExecute(prDescPrepSci); + + return; +} + + +/** Entry Action for the state SCIENCE. */ +void CrIaIaswLoad196s1(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short iasw_state_prev; + unsigned short iasw_state; + + unsigned short evt_data[2]; + + unsigned char FdCheckCentConsIntEn; + + /* get current state */ + iasw_state = FwSmGetCurState(smDescIasw); + + /* get previous state from data pool */ + CrIaCopy(IASWSTATE_ID, &iasw_state_prev); + + /* update state in data pool */ + CrIaPaste(IASWSTATE_ID, &iasw_state); + + /* Load EVT_IASW_SM_TRANS */ + evt_data[0] = iasw_state_prev; + evt_data[1] = iasw_state; + + CrIaEvtRep(1, CRIA_SERV5_EVT_IASW_TR, evt_data, 4); + + /* Load (196,1) Report */ + CrIaLoadAocsReport(); + + /* Enable FdCheck Centroid Consistency Check */ + FdCheckCentConsIntEn = 1; + CrIaPaste(FDCHECKCENTCONSINTEN_ID, &FdCheckCentConsIntEn); + + return; +} + +/** Exit Action for the state SCIENCE. */ +void CrIaIaswScienceExit(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char FdCheckCentConsIntEn; + + /* Stop all Science Procedures */ + FwPrStop(prDescSaveImages); + FwPrStop(prDescNomSci); + FwPrStop(prDescAcqFullDrop); + FwPrStop(prDescCalFullSnap); + FwPrStop(prDescSciStack); + + /* Stop all Science Algorithms */ + FwSmMakeTrans(smDescAlgoCent0, Stop); + FwSmMakeTrans(smDescAlgoCent1, Stop); + FwSmMakeTrans(smDescAlgoCmpr, Stop); + FwSmMakeTrans(smDescAlgoAcq1, Stop); + + /* Disable FdCheck Centroid Consistency Check */ + FdCheckCentConsIntEn = 0; + CrIaPaste(FDCHECKCENTCONSINTEN_ID, &FdCheckCentConsIntEn); + + return; +} + +/** Do Action for the state SCIENCE. */ +void CrIaIaswExecAllSciPr(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Execute all Science Procedures */ + FwPrExecute(prDescNomSci); + FwPrExecute(prDescAcqFullDrop); + FwPrExecute(prDescCalFullSnap); + FwPrExecute(prDescSciStack); + + return; +} + +/** Entry Action for the state SEM_OFFLINE. */ +void CrIaIaswSwitchOnSem(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short iasw_state_prev; + unsigned short iasw_state; + + unsigned short evt_data[2]; + + /* get current state */ + iasw_state = FwSmGetCurState(smDescIasw); + + /* get previous state from data pool */ + CrIaCopy(IASWSTATE_ID, &iasw_state_prev); + + /* update state in data pool */ + CrIaPaste(IASWSTATE_ID, &iasw_state); + + /* Load EVT_IASW_SM_TRANS */ + evt_data[0] = iasw_state_prev; + evt_data[1] = iasw_state; + + CrIaEvtRep(1, CRIA_SERV5_EVT_IASW_TR, evt_data, 4); + + /* SEM Switch-on command to SEM unit SM */ + FwSmMakeTrans(smDescSem, SwitchOn); + + return; +} + +/** Action on the transition from PRE_SCIENCE to CHOICE1. */ +void CrIaIaswSMAction1(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Stop Prepare Science Procedure */ + + FwPrStop(prDescPrepSci); + + return; +} + +/** Guard on the transition from PRE_SCIENCE to SCIENCE. */ +FwSmBool_t CrIaIaswFlag1(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char prep_sci_proc; + unsigned short sem_oper_state; + + /* StartScience */ + /* [ (Prepare Science is not running) && (SEM OPER SM is in STABILIZE) ] */ + + /* Get the current state of the Prepare Science Procedure */ + /* 1 if the procedure is STARTED or 0 if it is STOPPED */ + prep_sci_proc = FwPrIsStarted(prDescPrepSci); + + /* Check for SEM Unit SM is in STABILIZE */ + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if ((prep_sci_proc == PR_STOPPED) && (sem_oper_state == CrIaSem_STABILIZE)) + return 1; + + return 0; +} + +/** Guard on the transition from SCIENCE to PRE_SCIENCE. */ +FwSmBool_t CrIaIaswAreSciPrTerm(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short pr_state_NomSci, pr_state_AcqFullDrop, pr_state_CalFullSnap, pr_state_SciStack; + + /* All Science Procedures controlled by do-action of SCIENCE have terminated execution */ + + /* Get the status of all Science Procedures, and check if they are terminated */ + /* 1 if the procedure is STARTED or 0 if it is STOPPED */ + pr_state_NomSci = FwPrIsStarted(prDescNomSci); + pr_state_AcqFullDrop = FwPrIsStarted(prDescAcqFullDrop); + pr_state_CalFullSnap = FwPrIsStarted(prDescCalFullSnap); + pr_state_SciStack = FwPrIsStarted(prDescSciStack); + + if ((pr_state_NomSci == PR_STOPPED) && + (pr_state_AcqFullDrop == PR_STOPPED) && + (pr_state_CalFullSnap == PR_STOPPED) && + (pr_state_SciStack == PR_STOPPED)) + return 1; + + return 0; +} + diff --git a/CrIa/src/CrIaPrSm/CrIaIaswInit.txt b/CrIa/src/CrIaPrSm/CrIaIaswInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..721f7161027f9cd63c5336b2537a42bcaee721f5 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaIaswInit.txt @@ -0,0 +1,24 @@ +{ + /** Define the state machine descriptor (SMD) */ + FwSmDesc_t smDesc = CrIaIaswCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDesc) != smSuccess) { + printf("The state machine CrIaIasw is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The state machine CrIaIasw is properly configured ... SUCCESS\n"); + } + + /** Start the SM, send a few transition commands to it, and execute it */ + FwSmStart(smDesc); + FwSmMakeTrans(smDesc, StopSem); + FwSmMakeTrans(smDesc, PrepareScience); + FwSmMakeTrans(smDesc, Execute); + FwSmMakeTrans(smDesc, StartOffline); + FwSmMakeTrans(smDesc, StartScience); + FwSmMakeTrans(smDesc, StopScience); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaNomSciCreate.c b/CrIa/src/CrIaPrSm/CrIaNomSciCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..23da963d5a3e156f0b9ddc594ab26145094f422d --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaNomSciCreate.c @@ -0,0 +1,146 @@ +/** + * @file CrIaNomSciCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:5 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaNomSci function definitions */ +#include "CrIaNomSciCreate.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/** + * Action for node N13. + * NOP + * @param smDesc the procedure descriptor + */ +static void code12899(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** + * Guard on the Control Flow from DECISION2 to DECISION3. + * pAcqFlag == FALSE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code2759(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION3 to DECISION4. + * pCal1Flag == FALSE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code44436(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION4 to DECISION5. + * pSciFlag == FALSE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code53213(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION5 to N13. + * pCal2Flag == FALSE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code10693(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaNomSciCreate(void* prData) +{ + const FwPrCounterU2_t DECISION2 = 1; /* The identifier of decision node DECISION2 in procedure CrIaNomSci */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaNomSci */ + const FwPrCounterU2_t DECISION3 = 2; /* The identifier of decision node DECISION3 in procedure CrIaNomSci */ + const FwPrCounterU2_t N_OUT_OF_DECISION3 = 2; /* The number of control flows out of decision node DECISION3 in procedure CrIaNomSci */ + const FwPrCounterU2_t DECISION4 = 3; /* The identifier of decision node DECISION4 in procedure CrIaNomSci */ + const FwPrCounterU2_t N_OUT_OF_DECISION4 = 2; /* The number of control flows out of decision node DECISION4 in procedure CrIaNomSci */ + const FwPrCounterU2_t DECISION5 = 4; /* The identifier of decision node DECISION5 in procedure CrIaNomSci */ + const FwPrCounterU2_t N_OUT_OF_DECISION5 = 2; /* The number of control flows out of decision node DECISION5 in procedure CrIaNomSci */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 17, /* N_ANODES - The number of action nodes */ + 4, /* N_DNODES - The number of decision nodes */ + 26, /* N_FLOWS - The number of control flows */ + 16, /* N_ACTIONS - The number of actions */ + 13 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaNomSci_N2, &CrIaNomSciN2); + FwPrAddActionNode(prDesc, CrIaNomSci_N3, &CrIaNomSciN3); + FwPrAddActionNode(prDesc, CrIaNomSci_N1, &CrIaNomSciN1); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddActionNode(prDesc, CrIaNomSci_N5, &CrIaNomSciN5); + FwPrAddDecisionNode(prDesc, DECISION3, N_OUT_OF_DECISION3); + FwPrAddActionNode(prDesc, CrIaNomSci_N6, &CrIaNomSciSdbResetFull); + FwPrAddActionNode(prDesc, CrIaNomSci_N7, &CrIaNomSciN7); + FwPrAddDecisionNode(prDesc, DECISION4, N_OUT_OF_DECISION4); + FwPrAddActionNode(prDesc, CrIaNomSci_N9, &CrIaNomSciN9); + FwPrAddActionNode(prDesc, CrIaNomSci_N7_1, &CrIaNomSciN7_1); + FwPrAddActionNode(prDesc, CrIaNomSci_N11_1, &CrIaNomSciN11_1); + FwPrAddDecisionNode(prDesc, DECISION5, N_OUT_OF_DECISION5); + FwPrAddActionNode(prDesc, CrIaNomSci_N9_1, &CrIaNomSciN9_1); + FwPrAddActionNode(prDesc, CrIaNomSci_N11, &CrIaNomSciN11); + FwPrAddActionNode(prDesc, CrIaNomSci_N4, &CrIaNomSciN4); + FwPrAddActionNode(prDesc, CrIaNomSci_N5_1, &CrIaNomSciN5_1); + FwPrAddActionNode(prDesc, CrIaNomSci_N8, &CrIaNomSciN8); + FwPrAddActionNode(prDesc, CrIaNomSci_N10, &CrIaNomSciSdbResetFull); + FwPrAddActionNode(prDesc, CrIaNomSci_N12, &CrIaNomSciN12); + FwPrAddActionNode(prDesc, CrIaNomSci_N13, &code12899); + FwPrAddFlowIniToAct(prDesc, CrIaNomSci_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N1, CrIaNomSci_N2, NULL); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N2, CrIaNomSci_N3, NULL); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N3, CrIaNomSci_N4, NULL); + FwPrAddFlowActToDec(prDesc, CrIaNomSci_N4, DECISION2, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaNomSci_N5, &CrIaNomSciIsAcqFlagTrue); + FwPrAddFlowDecToDec(prDesc, DECISION2, DECISION3, &code2759); + FwPrAddFlowActToDec(prDesc, CrIaNomSci_N5, DECISION3, &CrIaNomSciIsN5Finished); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaNomSci_N5_1, &CrIaNomSciIsCal1FlagTrue); + FwPrAddFlowDecToDec(prDesc, DECISION3, DECISION4, &code44436); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N5_1, CrIaNomSci_N6, NULL); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N6, CrIaNomSci_N7, NULL); + FwPrAddFlowActToDec(prDesc, CrIaNomSci_N7, DECISION4, &CrIaNomSciIsN7Finished); + FwPrAddFlowDecToAct(prDesc, DECISION4, CrIaNomSci_N7_1, &CrIaNomSciIsSciFlagTrue); + FwPrAddFlowDecToDec(prDesc, DECISION4, DECISION5, &code53213); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N7_1, CrIaNomSci_N8, NULL); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N8, CrIaNomSci_N9, NULL); + FwPrAddFlowActToDec(prDesc, CrIaNomSci_N9, DECISION5, &CrIaNomSciIsN9Finished); + FwPrAddFlowDecToAct(prDesc, DECISION5, CrIaNomSci_N9_1, &CrIaNomSciIsCal2FlagTrue); + FwPrAddFlowDecToAct(prDesc, DECISION5, CrIaNomSci_N13, &code10693); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N9_1, CrIaNomSci_N10, NULL); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N10, CrIaNomSci_N11, NULL); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N11, CrIaNomSci_N11_1, &CrIaNomSciIsN11Finished); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N13, CrIaNomSci_N11_1, &CrIaNomSciIsFlag1True); + FwPrAddFlowActToAct(prDesc, CrIaNomSci_N11_1, CrIaNomSci_N12, NULL); + FwPrAddFlowActToFin(prDesc, CrIaNomSci_N12, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaNomSciCreate.h b/CrIa/src/CrIaPrSm/CrIaNomSciCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..a7023da42a12639588eadddf18a41586218b0e4a --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaNomSciCreate.h @@ -0,0 +1,279 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaNomSci procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaNomSci.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:5 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaNomSciCreate_H_ +#define CrIaNomSciCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaNomSci_N1 (1) /* The identifier of action node N1 in procedure CrIaNomSci */ +#define CrIaNomSci_N2 (2) /* The identifier of action node N2 in procedure CrIaNomSci */ +#define CrIaNomSci_N3 (3) /* The identifier of action node N3 in procedure CrIaNomSci */ +#define CrIaNomSci_N4 (4) /* The identifier of action node N4 in procedure CrIaNomSci */ +#define CrIaNomSci_N5 (5) /* The identifier of action node N5 in procedure CrIaNomSci */ +#define CrIaNomSci_N5_1 (6) /* The identifier of action node N5_1 in procedure CrIaNomSci */ +#define CrIaNomSci_N6 (7) /* The identifier of action node N6 in procedure CrIaNomSci */ +#define CrIaNomSci_N7 (8) /* The identifier of action node N7 in procedure CrIaNomSci */ +#define CrIaNomSci_N7_1 (9) /* The identifier of action node N7_1 in procedure CrIaNomSci */ +#define CrIaNomSci_N8 (10) /* The identifier of action node N8 in procedure CrIaNomSci */ +#define CrIaNomSci_N9 (11) /* The identifier of action node N9 in procedure CrIaNomSci */ +#define CrIaNomSci_N9_1 (12) /* The identifier of action node N9_1 in procedure CrIaNomSci */ +#define CrIaNomSci_N10 (13) /* The identifier of action node N10 in procedure CrIaNomSci */ +#define CrIaNomSci_N11 (14) /* The identifier of action node N11 in procedure CrIaNomSci */ +#define CrIaNomSci_N11_1 (15) /* The identifier of action node N11_1 in procedure CrIaNomSci */ +#define CrIaNomSci_N12 (16) /* The identifier of action node N12 in procedure CrIaNomSci */ +#define CrIaNomSci_N13 (17) /* The identifier of action node N13 in procedure CrIaNomSci */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaNomSciCreate(void* prData); + +/** + * Action for node N2. + * <pre> + * Set SDB parameters according + * to procedure parameters + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Configure SDB for + * operation in Full CCD Mode + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN3(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * <pre> + * Generate event report + * EVT_SC_PR_STRT + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN1(FwPrDesc_t prDesc); + +/** + * Action for node N5. + * <pre> + * Start procedure + * Acquire Full Drop + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN5(FwPrDesc_t prDesc); + +/** + * Action for node N6. + * <pre> + * Send ResetFull cmd + * to SDB State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciSdbResetFull(FwPrDesc_t prDesc); + +/** + * Action for node N7. + * <pre> + * Start procedure + * Calibrate Full Snap + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN7(FwPrDesc_t prDesc); + +/** + * Action for node N9. + * <pre> + * Start procedure + * Science Window Stack/Snap + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN9(FwPrDesc_t prDesc); + +/** + * Action for node N7_1. + * <pre> + * Set STCK_ORDER + * equal to pStckOrderSci + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN7_1(FwPrDesc_t prDesc); + +/** + * Action for node N11_1. + * Stop Save Images Proc. + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN11_1(FwPrDesc_t prDesc); + +/** + * Action for node N9_1. + * <pre> + * Set STCK_ORDER + * equal to pStckOrderCal2 + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN9_1(FwPrDesc_t prDesc); + +/** + * Action for node N11. + * <pre> + * Start procedure + * Calibrate Full Snap + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN11(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * Start Save Images Procedure + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN4(FwPrDesc_t prDesc); + +/** + * Action for node N5_1. + * <pre> + * Set STCK_ORDER + * equal to pStckOrderCal1 + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN5_1(FwPrDesc_t prDesc); + +/** + * Action for node N8. + * <pre> + * Send ResetWin cmd + * to SDB State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN8(FwPrDesc_t prDesc); + +/** + * Action for node N12. + * Generate event report EVT_SC_PR_END with outcome "success" + * @param smDesc the procedure descriptor + */ +void CrIaNomSciN12(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N5. + * pAcqFlag == TRUE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsAcqFlagTrue(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N5 to DECISION3. + * <pre> + * (Acquire Full Drop Proc. + * has terminated) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsN5Finished(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION3 to N5_1. + * pCal1Flag == TRUE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsCal1FlagTrue(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N7 to DECISION4. + * <pre> + * (Calibrate Full Snap Proc. + * has terminated) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsN7Finished(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION4 to N7_1. + * pSciFlag == TRUE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsSciFlagTrue(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N9 to DECISION5. + * <pre> + * (Science Window Stack/Snap + * Proc. has terminated) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsN9Finished(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION5 to N9_1. + * pCal2Flag == TRUE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsCal2FlagTrue(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N11 to N11_1. + * <pre> + * (Calibrate Full Snap Proc. + * has terminated) && Flag_1 + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsN11Finished(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N13 to N11_1. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaNomSciIsFlag1True(FwPrDesc_t prDesc); + +#endif /* CrIaNomSciCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaNomSciFunc.c b/CrIa/src/CrIaPrSm/CrIaNomSciFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..1cce6cfcf828b425c12a9237588775e9d0b4f72e --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaNomSciFunc.c @@ -0,0 +1,530 @@ +/** + * @file CrIaNomSciFunc.c + * @ingroup CrIaPrSci + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Jun 3 2016 19:48:5 + * + * @brief Implementation of the Nominal Science Procedure nodes and guards. + * Perform a nominal science sequence (acquisition, calibration, science, and calibration). + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> + +/** CrIaNomSci function definitions */ +#include "CrIaNomSciCreate.h" + +#include <CrIaIasw.h> /* for Event Reporting and extern sm and prDescriptors */ +#include <CrIaPrSm/CrIaSdbCreate.h> /* for ResetWin etc. */ + +#include <IfswDebug.h> + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaNomSciN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_NOM_SCI_PR; + + /* Generate event report EVT_SC_PR_STRT */ + + evt_data[0] = ProcId; + evt_data[1] = 0; /* NOT USED */ + + DEBUGP("Event %d generated to signal start of NOM SCI PR\n", ProcId); + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_STRT, evt_data, 4); + + return; +} + +/** Action for node N2. */ +void CrIaNomSciN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char utemp8; + unsigned short utemp16; + + /* N are datatype 8 -> need to be 16 */ + CrIaCopy(NOMSCI_PSIBNFULL_ID, &utemp8); + utemp16 = (unsigned short) utemp8; + CrIaPaste(SIBNFULL_ID, &utemp16); + + CrIaCopy(NOMSCI_PSIBNWIN_ID, &utemp8); + utemp16 = (unsigned short) utemp8; + CrIaPaste(SIBNWIN_ID, &utemp16); + + CrIaCopy(NOMSCI_PCIBNFULL_ID, &utemp8); + utemp16 = (unsigned short) utemp8; + CrIaPaste(CIBNFULL_ID, &utemp16); + + CrIaCopy(NOMSCI_PCIBNWIN_ID, &utemp8); + utemp16 = (unsigned short) utemp8; + CrIaPaste(CIBNWIN_ID, &utemp16); + + CrIaCopy(NOMSCI_PGIBNFULL_ID, &utemp8); + utemp16 = (unsigned short) utemp8; + CrIaPaste(GIBNFULL_ID, &utemp16); + + CrIaCopy(NOMSCI_PGIBNWIN_ID, &utemp8); + utemp16 = (unsigned short) utemp8; + CrIaPaste(GIBNWIN_ID, &utemp16); + + /* sizes are compatible */ + CrIaCopy(NOMSCI_PSIBSIZEFULL_ID, &utemp16); + CrIaPaste(SIBSIZEFULL_ID, &utemp16); + + CrIaCopy(NOMSCI_PSIBSIZEWIN_ID, &utemp16); + CrIaPaste(SIBSIZEWIN_ID, &utemp16); + + CrIaCopy(NOMSCI_PCIBSIZEFULL_ID, &utemp16); + CrIaPaste(CIBSIZEFULL_ID, &utemp16); + + CrIaCopy(NOMSCI_PCIBSIZEWIN_ID, &utemp16); + CrIaPaste(CIBSIZEWIN_ID, &utemp16); + + CrIaCopy(NOMSCI_PGIBSIZEFULL_ID, &utemp16); + CrIaPaste(GIBSIZEFULL_ID, &utemp16); + + CrIaCopy(NOMSCI_PGIBSIZEWIN_ID, &utemp16); + CrIaPaste(GIBSIZEWIN_ID, &utemp16); + + return; +} + +/** Action for node N3. */ +void CrIaNomSciN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Configure SDB for operation in Full CCD Mode */ + /* This is done by sending command Reset and then command ConfigFull to SDB State Machine */ + + FwSmMakeTrans(smDescSdb, Reset); + FwSmMakeTrans(smDescSdb, ConfigFull); + + return; +} + +/** Action for node N4. */ +void CrIaNomSciN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Start Save Images Procedure */ + /* Procedure parameters determine wether the Save Images Procedure sends images to ground or wether it saves */ + /* them to flash */ + + unsigned short saveTarget; + unsigned char pFbfInit, pFbfEnd; + + /* Mantis 1988: copy save target from Nominal Science to Save Images data pool entry */ + CrIaCopy(NOMSCI_PSAVETARGET_ID, &saveTarget); + CrIaPaste(SAVEIMAGES_PSAVETARGET_ID, &saveTarget); + + /* also initialize FbfId to FbfInit if the save target is the FLASH */ + if (saveTarget == SAVETARGET_FLASH) + { + CrIaCopy(NOMSCI_PFBFINIT_ID, &pFbfInit); + CrIaCopy(NOMSCI_PFBFEND_ID, &pFbfEnd); + + CrIaPaste(SAVEIMAGES_PFBFINIT_ID, &pFbfInit); + CrIaPaste(SAVEIMAGES_PFBFEND_ID, &pFbfEnd); + } + + FwPrStart(prDescSaveImages); + + return; +} + +/* --------------------------------------------------------------------------------------------------------- Acq --- */ + +/** Action for node N5. */ +void CrIaNomSciN5(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int expTimeAcq, imageRepAcq; + + /* Start procedure Acquire Full Drop */ + PRDEBUGP("NomSci: Start procedure Acquire Full Drop (Acq)\n"); + + /* enter parameters relevant for AcqFullDrop */ + CrIaCopy(NOMSCI_PEXPTIMEACQ_ID, &expTimeAcq); + CrIaPaste(ACQFULLDROP_PEXPTIME_ID, &expTimeAcq); + + CrIaCopy(NOMSCI_PIMAGEREPACQ_ID, &imageRepAcq); + CrIaPaste(ACQFULLDROP_PIMAGEREP_ID, &imageRepAcq); + + FwPrStart(prDescAcqFullDrop); + + return; +} + +/* -------------------------------------------------------------------------------------------------------- Cal1 --- */ + +/** Action for node N5_1. */ +void CrIaNomSciN5_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Set STCK_ORDER equal to pStckOrderCal1 */ + unsigned short StackingOrder; + + CrIaCopy(NOMSCI_PSTCKORDERCAL1_ID, &StackingOrder); + CrIaPaste(STCK_ORDER_ID, &StackingOrder); + + PRDEBUGP("NomSci: Stacking Order (Cal1) is: %d\n", StackingOrder); + + return; +} + +/** Action for node N6 / N10. */ +void CrIaNomSciSdbResetFull(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send ResetFull command to SDB State Machine */ + + FwSmMakeTrans(smDescSdb, ResetFull); + + return; +} + +/** Action for node N7. */ +void CrIaNomSciN7(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short utemp16; + unsigned int utemp32; + + /* NOTE: we need to copy the NOMSCI_ stuff to the CALFULLSNAP stuff before */ + + CrIaCopy(NOMSCI_PNMBIMAGESCAL1_ID, &utemp32); + CrIaPaste(CALFULLSNAP_PNMBIMAGES_ID, &utemp32); + + CrIaCopy(NOMSCI_PEXPTIMECAL1_ID, &utemp32); + CrIaPaste(CALFULLSNAP_PEXPTIME_ID, &utemp32); + + CrIaCopy(NOMSCI_PIMAGEREPCAL1_ID, &utemp32); + CrIaPaste(CALFULLSNAP_PIMAGEREP_ID, &utemp32); + + CrIaCopy(NOMSCI_PCENTSELCAL1_ID, &utemp16); + CrIaPaste(CALFULLSNAP_PCENTSEL_ID, &utemp16); + + /* Start procedure Calibrate Full Snap */ + + PRDEBUGP("NomSci: Start procedure Calibrate Full Snap (Cal1)\n"); + + FwPrStart(prDescCalFullSnap); + + return; +} + +/* --------------------------------------------------------------------------------------------------------- Sci --- */ + +/** Action for node N7_1. */ +void CrIaNomSciN7_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Set STCK_ORDER equal to pStckOrderSci */ + unsigned short StackingOrder; + + CrIaCopy(NOMSCI_PSTCKORDERSCI_ID, &StackingOrder); + CrIaPaste(STCK_ORDER_ID, &StackingOrder); + + PRDEBUGP("Stacking Order (SCI) is: %d\n", StackingOrder); + + return; +} + +/** Action for node N8. */ +void CrIaNomSciN8(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send ResetWin command to SDB State Machine */ + + FwSmMakeTrans(smDescSdb, ResetWin); + + return; +} + +/** Action for node N9. */ +void CrIaNomSciN9(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short utemp16; + unsigned int utemp32; + + PRDEBUGP("--> starting compression via stack PR\n"); + + /* NOTE: we need to copy the NOMSCI_ stuff to the SCIWIN_ stuff before + we enter SciWin (with SciStack). So, for the 100th time, we need to check parameter sizes... */ + + CrIaCopy(NOMSCI_PNMBIMAGESSCI_ID, &utemp32); + CrIaPaste(SCIWIN_PNMBIMAGES_ID, &utemp32); + + CrIaCopy(NOMSCI_PCCDRDMODESCI_ID, &utemp16); + CrIaPaste(SCIWIN_PCCDRDMODE_ID, &utemp16); + + CrIaCopy(NOMSCI_PEXPTIMESCI_ID, &utemp32); + CrIaPaste(SCIWIN_PEXPTIME_ID, &utemp32); + + CrIaCopy(NOMSCI_PIMAGEREPSCI_ID, &utemp32); + CrIaPaste(SCIWIN_PIMAGEREP_ID, &utemp32); + + CrIaCopy(NOMSCI_PWINPOSXSCI_ID, &utemp16); + CrIaPaste(SCIWIN_PWINPOSX_ID, &utemp16); + + CrIaCopy(NOMSCI_PWINPOSYSCI_ID, &utemp16); + CrIaPaste(SCIWIN_PWINPOSY_ID, &utemp16); + + CrIaCopy(NOMSCI_PWINSIZEXSCI_ID, &utemp16); + CrIaPaste(SCIWIN_PWINSIZEX_ID, &utemp16); + + CrIaCopy(NOMSCI_PWINSIZEYSCI_ID, &utemp16); + CrIaPaste(SCIWIN_PWINSIZEY_ID, &utemp16); + + CrIaCopy(NOMSCI_PCENTSELSCI_ID, &utemp16); + CrIaPaste(SCIWIN_PCENTSEL_ID, &utemp16); + + /* Start procedure Science Window Stack/Snap */ + + FwPrStart(prDescSciStack); + + return; +} + +/* -------------------------------------------------------------------------------------------------------- Cal2 --- */ + +/** Action for node N9_1. */ +void CrIaNomSciN9_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Set STCK_ORDER equal to pStckOrderCal2 */ + unsigned short StackingOrder; + + CrIaCopy(NOMSCI_PSTCKORDERCAL2_ID, &StackingOrder); + CrIaPaste(STCK_ORDER_ID, &StackingOrder); + + PRDEBUGP("NomSci: Stacking Order (CAL2) is: %d\n", StackingOrder); + + return; +} + +/** Action for node N11. */ +void CrIaNomSciN11(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short utemp16; + unsigned int utemp32; + + /* NOTE: we need to copy the NOMSCI_ stuff to the CALFULLSNAP stuff before */ + + CrIaCopy(NOMSCI_PNMBIMAGESCAL2_ID, &utemp32); + CrIaPaste(CALFULLSNAP_PNMBIMAGES_ID, &utemp32); + + CrIaCopy(NOMSCI_PEXPTIMECAL2_ID, &utemp32); + CrIaPaste(CALFULLSNAP_PEXPTIME_ID, &utemp32); + + CrIaCopy(NOMSCI_PIMAGEREPCAL2_ID, &utemp32); + CrIaPaste(CALFULLSNAP_PIMAGEREP_ID, &utemp32); + + CrIaCopy(NOMSCI_PCENTSELCAL2_ID, &utemp16); + CrIaPaste(CALFULLSNAP_PCENTSEL_ID, &utemp16); + + /* Start procedure Calibrate Full Snap */ + + PRDEBUGP("NomSci: Start procedure Calibrate Full Snap (Cal2)\n"); + + FwPrStart(prDescCalFullSnap); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N11_1. */ +void CrIaNomSciN11_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Stop Save Images Procedure */ + + FwPrStop(prDescSaveImages); + + return; +} + +/** Action for node N12. */ +void CrIaNomSciN12(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_NOM_SCI_PR; + + /* Generate event report EVT_SC_PR_END with outcome "success" */ + + evt_data[0] = ProcId; + evt_data[1] = 1; /* 1 means success */ + DEBUGP("Event %d generated to signal end (but not stop) of NOM SCI PR\n", ProcId); + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_END, evt_data, 4); + + return; +} + +/**************/ +/*** GUARDS ***/ +/**************/ + +/** Guard on the Control Flow from DECISION2 to N5. */ +FwPrBool_t CrIaNomSciIsAcqFlagTrue(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char pAcqFlag; + + /* if pAcqFlag is TRUE then proceed to N5 (start procedure Acquire Full Drop) */ + + CrIaCopy(NOMSCI_PACQFLAG_ID, &pAcqFlag); + + if (pAcqFlag) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N5 to DECISION3. */ +FwPrBool_t CrIaNomSciIsN5Finished(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short status; + + /* Acquire Full Drop Proc. has terminated ? */ + status = FwPrIsStarted(prDescAcqFullDrop); + + if (status != PR_STOPPED) + return 0; + + return 1; +} + +/** Guard on the Control Flow from DECISION3 to N5_1. */ +FwPrBool_t CrIaNomSciIsCal1FlagTrue(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char pCal1Flag; + + /* if pCal1Flag is TRUE then proceed to N5_1 (set STCK_ORDER) */ + + CrIaCopy(NOMSCI_PCAL1FLAG_ID, &pCal1Flag); + + PRDEBUGP("Cal Flag is: %d\n", pCal1Flag); + + if (pCal1Flag) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N7 to DECISION4. */ +FwPrBool_t CrIaNomSciIsN7Finished(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short status; + + /* Calibrate Full Snap Proc. has terminated ? */ + status = FwPrIsStarted(prDescCalFullSnap); + + if (status != PR_STOPPED) + return 0; + + return 1; +} + +/** Guard on the Control Flow from DECISION4 to N7_1. */ +FwPrBool_t CrIaNomSciIsSciFlagTrue(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char pSciFlag; + + /* if pSciFlag is TRUE then proceed to N7_1 (set STCK_ORDER) */ + + CrIaCopy(NOMSCI_PSCIFLAG_ID, &pSciFlag); + + if (pSciFlag) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N9 to DECISION5. */ +FwPrBool_t CrIaNomSciIsN9Finished(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short status; + + /* Science Window Stack/Snap Proc. has terminated ? */ + + status = FwPrIsStarted(prDescSciStack); + + if (status != PR_STOPPED) + return 0; + + return 1; +} + +/** Guard on the Control Flow from DECISION5 to N9_1. */ +FwPrBool_t CrIaNomSciIsCal2FlagTrue(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char pCal2Flag; + + /* if pCal2Flag is TRUE then proceed to N13 (set STCK_ORDER) */ + + CrIaCopy(NOMSCI_PCAL2FLAG_ID, &pCal2Flag); + + if (pCal2Flag) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N11 to N11_1. */ +FwPrBool_t CrIaNomSciIsN11Finished(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short gibOut, gibIn; + unsigned short status; + + PRDEBUGP("xxx CrIaNomSciIsN11Finished xxx\n"); + + /* Calibrate Full Snap Proc. has terminated ? */ + status = FwPrIsStarted(prDescCalFullSnap); + + /* Flag_1 is true if the Save Images Proc. has finished its job (i.e. if gibIn is equal to gibOut) */ + + /* get relevant GIB sizes */ + CrIaCopy(GIBOUT_ID, &gibOut); + CrIaCopy(GIBIN_ID, &gibIn); + + if (status == PR_STOPPED) + { + if (gibOut == gibIn) + return 1; + } + + return 0; +} + +/** Guard on the Control Flow from N13 to N11_1. */ +FwPrBool_t CrIaNomSciIsFlag1True(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short gibOut, gibIn; + + /* Flag_1 is true if the Save Images Proc. has finished its job (i.e. if gibIn is equal to gibOut) */ + + /* get relevant GIB sizes */ + CrIaCopy(GIBOUT_ID, &gibOut); + CrIaCopy(GIBIN_ID, &gibIn); + + if (gibOut == gibIn) + return 1; + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaNomSciInit.txt b/CrIa/src/CrIaPrSm/CrIaNomSciInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..79327757a7e9d49fa8d3d2a8f044c5ca79653ec6 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaNomSciInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaNomSciCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaNomSci is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaNomSci is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaPrepSciCreate.c b/CrIa/src/CrIaPrSm/CrIaPrepSciCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..9d1c01f41fa551204934fe6364ccffc34d9dea48 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrepSciCreate.c @@ -0,0 +1,75 @@ +/** + * @file CrIaPrepSciCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaPrepSci function definitions */ +#include "CrIaPrepSciCreate.h" + +/** CrIaPrepSci function definitions */ +#include <stdlib.h> + +/** + * Action for node PREPSC4. + * Do Nothing + * @param smDesc the procedure descriptor + */ +static void code34502(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** + * Guard on the Control Flow from DECISION1 to PREPSC5. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code26134(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaPrepSciCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaPrepSci */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 3; /* The number of control flows out of decision node DECISION1 in procedure CrIaPrepSci */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 6, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 10, /* N_FLOWS - The number of control flows */ + 5, /* N_ACTIONS - The number of actions */ + 6 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaPrepSci_PREPSC1, &CrIaPrepSciSwitchOff); + FwPrAddActionNode(prDesc, CrIaPrepSci_PREPSC2, &CrIaPrepSciSwitchOn); + FwPrAddActionNode(prDesc, CrIaPrepSci_PREPSC3, &CrIaPrepSciGoToStab); + FwPrAddActionNode(prDesc, CrIaPrepSci_PREPSC4, &code34502); + FwPrAddActionNode(prDesc, CrIaPrepSci_PREPSC5, &CrIaPrepSciGenEvt); + FwPrAddActionNode(prDesc, CrIaPrepSci_PREPSC6, &CrIaPrepSciGoToStab); + FwPrAddFlowIniToDec(prDesc, DECISION1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaPrepSci_PREPSC1, &CrIaPrepSciIsOff); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaPrepSci_PREPSC4, &CrIaPrepSciIsInStabOrHigher); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaPrepSci_PREPSC5, &code26134); + FwPrAddFlowActToAct(prDesc, CrIaPrepSci_PREPSC1, CrIaPrepSci_PREPSC2, &CrIaPrepSciIsOff); + FwPrAddFlowActToAct(prDesc, CrIaPrepSci_PREPSC2, CrIaPrepSci_PREPSC3, &CrIaPrepSciIsInStandBy); + FwPrAddFlowActToFin(prDesc, CrIaPrepSci_PREPSC3, &CrIaPrepSciIsInStab); + FwPrAddFlowActToAct(prDesc, CrIaPrepSci_PREPSC4, CrIaPrepSci_PREPSC6, &CrIsPrepSciIsNonTransState); + FwPrAddFlowActToFin(prDesc, CrIaPrepSci_PREPSC5, NULL); + FwPrAddFlowActToFin(prDesc, CrIaPrepSci_PREPSC6, &CrIaPrepSciIsInStab); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaPrepSciCreate.h b/CrIa/src/CrIaPrSm/CrIaPrepSciCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..34d005e7c0aaadce9f8f426b5b6a7c23fa4d8ea7 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrepSciCreate.h @@ -0,0 +1,127 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaPrepSci procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaPrepSci.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaPrepSciCreate_H_ +#define CrIaPrepSciCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaPrepSci_PREPSC1 1 /* The identifier of action node PREPSC1 in procedure CrIaPrepSci */ +#define CrIaPrepSci_PREPSC2 2 /* The identifier of action node PREPSC2 in procedure CrIaPrepSci */ +#define CrIaPrepSci_PREPSC3 3 /* The identifier of action node PREPSC3 in procedure CrIaPrepSci */ +#define CrIaPrepSci_PREPSC4 4 /* The identifier of action node PREPSC4 in procedure CrIaPrepSci */ +#define CrIaPrepSci_PREPSC5 5 /* The identifier of action node PREPSC5 in procedure CrIaPrepSci */ +#define CrIaPrepSci_PREPSC6 6 /* The identifier of action node PREPSC6 in procedure CrIaPrepSci */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaPrepSciCreate(void* prData); + +/** + * Action for node PREPSC1. + * <pre> + * Send SwitchOff + * Command to SEM Unit SM + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaPrepSciSwitchOff(FwPrDesc_t prDesc); + +/** + * Action for node PREPSC2. + * <pre> + * Send SwitchOn + * Command to SEM Unit SM + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaPrepSciSwitchOn(FwPrDesc_t prDesc); + +/** + * Action for node PREPSC3 and PREPSC6. + * <pre> + * Send GoToStabilize + * Command to SEM Unit SM + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaPrepSciGoToStab(FwPrDesc_t prDesc); + +/** + * Action for node PREPSC5. + * Generate EVT_SEM_ILL_ST with SEM + * Unit SM and SEM Operational SM states as parameters + * @param smDesc the procedure descriptor + */ +void CrIaPrepSciGenEvt(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to PREPSC1. + * SEM Unit SM is in OFF + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaPrepSciIsOff(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to PREPSC4. + * <pre> + * SEM Operational SM is in STABILIZE + * or Higher State + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaPrepSciIsInStabOrHigher(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from PREPSC2 to PREPSC3. + * SEM Unit SM is in STANDBY + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaPrepSciIsInStandBy(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from PREPSC3 to Final Node. + * SEM Unit SM is in STABILIZE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaPrepSciIsInStab(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from PREPSC4 to PREPSC6. + * <pre> + * SEM Operational SM is in + * non-transitory state + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIsPrepSciIsNonTransState(FwPrDesc_t prDesc); + +#endif /* CrIaPrepSciCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaPrepSciFunc.c b/CrIa/src/CrIaPrSm/CrIaPrepSciFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..30e30bd737f403281201739fdf25b9b5c4a2c226 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrepSciFunc.c @@ -0,0 +1,208 @@ +/** + * @file CrIaPrepSciFunc.c + * @ingroup CrIaPr + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Jun 3 2016 19:48:4 + * + * @brief Implementation of the Prepare Science Procedure nodes and guards. + * It belongs to Service 193 (IASW Mode Control Service) which allows the OBC or the + * Ground to command mode changes to the IASW. + * In state PRE_SCIENCE of the IASW State Machine, the Prepare Science Procedure of is executed. + * This procedure is responsible for bringing the SEM into STABILIZE. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConstants.h> +#include <FwProfile/FwSmDCreate.h> +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwSmCore.h> + +#include <FwProfile/FwPrConstants.h> +#include <FwProfile/FwPrDCreate.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +/** CrIaIasw function definitions */ +#include <CrIaPrSm/CrIaIaswCreate.h> + +/** CrIaSem function definitions */ +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> + +/** CrIaPrepSci function definitions */ +#include "CrIaPrepSciCreate.h" + +#include <CrIaIasw.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <IfswDebug.h> + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node PREPSC1. */ +void CrIaPrepSciSwitchOff(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send SwitchOff Command to SEM Unit SM */ + FwSmMakeTrans(smDescSem, SwitchOff); + + return; +} + +/** Action for node PREPSC2. */ +void CrIaPrepSciSwitchOn(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send SwitchOn Command to SEM Unit SM */ + FwSmMakeTrans(smDescSem, SwitchOn); + + return; +} + +/** Action for node PREPSC3 / PREPSC6. */ +void CrIaPrepSciGoToStab(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send GoToStabilize Command to SEM Unit SM */ + FwSmMakeTrans(smDescSem, GoToStabilize); + + return; +} + +/** Action for node PREPSC5. */ +void CrIaPrepSciGenEvt(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + + /* Generate EVT_SEM_ILL_ST with SEM Unit SM and SEM Operational SM states as parameters */ + evt_data[0] = FwSmGetCurState(smDescSem); /* report current SEM state */ + evt_data[1] = FwSmGetCurStateEmb(smDescSem); /* report current SEM OPER state */ + + CrIaEvtRep(3, CRIA_SERV5_EVT_SEM_ILL_ST, evt_data, 4); + + return; +} + +/** Guard on the Control Flow from DECISION1 to PREPSC1 / PREPSC1 to PREPSC2. */ +FwPrBool_t CrIaPrepSciIsOff(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_state; + + /* Check for SEM Unit SM is in OFF */ + /* get current state */ + sem_state = FwSmGetCurState(smDescSem); + + if (sem_state == CrIaSem_OFF) + return 1; + + return 0; +} + +/** Guard on the Control Flow from DECISION1 to PREPSC4. */ +FwPrBool_t CrIaPrepSciIsInStabOrHigher(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state; + + /* Check for SEM Unit SM is in STABILIZE or Higher State */ + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if ((sem_oper_state == CrIaSem_STABILIZE) | /* Transition states are ignored */ + (sem_oper_state == CrIaSem_DIAGNOSTICS) | + (sem_oper_state == CrIaSem_CCD_WINDOW) | + (sem_oper_state == CrIaSem_CCD_FULL)) + return 1; + + return 0; +} + +#define DELAY_3S 24 + +/** Guard on the Control Flow from PREPSC2 to PREPSC3. */ +FwPrBool_t CrIaPrepSciIsInStandBy(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state; + static unsigned int delay; + + /* Check for SEM Unit SM is in STANDBY */ + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if (sem_oper_state == CrIaSem_STANDBY) + { + /* NOTE: FwPrGetNodeExecCnt(prDesc) does not work here, we have to use a static counter, because this guard is already + active as soon as SEM is switched on and has a large value when we enter standby */ + if (delay < DELAY_3S) + { + delay++; + /* PRDEBUGP("delaying GoToStabilize %d\n", FwPrGetNodeExecCnt(prDesc)); */ + return 0; + } + else + { + /* reset static counter */ + delay = 0; + return 1; + } + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from PREPSC3 to Final Node. */ +FwPrBool_t CrIaPrepSciIsInStab(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state; + + /* Check for SEM Unit SM is in STABILIZE */ + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if (sem_oper_state == CrIaSem_STABILIZE) + return 1; + + return 0; +} + +/** Guard on the Control Flow from PREPSC4 to PREPSC6. */ +FwPrBool_t CrIsPrepSciIsNonTransState(FwPrDesc_t prDesc) +{ + unsigned short sem_oper_state; + + CRFW_UNUSED(prDesc); + + /* Check for SEM Operational SM is in non-transitory state */ + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if ((sem_oper_state != CrIaSem_TR_CCD_WINDOW) && + (sem_oper_state != CrIaSem_TR_CCD_FULL)) + { + return 1; + } + else + { + return 0; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaPrepSciInit.txt b/CrIa/src/CrIaPrSm/CrIaPrepSciInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..d99622608338cd60bd3aab6a28b92fa2e41ae561 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrepSciInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaPrepSciCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaPrepSci is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaPrepSci is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Create.c b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Create.c new file mode 100644 index 0000000000000000000000000000000000000000..c3f5a8aab33a9e8834241c368fb60d3df3ca6b93 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Create.c @@ -0,0 +1,59 @@ +/** + * @file CrIaPrgAct6s2Create.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaPrgAct6s2 function definitions */ +#include "CrIaPrgAct6s2Create.h" + +/** + * Guard on the Control Flow from DECISION1 to MEMLOAD4. + * Read-Back Data are Incorrect + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code88379(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaPrgAct6s2Create(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaPrgAct6s2 */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaPrgAct6s2 */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 4, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 7, /* N_FLOWS - The number of control flows */ + 4, /* N_ACTIONS - The number of actions */ + 2 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaPrgAct6s2_MEMLOAD1, &CrIaPrgAct6s2PatchData); + FwPrAddActionNode(prDesc, CrIaPrgAct6s2_MEMLOAD2, &CrIaPrgAct6s2ReadData); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaPrgAct6s2_MEMLOAD3, &CrIaPrgAct6s2Completed); + FwPrAddActionNode(prDesc, CrIaPrgAct6s2_MEMLOAD4, &CrIaPrgAct6s2Failed); + FwPrAddFlowIniToAct(prDesc, CrIaPrgAct6s2_MEMLOAD1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaPrgAct6s2_MEMLOAD1, CrIaPrgAct6s2_MEMLOAD2, NULL); + FwPrAddFlowActToDec(prDesc, CrIaPrgAct6s2_MEMLOAD2, DECISION1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaPrgAct6s2_MEMLOAD3, &CrIaPrgAct6s2IsReadDataCorrect); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaPrgAct6s2_MEMLOAD4, &code88379); + FwPrAddFlowActToFin(prDesc, CrIaPrgAct6s2_MEMLOAD3, NULL); + FwPrAddFlowActToFin(prDesc, CrIaPrgAct6s2_MEMLOAD4, NULL); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Create.h b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Create.h new file mode 100644 index 0000000000000000000000000000000000000000..01957838309ff8d2690212dd9176bc327e5d61fd --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Create.h @@ -0,0 +1,83 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaPrgAct6s2 procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaPrgAct6s2.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaPrgAct6s2Create_H_ +#define CrIaPrgAct6s2Create_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaPrgAct6s2_MEMLOAD1 1 /* The identifier of action node MEMLOAD1 in procedure CrIaPrgAct6s2 */ +#define CrIaPrgAct6s2_MEMLOAD2 2 /* The identifier of action node MEMLOAD2 in procedure CrIaPrgAct6s2 */ +#define CrIaPrgAct6s2_MEMLOAD3 3 /* The identifier of action node MEMLOAD3 in procedure CrIaPrgAct6s2 */ +#define CrIaPrgAct6s2_MEMLOAD4 4 /* The identifier of action node MEMLOAD4 in procedure CrIaPrgAct6s2 */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaPrgAct6s2Create(void* prData); + +/** + * Action for node MEMLOAD1. + * Patch data to their destination + * @param smDesc the procedure descriptor + */ +void CrIaPrgAct6s2PatchData(FwPrDesc_t prDesc); + +/** + * Action for node MEMLOAD2. + * Read back patched data + * @param smDesc the procedure descriptor + */ +void CrIaPrgAct6s2ReadData(FwPrDesc_t prDesc); + +/** + * Action for node MEMLOAD3. + * <pre> + * + * Set action outcome to "completed" + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaPrgAct6s2Completed(FwPrDesc_t prDesc); + +/** + * Action for node MEMLOAD4. + * <pre> + * + * Set action outcome to "failed" + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaPrgAct6s2Failed(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to MEMLOAD3. + * Read-Back Data are Correct + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaPrgAct6s2IsReadDataCorrect(FwPrDesc_t prDesc); + +#endif /* CrIaPrgAct6s2Create_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Func.c b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Func.c new file mode 100644 index 0000000000000000000000000000000000000000..16ef372b641926a63567abe4ab48a4aae24da433 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Func.c @@ -0,0 +1,53 @@ +/** + * @file CrIaPrgAct6s2Func.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaPrgAct6s2 function definitions */ +#include "CrIaPrgAct6s2Create.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node MEMLOAD1. */ +void CrIaPrgAct6s2PatchData(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Action for node MEMLOAD2. */ +void CrIaPrgAct6s2ReadData(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Action for node MEMLOAD3. */ +void CrIaPrgAct6s2Completed(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Action for node MEMLOAD4. */ +void CrIaPrgAct6s2Failed(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Guard on the Control Flow from DECISION1 to MEMLOAD3. */ +FwPrBool_t CrIaPrgAct6s2IsReadDataCorrect(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Init.txt b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Init.txt new file mode 100644 index 0000000000000000000000000000000000000000..da50522e28b52f6adf1dca063a0cf1b0bed3c1f2 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaPrgAct6s2Init.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaPrgAct6s2Create(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaPrgAct6s2 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaPrgAct6s2 is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecCreate.c b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..563a2ef91ebb6b7fbf5aa9565dd5da360700b5b3 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecCreate.c @@ -0,0 +1,72 @@ +/** + * @file CrIaSaaEvalAlgoExecCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSaaEvalAlgoExec function definitions */ +#include "CrIaSaaEvalAlgoExecCreate.h" + +/** + * Action for node N5. + * NOP + * @param smDesc the procedure descriptor + */ +static void code63784(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** + * Guard on the Control Flow from DECISION1 to N1. + * saaCounter == 0 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code24409(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSaaEvalAlgoExecCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaSaaEvalAlgoExec */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 3; /* The number of control flows out of decision node DECISION1 in procedure CrIaSaaEvalAlgoExec */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 5, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 9, /* N_FLOWS - The number of control flows */ + 5, /* N_ACTIONS - The number of actions */ + 4 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaSaaEvalAlgoExec_N1, &CrIaSaaEvalAlgoExecN1); + FwPrAddActionNode(prDesc, CrIaSaaEvalAlgoExec_N2, &CrIaSaaEvalAlgoExecN2); + FwPrAddActionNode(prDesc, CrIaSaaEvalAlgoExec_N3, &CrIaSaaEvalAlgoExecN3); + FwPrAddActionNode(prDesc, CrIaSaaEvalAlgoExec_N4, &CrIaSaaEvalAlgoExecN4); + FwPrAddActionNode(prDesc, CrIaSaaEvalAlgoExec_N5, &code63784); + FwPrAddFlowIniToDec(prDesc, DECISION1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSaaEvalAlgoExec_N2, &CrIaSaaEvalAlgoExecIsCntLow); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSaaEvalAlgoExec_N3, &CrIaSaaEvalAlgoExecIsCntHigh); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSaaEvalAlgoExec_N1, &code24409); + FwPrAddFlowActToAct(prDesc, CrIaSaaEvalAlgoExec_N1, CrIaSaaEvalAlgoExec_N5, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSaaEvalAlgoExec_N2, CrIaSaaEvalAlgoExec_N5, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSaaEvalAlgoExec_N3, CrIaSaaEvalAlgoExec_N4, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSaaEvalAlgoExec_N4, CrIaSaaEvalAlgoExec_N5, NULL); + FwPrAddFlowActToDec(prDesc, CrIaSaaEvalAlgoExec_N5, DECISION1, &CrIaSaaEvalAlgoExecIsNextExec); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecCreate.h b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..d554a748ac9c1772cfb1c37f0834436eb6fb2d64 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecCreate.h @@ -0,0 +1,99 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSaaEvalAlgoExec procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * + * <b>Note for Control Flow from N5 to DECISION1</b> + * This guard returns true if the Node Execution Counter (as returned by + * FwPrGetNodeExecCnt) is equal to 1. + * + * @image html CrIaSaaEvalAlgoExec.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSaaEvalAlgoExecCreate_H_ +#define CrIaSaaEvalAlgoExecCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSaaEvalAlgoExec_N1 1 /* The identifier of action node N1 in procedure CrIaSaaEvalAlgoExec */ +#define CrIaSaaEvalAlgoExec_N2 2 /* The identifier of action node N2 in procedure CrIaSaaEvalAlgoExec */ +#define CrIaSaaEvalAlgoExec_N3 3 /* The identifier of action node N3 in procedure CrIaSaaEvalAlgoExec */ +#define CrIaSaaEvalAlgoExec_N4 4 /* The identifier of action node N4 in procedure CrIaSaaEvalAlgoExec */ +#define CrIaSaaEvalAlgoExec_N5 5 /* The identifier of action node N5 in procedure CrIaSaaEvalAlgoExec */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSaaEvalAlgoExecCreate(void* prData); + +/** + * Action for node N1. + * isSaaActive = TRUE + * @param smDesc the procedure descriptor + */ +void CrIaSaaEvalAlgoExecN1(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * saaCounter = 0 + * @param smDesc the procedure descriptor + */ +void CrIaSaaEvalAlgoExecN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * isSaaActive = FALSE + * @param smDesc the procedure descriptor + */ +void CrIaSaaEvalAlgoExecN3(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * saaCounter = saaCounter - SAA_EVAL_PER + * @param smDesc the procedure descriptor + */ +void CrIaSaaEvalAlgoExecN4(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N2. + * 0 < saaCounter < SAA_EVAL_PER + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSaaEvalAlgoExecIsCntLow(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N3. + * saaCounter >= SAA_EVAL_PER + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSaaEvalAlgoExecIsCntHigh(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N5 to DECISION1. + * Next Execution + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSaaEvalAlgoExecIsNextExec(FwPrDesc_t prDesc); + +#endif /* CrIaSaaEvalAlgoExecCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecFunc.c b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..545c2e3ac94f2e79f9fb0b32a612057985f9e629 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecFunc.c @@ -0,0 +1,140 @@ +/** + * @file CrIaSaaEvalAlgoExecFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaSaaEvalAlgoExec function definitions */ +#include "CrIaSaaEvalAlgoExecCreate.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSaaEvalAlgoExecN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char isSaaActive; + + /* isSaaActive = TRUE */ + + isSaaActive = 1; + CrIaPaste(ISSAAACTIVE_ID, &isSaaActive); + + return; +} + +/** Action for node N2. */ +void CrIaSaaEvalAlgoExecN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int saaCounter; + + /* saaCounter = 0 */ + + saaCounter = 0; + CrIaPaste(SAACOUNTER_ID, &saaCounter); + + return; +} + +/** Action for node N3. */ +void CrIaSaaEvalAlgoExecN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char isSaaActive; + + /* isSaaActive = FALSE */ + + isSaaActive = 0; + CrIaPaste(ISSAAACTIVE_ID, &isSaaActive); + + return; +} + +/** Action for node N4. */ +void CrIaSaaEvalAlgoExecN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int saaCounter; + int saaExecPer; + + /* saaCounter = saaCounter - SAA_EVAL_PER */ + + CrIaCopy(SAACOUNTER_ID, &saaCounter); + CrIaCopy(SAA_EXEC_PER_ID, &saaExecPer); + + saaCounter -= saaExecPer; + + CrIaPaste(SAACOUNTER_ID, &saaCounter); + + return; +} + +/** Guard on the Control Flow from DECISION1 to N2. */ +FwPrBool_t CrIaSaaEvalAlgoExecIsCntLow(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int saaCounter; + int saaExecPer; + + /* 0 < saaCounter < SAA_EVAL_PER */ + + CrIaCopy(SAACOUNTER_ID, &saaCounter); + CrIaCopy(SAA_EXEC_PER_ID, &saaExecPer); + + if ((saaCounter > 0) && (saaCounter < (unsigned int)saaExecPer)) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION1 to N3. */ +FwPrBool_t CrIaSaaEvalAlgoExecIsCntHigh(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int saaCounter; + int saaExecPer; + + /* saaCounter >= SAA_EVAL_PER */ + + CrIaCopy(SAACOUNTER_ID, &saaCounter); + CrIaCopy(SAA_EXEC_PER_ID, &saaExecPer); + + if (saaCounter >= (unsigned int)saaExecPer) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from N5 to DECISION1. */ +FwPrBool_t CrIaSaaEvalAlgoExecIsNextExec(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Next Execution */ + + if (FwPrGetNodeExecCnt(prDesc)) + { + return 1; + } + else + { + return 0; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecInit.txt b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..52dbaf324ce38553c4040f8427031ae7f13f5466 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaaEvalAlgoExecInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSaaEvalAlgoExecCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSaaEvalAlgoExec is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSaaEvalAlgoExec is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSaveImagesCreate.c b/CrIa/src/CrIaPrSm/CrIaSaveImagesCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..43206d4d3fa1456ce32423d34b1a944109ea7dd6 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaveImagesCreate.c @@ -0,0 +1,61 @@ +/** + * @file CrIaSaveImagesCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSaveImages function definitions */ +#include "CrIaSaveImagesCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to N5. + * pSaveTarget == FLASH + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code66587(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSaveImagesCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaSaveImages */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaSaveImages */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 5, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 8, /* N_FLOWS - The number of control flows */ + 5, /* N_ACTIONS - The number of actions */ + 5 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaSaveImages_N2, &CrIaSaveImagesN2); + FwPrAddActionNode(prDesc, CrIaSaveImages_N3, &CrIaSaveImagesN3); + FwPrAddActionNode(prDesc, CrIaSaveImages_N4, &CrIaSaveImagesN4); + FwPrAddActionNode(prDesc, CrIaSaveImages_N1, &CrIaSaveImagesN1); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaSaveImages_N5, &CrIaSaveImagesN5); + FwPrAddFlowIniToAct(prDesc, CrIaSaveImages_N1, NULL); + FwPrAddFlowActToDec(prDesc, CrIaSaveImages_N2, DECISION1, &CrIaSaveImageGibInDiffGibOut); + FwPrAddFlowActToAct(prDesc, CrIaSaveImages_N3, CrIaSaveImages_N4, &CrIaSaveImagesFlag1); + FwPrAddFlowActToDec(prDesc, CrIaSaveImages_N4, DECISION1, &CrIaSaveImageGibInDiffGibOut); + FwPrAddFlowActToAct(prDesc, CrIaSaveImages_N1, CrIaSaveImages_N2, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSaveImages_N3, &CrIaSaveImagesTrgIsGrd); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSaveImages_N5, &code66587); + FwPrAddFlowActToAct(prDesc, CrIaSaveImages_N5, CrIaSaveImages_N4, &CrIaSaveImagesFlag2); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSaveImagesCreate.h b/CrIa/src/CrIaPrSm/CrIaSaveImagesCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..7acc256dfc021b508b5d10fde577edfd59f5248b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaveImagesCreate.h @@ -0,0 +1,116 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSaveImages procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaSaveImages.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSaveImagesCreate_H_ +#define CrIaSaveImagesCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSaveImages_N1 1 /* The identifier of action node N1 in procedure CrIaSaveImages */ +#define CrIaSaveImages_N2 2 /* The identifier of action node N2 in procedure CrIaSaveImages */ +#define CrIaSaveImages_N3 3 /* The identifier of action node N3 in procedure CrIaSaveImages */ +#define CrIaSaveImages_N4 4 /* The identifier of action node N4 in procedure CrIaSaveImages */ +#define CrIaSaveImages_N5 5 /* The identifier of action node N5 in procedure CrIaSaveImages */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSaveImagesCreate(void* prData); + +/** + * Action for node N2. + * Set gibOut to point to oldest GIB + * @param smDesc the procedure descriptor + */ +void CrIaSaveImagesN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * Start Down-Transfer of GIB + * @param smDesc the procedure descriptor + */ +void CrIaSaveImagesN3(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * Increment gibOut + * @param smDesc the procedure descriptor + */ +void CrIaSaveImagesN4(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * <pre> + * Generate event report + * EVT_SC_PR_STRT + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSaveImagesN1(FwPrDesc_t prDesc); + +/** + * Action for node N5. + * <pre> + * Start FBF Save Procedure + * to transfer GIB pointed at by + * gibOut to flash memory + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSaveImagesN5(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N2 to DECISION1. + * gibIn != gibOut + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSaveImageGibInDiffGibOut(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N3 to N4. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSaveImagesFlag1(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N3. + * pSaveTarget == GROUND + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSaveImagesTrgIsGrd(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N5 to N4. + * Flag_2 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSaveImagesFlag2(FwPrDesc_t prDesc); + +#endif /* CrIaSaveImagesCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSaveImagesFunc.c b/CrIa/src/CrIaPrSm/CrIaSaveImagesFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..40d567ea14e8b879eaed94af312d5a0e8bfa12e2 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaveImagesFunc.c @@ -0,0 +1,323 @@ +/** + * @file CrIaSaveImagesFunc.c + * @ingroup CrIaPrSci + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Feb 11 2016 22:56:45 + * + * @brief Implementation of the Save Images Procedure nodes and guards. + * Transfer a pre-defined number of science images to ground or to flash. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> /* for CRIA_SERV198_SAVE_IMG_PR, SAVETARGET_GROUND/FLASH */ + +/** CrIaSaveImages function definitions */ +#include "CrIaSaveImagesCreate.h" + +#include <CrIaIasw.h> /* for the smDescSdu2 handle */ +#include <CrIaPrSm/CrIaSduCreate.h> /* for StartDownTransfer */ +#include <CrIaPrSm/CrIaSemCreate.h> +#include <Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.h> /* for PR_STOPPED */ + +#include "IfswDebug.h" + +/* Mantis 2131: use flag to check that not all FBFs in range pFbfInit to pFbfEnd have been filled */ +static unsigned char isRunOutOfFbfs; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N2. */ +void CrIaSaveImagesN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId; + + /* NOTE: This node is required to set gibOut to point to the oldest gib, + but this is guaranteed by design and hence the function returns without + doing anything. */ + + /* Set flag isRunOutOfFbfs to FALSE */ + isRunOutOfFbfs = 0; + + /* Mantis 2153 */ + CrIaCopy(SAVEIMAGES_PFBFINIT_ID, &fbfId); + CrIaPaste(FBFSAVE_PFBFID_ID, &fbfId); + + return; +} + +/** Action for node N3. */ +void CrIaSaveImagesN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short gibOut; + unsigned short sdbstate; + + /* start downtransfer of gib */ + PRDEBUGP("start downtransfer\n"); + + CrIaCopy(GIBOUT_ID, &gibOut); + CrIaPaste(GIBTOTRANSFER_ID, &gibOut); + CrIaCopy (SDBSTATE_ID, &sdbstate); + + CrIaPaste(TRANSFERMODE_ID, &sdbstate); /* memorize the mode in which the transfer was started */ + + FwSmMakeTrans(smDescSdu2, StartDownTransfer); + + return; +} + + +unsigned char IncrementFbfId (unsigned char StartId, unsigned char EndId) +{ + unsigned char fbfEnb, StartIndex, EndIndex, indices, Index; + int k; + + if (StartId == EndId) + { + return StartId; + } + + StartIndex = StartId - 1; /* Id cannot be 0 */ + EndIndex = EndId - 1; + + indices = EndIndex - StartIndex; + + /* also consider the reverse case with wrap around */ + if (StartIndex > EndIndex) + { + indices = 250 - StartIndex + EndIndex; + } + + /* Increment FBF Counter skipping disabled FBFs */ + for (k=0; k < indices; k++) + { + Index = (StartIndex + k) % 250; + + /* check if FBF is enabled */ + CrIaCopyArrayItem(FBF_ENB_ID, &fbfEnb, Index); + + if (fbfEnb == 1) + { + /* found an enabled index */ + return Index + 1; /* ID is Index + 1 */ + } + } + + /* Set flag isRunOutOfFbfs to TRUE, because we have run out of enabled FBFs */ + isRunOutOfFbfs = 1; + + /* nothing found */ + return StartId; +} + + +/** Action for node N4. */ +void CrIaSaveImagesN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* increment gibOut */ + unsigned short gibOut, newGibOut, gibIn, gibSizeWin, gibNWin, gibSizeFull, gibNFull; + unsigned short sdbstate; + unsigned short saveTarget; + unsigned char fbfId, pFbfEnd; + unsigned long int xibOffset; + unsigned short transferMode; + + /* increment by a gibSize, which depends on the mode Win/Full + + NOTE: Here the spec makes me (RO) not extremely happy. + In this node we adjust the Gib by the size depending on the *current* mode, + which may not be the mode in which the pending data were produced. + */ + + /* increment FbfId if the save target is the FLASH */ + CrIaCopy(SAVEIMAGES_PSAVETARGET_ID, &saveTarget); + + if (saveTarget == SAVETARGET_FLASH) + { + CrIaCopy(FBFSAVE_PFBFID_ID, &fbfId); + CrIaCopy(SAVEIMAGES_PFBFEND_ID, &pFbfEnd); + + /* increment index to next possible one */ + /* Mantis 2153 */ + if (fbfId != pFbfEnd) + { + if ((fbfId == 250) && (pFbfEnd != 250)) + fbfId = 1; + else + fbfId += 1; + + fbfId = IncrementFbfId (fbfId, pFbfEnd); + } + + CrIaPaste(FBFSAVE_PFBFID_ID, &fbfId); + } + + /* get state of SDB (WIN or FULL) */ + CrIaCopy (SDBSTATE_ID, &sdbstate); + + /* + NOTE: Between the start of a transfer and its completion, the imaging mode may change + and the following scenarios arise: + a) mode unchanged: increment GIBOUT using GIBIN and GIBOUT from data pool + b) mode changed: do not increment, because it has been reset! + */ + CrIaCopy(TRANSFERMODE_ID, &transferMode); + if (sdbstate != transferMode) + return; + + /* get relevant GIB sizes */ + CrIaCopy(GIBOUT_ID, &gibOut); + CrIaCopy(GIBIN_ID, &gibIn); + CrIaCopy(GIBSIZEWIN_ID, &gibSizeWin); + CrIaCopy(GIBSIZEFULL_ID, &gibSizeFull); + CrIaCopy(GIBNWIN_ID, &gibNWin); + CrIaCopy(GIBNFULL_ID, &gibNFull); + + /* move to the next gibOut in sequence */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_RES_OFFSET_FROM_ADDR((unsigned long int)gibAddressWin); + newGibOut = updateXibFwd((unsigned int)gibOut, (unsigned int)gibIn, xibOffset, (unsigned int)gibSizeWin, (unsigned int)gibNWin, GIBOUT_WIN_XIB); + } + else + { + xibOffset = GET_RES_OFFSET_FROM_ADDR((unsigned long int)gibAddressFull); + newGibOut = updateXibFwd((unsigned int)gibOut, (unsigned int)gibIn, xibOffset, (unsigned int)gibSizeFull, (unsigned int)gibNFull, GIBOUT_FULL_XIB); + } + + gibOut = newGibOut; + + CrIaPaste(GIBOUT_ID, &gibOut); + + return; +} + +/** Action for node N1. */ +void CrIaSaveImagesN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* generate event report EVT_SC_PR_STRT */ + unsigned short evt_data[2]; + + PRDEBUGP("save images pr start\n"); + evt_data[0] = CRIA_SERV198_SAVE_IMG_PR; /* proc ID */ + evt_data[1] = 0; /* NOT USED */ + + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_STRT, evt_data, 4); + + return; +} + +/** Action for node N5. */ +void CrIaSaveImagesN5(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* start FBF save procedure to transfer gib pointed at by gibOut to FLASH memory */ + unsigned short gibOut; + unsigned short sdbstate; + unsigned int pFbfRamAddr; + + /* start save to FBF of gib */ + PRDEBUGP("start save to FBF\n"); + + /* address of gib out */ + CrIaCopy(GIBOUT_ID, &gibOut); + pFbfRamAddr = (unsigned int) GET_ADDR_FROM_RES_OFFSET(gibOut); + CrIaPaste(FBFSAVE_PFBFRAMADDR_ID, &pFbfRamAddr); + + /* + NOTE: FbfID is set to FbfInit by the Nominal Science or by the Start Procedure of Save Images. + The FbfID is then incremented in N4 before the gib is adjusted + */ + + /* Memorize the mode in which the transfer was started. This is needed later in N4 */ + CrIaCopy (SDBSTATE_ID, &sdbstate); + CrIaPaste(TRANSFERMODE_ID, &sdbstate); + + /* start FBF save procedure (see Mantis 1548) */ + FwPrStart(prDescFbfSave); + + return; +} + +/** Guard on the Control Flow from N2 to DECISION1. */ +FwPrBool_t CrIaSaveImageGibInDiffGibOut(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short gibIn, gibOut; + + CrIaCopy(GIBIN_ID, &gibIn); + CrIaCopy(GIBOUT_ID, &gibOut); + + /* if gibIn is ahead of gibOut, then we have sth. to transfer */ + if (gibIn != gibOut) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N3 to N4. */ +FwPrBool_t CrIaSaveImagesFlag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* flag1 = downtransfer of gib has completed, i.e. SDU2 SM is in state inactive */ + unsigned short sdu2State; + + sdu2State = FwSmGetCurState(smDescSdu2); + + if (sdu2State == CrIaSdu_INACTIVE) + return 1; + + return 0; +} + +/** Guard on the Control Flow from DECISION1 to N3. */ +FwPrBool_t CrIaSaveImagesTrgIsGrd(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* pSaveTarget = ground (or FLASH) */ + unsigned short saveTarget; + + CrIaCopy(SAVEIMAGES_PSAVETARGET_ID, &saveTarget); + + if (saveTarget == SAVETARGET_GROUND) + return 1; /* NOTE: 0 goes to N5, 1 goes to N3 */ + + /* else FLASH */ + return 0; +} + +/** Guard on the Control Flow from N5 to N4. */ +FwPrBool_t CrIaSaveImagesFlag2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* flag2 = fbfSaveProcedure has terminated and not all FBFs in range pFbfInit to pFbfEnd have been filled */ + unsigned short fbfSaveNode; + + fbfSaveNode = (unsigned short) (FwPrGetCurNode(prDescFbfSave) & 0xffff); + + if ((fbfSaveNode == PR_STOPPED) && !isRunOutOfFbfs) + { + return 1; + } + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSaveImagesInit.txt b/CrIa/src/CrIaPrSm/CrIaSaveImagesInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..49762dc2d7a10310a067a405c53f35ee1bbdd418 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSaveImagesInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSaveImagesCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSaveImages is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSaveImages is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSciDataUpdCreate.c b/CrIa/src/CrIaPrSm/CrIaSciDataUpdCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..ca8663bcbf9192ff05d2787d4ea0e5a3ddd8fc3a --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciDataUpdCreate.c @@ -0,0 +1,118 @@ +/** + * @file CrIaSciDataUpdCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSciDataUpd function definitions */ +#include "CrIaSciDataUpdCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to N2. + * <pre> + * SDSC has + * illegal value + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code9110(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION2 to DECISION3. + * <pre> + * SDSC is + * in sequence + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code45000(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION3 to N5. + * <pre> + * SIB is large enough to hold + * new bach of science data + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code76599(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION4 to DECISION1. + * ! Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code94970(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSciDataUpdCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaSciDataUpd */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaSciDataUpd */ + const FwPrCounterU2_t DECISION2 = 2; /* The identifier of decision node DECISION2 in procedure CrIaSciDataUpd */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaSciDataUpd */ + const FwPrCounterU2_t DECISION3 = 3; /* The identifier of decision node DECISION3 in procedure CrIaSciDataUpd */ + const FwPrCounterU2_t N_OUT_OF_DECISION3 = 2; /* The number of control flows out of decision node DECISION3 in procedure CrIaSciDataUpd */ + const FwPrCounterU2_t DECISION4 = 4; /* The identifier of decision node DECISION4 in procedure CrIaSciDataUpd */ + const FwPrCounterU2_t N_OUT_OF_DECISION4 = 2; /* The number of control flows out of decision node DECISION4 in procedure CrIaSciDataUpd */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 5, /* N_ANODES - The number of action nodes */ + 4, /* N_DNODES - The number of decision nodes */ + 14, /* N_FLOWS - The number of control flows */ + 5, /* N_ACTIONS - The number of actions */ + 8 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaSciDataUpd_N2, &CrIaSciDataUpdN2); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddActionNode(prDesc, CrIaSciDataUpd_N3, &CrIaSciDataUpdN3); + FwPrAddActionNode(prDesc, CrIaSciDataUpd_N5, &CrIaSciDataUpdN5); + FwPrAddDecisionNode(prDesc, DECISION3, N_OUT_OF_DECISION3); + FwPrAddActionNode(prDesc, CrIaSciDataUpd_N4, &CrIaSciDataUpdN4); + FwPrAddDecisionNode(prDesc, DECISION4, N_OUT_OF_DECISION4); + FwPrAddActionNode(prDesc, CrIaSciDataUpd_N1, &CrIaSciDataUpdN1); + FwPrAddFlowIniToDec(prDesc, DECISION4, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSciDataUpd_N2, NULL); + FwPrAddFlowDecToDec(prDesc, DECISION1, DECISION2, &CrIaSciDataUpdHasSdscLegalVal); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSciDataUpd_N2, &code9110); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaSciDataUpd_N3, &CrIaSciDataUpdIsSdscOutOfSeq); + FwPrAddFlowDecToDec(prDesc, DECISION2, DECISION3, &code45000); + FwPrAddFlowActToDec(prDesc, CrIaSciDataUpd_N3, DECISION3, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSciDataUpd_N5, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaSciDataUpd_N4, &CrIaSciDataUpdIsSibTooSmall); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaSciDataUpd_N5, &code76599); + FwPrAddFlowActToFin(prDesc, CrIaSciDataUpd_N4, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION4, CrIaSciDataUpd_N1, &CrIaSciDataUpdFlag1); + FwPrAddFlowDecToDec(prDesc, DECISION4, DECISION1, &code94970); + FwPrAddFlowActToDec(prDesc, CrIaSciDataUpd_N1, DECISION1, NULL); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSciDataUpdCreate.h b/CrIa/src/CrIaPrSm/CrIaSciDataUpdCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..5a1cec34679924218e74602d2ead4280ec3b097c --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciDataUpdCreate.h @@ -0,0 +1,119 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSciDataUpd procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaSciDataUpd.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSciDataUpdCreate_H_ +#define CrIaSciDataUpdCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSciDataUpd_N1 1 /* The identifier of action node N1 in procedure CrIaSciDataUpd */ +#define CrIaSciDataUpd_N2 2 /* The identifier of action node N2 in procedure CrIaSciDataUpd */ +#define CrIaSciDataUpd_N3 3 /* The identifier of action node N3 in procedure CrIaSciDataUpd */ +#define CrIaSciDataUpd_N4 4 /* The identifier of action node N4 in procedure CrIaSciDataUpd */ +#define CrIaSciDataUpd_N5 5 /* The identifier of action node N5 in procedure CrIaSciDataUpd */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSciDataUpdCreate(void* prData); + +/** + * Action for node N2. + * Generate Event EVT_SDSC_ILL + * @param smDesc the procedure descriptor + */ +void CrIaSciDataUpdN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * Generate Event EVT_SDSC_OOS + * @param smDesc the procedure descriptor + */ +void CrIaSciDataUpdN3(FwPrDesc_t prDesc); + +/** + * Action for node N5. + * Store science data in SIB + * @param smDesc the procedure descriptor + */ +void CrIaSciDataUpdN5(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * Generate Event EVT_SIB_SIZE + * @param smDesc the procedure descriptor + */ +void CrIaSciDataUpdN4(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * <pre> + * Increment sibIn + * and initialize header + * information for new image + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciDataUpdN1(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to DECISION2. + * <pre> + * SDSC has + * legal value + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciDataUpdHasSdscLegalVal(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N3. + * SDSC is out-of-sequence + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciDataUpdIsSdscOutOfSeq(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION3 to N4. + * <pre> + * SIB is too small to hold + * new batch of science data + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciDataUpdIsSibTooSmall(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION4 to N1. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciDataUpdFlag1(FwPrDesc_t prDesc); + +#endif /* CrIaSciDataUpdCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSciDataUpdFunc.c b/CrIa/src/CrIaPrSm/CrIaSciDataUpdFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..6d74b91e2194012700610b8b5adc9a7506db604e --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciDataUpdFunc.c @@ -0,0 +1,794 @@ +/** + * @file CrIaSciDataUpdFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdint.h> /* for uint32_t */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> /* for memcpy */ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +#include <Services/General/CrSemParamGetter.h> +#include <CrIaDataPoolId.h> +#include <CrIaDataPool.h> +#include <ScienceDataProcessing.h> /* for updateXib */ +#include "Sdp/SdpAlgorithmsImplementation.h" /* for sram1tosram2_shorts */ +#include "EngineeringAlgorithms.h" + +/* event generation */ +#include <CrIaSemEvents.h> +#include <Services/General/CrIaConstants.h> + +/** CrIaSciDataUpd function definitions */ +#include "CrIaSciDataUpdCreate.h" + +/* Acquisition Types and max packet numbers */ +#include <Services/General/CrSemConstants.h> + +#include <CrIaIasw.h> /* for sibAddressFull and Win and the S21 globasl */ + +#include "../IfswDebug.h" + +unsigned short SibIn, SibOut, SibSize, newSibIn; +unsigned short SibN; + +/* Flag TransferComplete is used to help identify the last packet of an image acquisition. The flag is managed as follows: + * (a) It is initialized to zero at the point of declaration in module CrIaIasw + * (b) It is reset to zero in node N1 of the Science Data Update Procedure (i.e. at the start of a new image acquisition) + * (c) It is set to non-zero values in node N5 of the Science Data Update Procedure when the last packet of an image or sub-image is received + */ + +CrFwBool_t FD_SDSC_ILL_Flag, FD_SDSC_OOS_Flag; /* for FdCheck Incorrect Science Data Sequence Counter */ + +static unsigned char S21_Flag0; + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N2. */ +void CrIaSciDataUpdN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short CurrentPacketNum; + unsigned short evt_data[2]; + CrFwPckt_t pckt; + + DEBUGP("SciDatUpd N2.\n"); + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum (&CurrentPacketNum, pckt); + + /* generate event EVT_SDSC_ILL */ + evt_data[0] = CurrentPacketNum; + /* evt_data[1] not used */ + + CrIaEvtRep(3, CRIA_SERV5_EVT_SDSC_ILL, evt_data, 4); + + /* Set flag for FdCheck Incorrect Science Data Sequence Counter */ + FD_SDSC_ILL_Flag = 1; + + return; +} + + +/** Action for node N3. */ +void CrIaSciDataUpdN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short CurrentPacketNum; + unsigned short evt_data[2]; + + CrFwPckt_t pckt; + + DEBUGP("SciDatUpd N3.\n"); + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum (&CurrentPacketNum, pckt); + + /* generate event EVT_SDSC_OOS */ + evt_data[0] = S21LastPacketNum; + evt_data[1] = CurrentPacketNum; + + CrIaEvtRep(3, CRIA_SERV5_EVT_SDSC_OOS, evt_data, 4); + + /* Set flag for FdCheck Incorrect Science Data Sequence Counter */ + FD_SDSC_OOS_Flag = 1; + + return; +} + + +/** Action for node N5. */ +void CrIaSciDataUpdN5(FwPrDesc_t __attribute__((unused)) prDesc) +{ + CrFwPckt_t pckt; + + unsigned short *source; + unsigned short *dest = NULL; + + unsigned char AcqType, lstpckt, tcompl; + unsigned short NumDataWords; + unsigned short TotalPacketNum; + unsigned short CurrentPacketNum; + + unsigned int SibAddress; + unsigned long int xibOffset; + unsigned short semWinSizeX, semWinSizeY; + + unsigned short xib_err_id; + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + + DEBUGP("SciDatUpd N5: S21 STORE.\n"); + + CrSemServ21DatCcdWindowParamGetHkStatDataAcqType (&AcqType, pckt); + CrSemServ21DatCcdWindowParamGetHkStatNumDataWords (&NumDataWords, pckt); + + /* store science data in sib */ +#ifdef PC_TARGET + { + unsigned int j; + unsigned char val0, val1; + + for (j=0; j<NumDataWords; j++) + { + val0 = pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 52 + 2*j]; + val1 = pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 52 + 2*j+1]; + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 52 + 2*j] = val1; + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 52 + 2*j+1] = val0; + } + } +#endif + + source = (unsigned short *)(&pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 52]); /* NOTE: int alignment matters here! */ + + if ((unsigned long int)source & 0x1L) + { + PRDEBUGP("WE ARE NOT SHORT ALIGNED!!!!!!!!! 0x%lx\n", (unsigned long int)source); + } + +#if (__sparc__) + switch (AcqType) + { + case CCD_FULL_ID : + case CCD_WIN_EXPOS_ID : + + dest = &(((unsigned short *)incomingSibInStruct.Expos)[incomingSibInStruct.ExposSamples]); + incomingSibInStruct.ExposSamples += NumDataWords; + break; + + case CCD_WIN_LSM_ID : + + dest = &(((unsigned short *)incomingSibInStruct.Lsm)[incomingSibInStruct.LsmSamples]); + incomingSibInStruct.LsmSamples += NumDataWords; + break; + + case CCD_WIN_RSM_ID : + + dest = &(((unsigned short *)incomingSibInStruct.Rsm)[incomingSibInStruct.RsmSamples]); + incomingSibInStruct.RsmSamples += NumDataWords; + break; + + case CCD_WIN_TM_ID : + + dest = &(((unsigned short *)incomingSibInStruct.Tm)[incomingSibInStruct.TmSamples]); + incomingSibInStruct.TmSamples += NumDataWords; + break; + + default: + /* no other types are possible */ + return; + } +#else + switch (AcqType) + { + case CCD_FULL_ID : + case CCD_WIN_EXPOS_ID : + + dest = &(((unsigned short *)ShmIncomingSibInPTR->Expos)[ShmIncomingSibInPTR->ExposSamples]); + ShmIncomingSibInPTR->ExposSamples += NumDataWords; + break; + + case CCD_WIN_LSM_ID : + + dest = &(((unsigned short *)ShmIncomingSibInPTR->Lsm)[ShmIncomingSibInPTR->LsmSamples]); + ShmIncomingSibInPTR->LsmSamples += NumDataWords; + break; + + case CCD_WIN_RSM_ID : + + dest = &(((unsigned short *)ShmIncomingSibInPTR->Rsm)[ShmIncomingSibInPTR->RsmSamples]); + ShmIncomingSibInPTR->RsmSamples += NumDataWords; + break; + + case CCD_WIN_TM_ID : + + dest = &(((unsigned short *)ShmIncomingSibInPTR->Tm)[ShmIncomingSibInPTR->TmSamples]); + ShmIncomingSibInPTR->TmSamples += NumDataWords; + break; + + default: + /* no other types are possible */ + DEBUGP("Acq type ERROR!\n"); + return; + } +#endif /* (__sparc__) */ + + /* carry out the actual memcopy from SRAM1 to SRAM2 considering short alignment. */ + sram1tosram2_shorts (source, NumDataWords, dest); + + /* + evaluate last SEM packet flag + */ + + /* get total packets */ + CrSemServ21DatCcdWindowParamGetHkStatTotalPacketNum (&TotalPacketNum, pckt); + + /* get current packet number */ + CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum (&CurrentPacketNum, pckt); + + CrIaCopy(TRANSFERCOMPLETE_ID, &tcompl); + + if (TotalPacketNum == CurrentPacketNum) + { + switch (AcqType) + { + case ACQ_TYPE_FULL : + tcompl = 0x0F; + break; + + case ACQ_TYPE_WIN_EXPOS : + tcompl |= 0x01; + break; + + case ACQ_TYPE_WIN_LSM : + tcompl |= 0x02; + break; + + case ACQ_TYPE_WIN_RSM : + tcompl |= 0x04; + break; + + case ACQ_TYPE_WIN_TM : + tcompl |= 0x08; + break; + + default : + break; + } + + CrIaPaste(TRANSFERCOMPLETE_ID, &tcompl); + + if (tcompl == 0xf) + { + lstpckt = 1; + CrIaPaste(LASTSEMPCKT_ID, &lstpckt); + tcompl = 0; + CrIaPaste(TRANSFERCOMPLETE_ID, &tcompl); + + /* Mantis 1779 */ + + /* increment SIBIN assuming the same Acquisition Type */ + if (AcqType == CCD_FULL_ID) + { + CrIaCopy(SIBIN_ID, &SibIn); + CrIaCopy(SIBOUT_ID, &SibOut); + SibAddress = (unsigned int) sibAddressFull; + xib_err_id = SIBIN_FULL_XIB; + CrIaCopy(SIBNFULL_ID, &SibN); + CrIaCopy(SIBSIZEFULL_ID, &SibSize); + } + else + { + CrIaCopy(SIBIN_ID, &SibIn); + CrIaCopy(SIBOUT_ID, &SibOut); + SibAddress = (unsigned int) sibAddressWin; + xib_err_id = SIBIN_WIN_XIB; + CrIaCopy(SIBNWIN_ID, &SibN); + CrIaCopy(SIBSIZEWIN_ID, &SibSize); + } + + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)SibAddress); + newSibIn = updateXib((unsigned int)SibIn, (unsigned int)SibOut, xibOffset, (unsigned int)SibSize, (unsigned int)SibN, xib_err_id); + + /* use the new sib, no harm if it is identical */ + CrIaPaste(SIBIN_ID, &newSibIn); + + PRDEBUGP("N5: SibIn(after) = %d\n", newSibIn); + + /* initialize the incomingSibInStruct structure */ +#if (__sparc__) + if (AcqType == CCD_FULL_ID) + { + CrIaSetupSibFull (&incomingSibInStruct, newSibIn); + } + else + { + CrIaCopy(PWINSIZEX_ID, &semWinSizeX); + CrIaCopy(PWINSIZEY_ID, &semWinSizeY); + + CrIaSetupSibWin (&incomingSibInStruct, newSibIn, semWinSizeX, semWinSizeY); + } +#else + if (AcqType == CCD_FULL_ID) + { + CrIaSetupSibFull (ShmIncomingSibInPTR, newSibIn); + } + else + { + CrIaCopy(PWINSIZEX_ID, &semWinSizeX); + CrIaCopy(PWINSIZEY_ID, &semWinSizeY); + + CrIaSetupSibWin (ShmIncomingSibInPTR, newSibIn, semWinSizeX, semWinSizeY); + } +#endif /* (__sparc__) */ + } + } + + return; +} + + +/** Action for node N4. */ +void CrIaSciDataUpdN4(FwPrDesc_t __attribute__((unused)) __attribute__((unused)) prDesc) +{ + CrFwPckt_t pckt; + unsigned char AcqType; + unsigned short size; + unsigned short evt_data[2]; + + pckt = S21SemPacket; + + CrSemServ21DatCcdWindowParamGetHkStatDataAcqType (&AcqType, pckt); + + if (AcqType == CCD_FULL_ID) + { + CrIaCopy(SIBSIZEFULL_ID, &size); + } + else /* belongs to the set of WINDOW products */ + { + CrIaCopy(SIBSIZEWIN_ID, &size); + } + + evt_data[0] = size; + + CrIaEvtRep(3, CRIA_SERV5_EVT_SIB_SIZE, evt_data, 4); + + return; +} + + +/** Action for node N1. */ +void CrIaSciDataUpdN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + CrFwPckt_t pckt; + + /* parameters read from the S21 packet */ + unsigned int AcqId, ExposureTime, ImageCycleCnt, AcqImageCnt; + unsigned char AcqType, AcqSrc, CcdTimingScriptId; + unsigned short TotalPacketNum, CurrentPacketNum, PixDataOffset, NumDataWords; /* DatScienceBlock;*/ + CrFwTimeStamp_t AcqTime; + unsigned int startTimeCoarse, endTimeCoarse; + unsigned short startTimeFine, endTimeFine; + union + { + unsigned int ui; + float f; + } VoltFeeVod, VoltFeeVrd, VoltFeeVog, VoltFeeVss, TempFeeCcd, TempFeeAdc, TempFeeBias; + + short TempOh1A, TempOh1B, TempOh2A, TempOh2B, TempOh3A, TempOh3B, TempOh4A, TempOh4B; + short AdcN5V, Temp1; + unsigned short semWinSizeX, semWinSizeY; + + struct SibHeader * sibHeader; + struct SibPhotometry * sibPhotometry; + struct SibCentroid * sibCentroid; + unsigned char isSdsActive, isSaaActive, tcompl; + + PRDEBUGP("Science Data Update Procedure Node N1. Only \"first\" packets enter here.\n"); + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + + /* get acquisition ID and other info from packet */ + CrSemServ21DatCcdWindowParamGetHkStatDataAcqId (&AcqId, pckt); + CrSemServ21DatCcdWindowParamGetHkStatDataAcqType (&AcqType, pckt); + CrSemServ21DatCcdWindowParamGetHkStatDataAcqSrc (&AcqSrc, pckt); + CrSemServ21DatCcdWindowParamGetHkStatCcdTimingScriptId (&CcdTimingScriptId, pckt); + CrSemServ21DatCcdWindowParamGetHkStatDataAcqTime (AcqTime.t, pckt); + CrSemServ21DatCcdWindowParamGetHkStatExposureTime (&ExposureTime, pckt); + CrSemServ21DatCcdWindowParamGetHkStatPixDataOffset (&PixDataOffset, pckt); + CrSemServ21DatCcdWindowParamGetHkStatTotalPacketNum (&TotalPacketNum, pckt); + CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum (&CurrentPacketNum, pckt); + CrSemServ21DatCcdWindowParamGetHkStatNumDataWords (&NumDataWords, pckt); + /* CrSemServ21DatCcdWindowParamGetDatScienceBlock (&DatScienceBlock, pckt); */ + + /* save Data Acquisition Time in DP as integration start time */ + startTimeCoarse = ((((unsigned int) AcqTime.t[0]) << 24) & 0xff000000) | ((((unsigned int) AcqTime.t[1]) << 16) & 0x00ff0000) | ((((unsigned int) AcqTime.t[2]) << 8) & 0x0000ff00) | (((unsigned int) AcqTime.t[3]) & 0x000000ff); + startTimeFine = ((((unsigned short) AcqTime.t[4]) << 8) & 0xff00) | (((unsigned short) AcqTime.t[5]) & 0x00ff); + CrIaPaste(INTEGSTARTTIMECRS_ID, &startTimeCoarse); + CrIaPaste(INTEGSTARTTIMEFINE_ID, &startTimeFine); + + /* NOTE: End of Integration time is calculated in PrepareCentroid */ + + /* get 7 SEM HK data pool varibles */ + /* CrIaCopy(VOLT_FEE_VOD_ID, &VoltFeeVod.f); */ + CrSemServ21DatCcdWindowParamGetHkVoltFeeVod(&VoltFeeVod.ui, pckt); + /* CrIaCopy(VOLT_FEE_VRD_ID, &VoltFeeVrd.f); */ + CrSemServ21DatCcdWindowParamGetHkVoltFeeVrd(&VoltFeeVrd.ui, pckt); + /* CrIaCopy(VOLT_FEE_VOG_ID, &VoltFeeVog.f); */ + CrSemServ21DatCcdWindowParamGetHkVoltFeeVog(&VoltFeeVog.ui, pckt); + /* CrIaCopy(VOLT_FEE_VSS_ID, &VoltFeeVss.f); */ + CrSemServ21DatCcdWindowParamGetHkVoltFeeVss(&VoltFeeVss.ui, pckt); + /* CrIaCopy(TEMP_FEE_CCD_ID, &TempFeeCcd.f); */ + CrSemServ21DatCcdWindowParamGetHkTempFeeCcd(&TempFeeCcd.ui, pckt); + /* CrIaCopy(TEMP_FEE_ADC_ID, &TempFeeAdc.f); */ + CrSemServ21DatCcdWindowParamGetHkTempFeeAdc(&TempFeeAdc.ui, pckt); + /* CrIaCopy(TEMP_FEE_BIAS_ID, &TempFeeBias.f); */ + CrSemServ21DatCcdWindowParamGetHkTempFeeBias(&TempFeeBias.ui, pckt); + + CrIaCopy(ADC_N5V_RAW_ID, &AdcN5V); + CrIaCopy(ADC_TEMP1_RAW_ID, &Temp1); + + /* get 4 OTA temperatures */ + CrIaCopy(ADC_TEMPOH1A_RAW_ID, &TempOh1A); + CrIaCopy(ADC_TEMPOH1B_RAW_ID, &TempOh1B); + CrIaCopy(ADC_TEMPOH2A_RAW_ID, &TempOh2A); + CrIaCopy(ADC_TEMPOH2B_RAW_ID, &TempOh2B); + CrIaCopy(ADC_TEMPOH3A_RAW_ID, &TempOh3A); + CrIaCopy(ADC_TEMPOH3B_RAW_ID, &TempOh3B); + CrIaCopy(ADC_TEMPOH4A_RAW_ID, &TempOh4A); + CrIaCopy(ADC_TEMPOH4B_RAW_ID, &TempOh4B); + + /* NOTE: the ImageCycleCnt is initialized to -1 in the Sem Oper SM and also incremented there */ + CrIaCopy(IMAGECYCLECNT_ID, &ImageCycleCnt); + CrIaCopy(ACQIMAGECNT_ID, &AcqImageCnt); + + PRDEBUGP("S21: imagecycle %d acqimages %d AcqType %d AcqID %d S21LastAcqId %d CurrPcktNum %d\n", ImageCycleCnt, AcqImageCnt, AcqType, AcqId, S21LastAcqId, CurrentPacketNum); + + /* + initialize the outgoingSibInStruct structure + + NOTE: We cannot simply say "outgoingSibInStruct = incomingSibInStruct;", + because incomingSibInStruct is not initialized for the very first frame. + Instead, we derive it from SIBIN. + */ + + CrIaCopy(SIBIN_ID, &SibIn); + + /* initialize the outgoingSibInStruct structure */ + if (AcqType == CCD_FULL_ID) + { +#ifdef PC_TARGET + CrIaSetupSibFull (ShmOutgoingSibInPTR, SibIn); +#else + CrIaSetupSibFull (&outgoingSibInStruct, SibIn); +#endif + } + else + { + CrIaCopy(PWINSIZEX_ID, &semWinSizeX); + CrIaCopy(PWINSIZEY_ID, &semWinSizeY); +#ifdef PC_TARGET + CrIaSetupSibWin (ShmOutgoingSibInPTR, SibIn, semWinSizeX, semWinSizeY); +#else + CrIaSetupSibWin (&outgoingSibInStruct, SibIn, semWinSizeX, semWinSizeY); +#endif + } + + /* for the very first image we also have to initialize the incomingSibInStruct */ + if (S21_Flag0 == 1) /* very first image */ + { + /* initialize the incomingSibInStruct structure */ +#if (__sparc__) + if (AcqType == CCD_FULL_ID) + { + CrIaSetupSibFull (&incomingSibInStruct, SibIn); + } + else + { + CrIaCopy(PWINSIZEX_ID, &semWinSizeX); + CrIaCopy(PWINSIZEY_ID, &semWinSizeY); + + CrIaSetupSibWin (&incomingSibInStruct, SibIn, semWinSizeX, semWinSizeY); + } +#else + if (AcqType == CCD_FULL_ID) + { + CrIaSetupSibFull (ShmIncomingSibInPTR, SibIn); + } + else + { + CrIaCopy(PWINSIZEX_ID, &semWinSizeX); + CrIaCopy(PWINSIZEY_ID, &semWinSizeY); + + CrIaSetupSibWin (ShmIncomingSibInPTR, SibIn, semWinSizeX, semWinSizeY); + } +#endif /* (__sparc__) */ + + /* Mantis 2106 */ + S21_Flag0 = 0; + } + + /* copy header entries */ +#if (__sparc__) + sibHeader = (struct SibHeader *) incomingSibInStruct.Header; +#else + sibHeader = (struct SibHeader *) ShmIncomingSibInPTR->Header; +#endif /* (__sparc__) */ + + sibHeader->AcqId = AcqId; + sibHeader->AcqType = AcqType; + sibHeader->AcqSrc = AcqSrc; + sibHeader->CcdTimingScriptId = CcdTimingScriptId; + sibHeader->startTimeCoarse = startTimeCoarse; + sibHeader->startTimeFine = startTimeFine; + sibHeader->ExposureTime = ExposureTime; + sibHeader->TotalPacketNum = TotalPacketNum; + sibHeader->CurrentPacketNum = CurrentPacketNum; + sibHeader->VoltFeeVod = VoltFeeVod.ui; + sibHeader->VoltFeeVrd = VoltFeeVrd.ui; + sibHeader->VoltFeeVog = VoltFeeVog.ui; + sibHeader->VoltFeeVss = VoltFeeVss.ui; + sibHeader->TempFeeCcd = TempFeeCcd.ui; + sibHeader->TempFeeAdc = TempFeeAdc.ui; + sibHeader->TempFeeBias = TempFeeBias.ui; + sibHeader->N5V = (unsigned int)AdcN5V; + sibHeader->Temp1 = (unsigned int) Temp1; + sibHeader->PixDataOffset = PixDataOffset; + sibHeader->NumDataWords = NumDataWords; + sibHeader->TempOh1A = (unsigned int) TempOh1A; + sibHeader->TempOh1B = (unsigned int) TempOh1B; + sibHeader->TempOh2A = (unsigned int) TempOh2A; + sibHeader->TempOh2B = (unsigned int) TempOh2B; + sibHeader->TempOh3A = (unsigned int) TempOh3A; + sibHeader->TempOh3B = (unsigned int) TempOh3B; + sibHeader->TempOh4A = (unsigned int) TempOh4A; + sibHeader->TempOh4B = (unsigned int) TempOh4B; + + PRDEBUGP("INIT SIB HDR S21Upd: Sib=%d, STC=%u, exp=%u\n", SibIn, startTimeCoarse, ExposureTime); + + /* store AcqId of this packet */ + S21LastAcqId = AcqId; + + PRDEBUGP("SETTING LAST to %d\n", S21LastAcqId); + + /* reset the SEM image ACQ_TYPE collection flag */ + tcompl = 0; + CrIaPaste(TRANSFERCOMPLETE_ID, &tcompl); + + /* initialize the Centroid structure values */ +#if (__sparc__) + sibCentroid = (struct SibCentroid *) incomingSibInStruct.Centroid; + PrepareSibCentroid(&incomingSibInStruct, CEN_INV_ALGO, 0.0f, 0.0f); +#else + sibCentroid = (struct SibCentroid *) ShmIncomingSibInPTR->Centroid; + PrepareSibCentroid(ShmIncomingSibInPTR, CEN_INV_ALGO, 0.0f, 0.0f); +#endif /* (__sparc__) */ + endTimeCoarse = sibCentroid->endIntegCoarse; + endTimeFine = sibCentroid->endIntegFine; + CrIaPaste(INTEGENDTIMECRS_ID, &endTimeCoarse); + CrIaPaste(INTEGENDTIMEFINE_ID, &endTimeFine); + + /* + store the information of the SDS and SAA flags + */ +#if (__sparc__) + sibPhotometry = (struct SibPhotometry *) incomingSibInStruct.Photometry; +#else + sibPhotometry = (struct SibPhotometry *) ShmIncomingSibInPTR->Photometry; +#endif /* (__sparc__) */ + + sibPhotometry->FlagsActive = 0; + + CrIaCopy(ISSAAACTIVE_ID, &isSaaActive); + if (isSaaActive == 1) + { + sibPhotometry->FlagsActive = DATA_SAA; + } + + CrIaCopy(ISSDSACTIVE_ID, &isSdsActive); + if (isSdsActive == 1) + { + /* SDS overrules the SAA state */ + sibPhotometry->FlagsActive = DATA_SUSPEND; + } + + /* initialize the other SibPhotometry values */ + sibPhotometry->centrum = 0.0f; + sibPhotometry->annulus1 = 0.0f; + sibPhotometry->annulus2 = 0.0f; + + /* no outcome */ + + return; +} + + +/** Guard on the Control Flow from DECISION1 to DECISION2. */ +/* this is the first thing that is executed for a new report */ +FwPrBool_t CrIaSciDataUpdHasSdscLegalVal(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short CurrentPacketNum; + unsigned short TotalPacketNum; + CrFwPckt_t pckt; + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + + CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum (&CurrentPacketNum, pckt); + CrSemServ21DatCcdWindowParamGetHkStatTotalPacketNum (&TotalPacketNum, pckt); + + if (CurrentPacketNum == 0) + return 0; + + if (CurrentPacketNum > TotalPacketNum) + return 0; + + return 1; +} + +/** Guard on the Control Flow from DECISION2 to N3. */ +FwPrBool_t CrIaSciDataUpdIsSdscOutOfSeq(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short CurrentPacketNum; + CrFwPckt_t pckt; + + DEBUGP("Guard D2/N3.\n"); + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum (&CurrentPacketNum, pckt); + + /* sdsc value is out of seq if it differs from 1 and from n+1 (n is last sdsc report) */ + /* NOTE: in this rule sequences of 1 are valid, but this could also be intentional */ + + if (CurrentPacketNum == (S21LastPacketNum + 1)) + { + S21LastPacketNum = CurrentPacketNum; + return 0; + } + + if (CurrentPacketNum == 1) + { + S21LastPacketNum = CurrentPacketNum; + return 0; + } + + return 1; /* 1 means out of sync */ +} + +/** Guard on the Control Flow from DECISION3 to N4. */ +FwPrBool_t CrIaSciDataUpdIsSibTooSmall(FwPrDesc_t __attribute__((unused)) prDesc) +{ + CrFwPckt_t pckt; + + unsigned char AcqType; + unsigned short NumDataWords; + unsigned int end, size; + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + + /* check if sib slot is too small to hold new patch of science data + this depends on the acquisition type */ + CrSemServ21DatCcdWindowParamGetHkStatDataAcqType (&AcqType, pckt); + CrSemServ21DatCcdWindowParamGetHkStatNumDataWords (&NumDataWords, pckt); + +#if (__sparc__) + switch (AcqType) + { + case CCD_FULL_ID : + case CCD_WIN_EXPOS_ID : + + end = (incomingSibInStruct.ExposSamples + NumDataWords) * BPW_PIXEL; + size = incomingSibInStruct.ExposSize; + break; + + case CCD_WIN_LSM_ID : + + end = (incomingSibInStruct.LsmSamples + NumDataWords) * BPW_PIXEL; + size = incomingSibInStruct.LsmSize; + break; + + case CCD_WIN_RSM_ID : + + end = (incomingSibInStruct.RsmSamples + NumDataWords) * BPW_PIXEL; + size = incomingSibInStruct.RsmSize; + break; + + case CCD_WIN_TM_ID : + + end = (incomingSibInStruct.TmSamples + NumDataWords) * BPW_PIXEL; + size = incomingSibInStruct.TmSize; + break; + + default: + /* NOTE: cannot be reached by design */ + return 1; + } +#else + switch (AcqType) + { + case CCD_FULL_ID : + case CCD_WIN_EXPOS_ID : + + end = (ShmIncomingSibInPTR->ExposSamples + NumDataWords) * BPW_PIXEL; + size = ShmIncomingSibInPTR->ExposSize; + break; + + case CCD_WIN_LSM_ID : + + end = (ShmIncomingSibInPTR->LsmSamples + NumDataWords) * BPW_PIXEL; + size = ShmIncomingSibInPTR->LsmSize; + break; + + case CCD_WIN_RSM_ID : + + end = (ShmIncomingSibInPTR->RsmSamples + NumDataWords) * BPW_PIXEL; + size = ShmIncomingSibInPTR->RsmSize; + break; + + case CCD_WIN_TM_ID : + + end = (ShmIncomingSibInPTR->TmSamples + NumDataWords) * BPW_PIXEL; + size = ShmIncomingSibInPTR->TmSize; + break; + + default: + /* NOTE: cannot be reached by design */ + return 1; + } +#endif /* (__sparc__) */ + + if (end > size) + { + /* int the case of an excess we generate the event in N4 */ + return 1; + } + + return 0; +} + +/** Guard on the Control Flow from DECISION4 to N1. */ +FwPrBool_t CrIaSciDataUpdFlag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int AcqId; + CrFwPckt_t pckt; + + pckt = S21SemPacket; /* (CrFwPckt_t) FwPrGetData(prDescSciDataUpd); */ + CrSemServ21DatCcdWindowParamGetHkStatDataAcqId (&AcqId, pckt); + + /* flag1 true, when report is the first one of a new image and the curr img is not the first image + since science was started (report has new acq id and acq image count not zero) */ + + if (AcqId != S21LastAcqId) /* it will be updated in N1 */ + { + if (S21LastAcqId == 0xffffffff) /* equivalent to: if (AcqImageCnt != 0) */ + { + DEBUGP("FIRST REP OF FIRST FRAME\n"); + S21_Flag0 = 1; + /* do not raise the S21_Flag1 */ + } + else + { + DEBUGP("FIRST REP OF FRAME\n"); + S21_Flag1 = 1; + } + + /* in BOTH cases go to N1 where the incomingSibInStruct will be initialized */ + DEBUGP("GO to N1!\n"); + + return 1; + } + + DEBUGP("REP_WITHIN_FRAME\n"); + DEBUGP("GO to D2/D3!\n"); + /* S21_Flag1 = 0; will be cleared in the SEM Oper DO Action */ + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSciDataUpdInit.txt b/CrIa/src/CrIaPrSm/CrIaSciDataUpdInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..ea60aab39c81cb5515b609c0b1d555a619fc7131 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciDataUpdInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSciDataUpdCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSciDataUpd is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSciDataUpd is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSciWinCreate.c b/CrIa/src/CrIaPrSm/CrIaSciWinCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..f86079d51914a81710f3f35ca953a438697572e4 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciWinCreate.c @@ -0,0 +1,57 @@ +/** + * @file CrIaSciWinCreate.c + * + * @author FW Profile code generator version 5.01 + * @date Created on: Jul 16 2018 16:41:56 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSciWin function definitions */ +#include "CrIaSciWinCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSciWinCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 11, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 12, /* N_FLOWS - The number of control flows */ + 11, /* N_ACTIONS - The number of actions */ + 5 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaSciWin_N4, &CrIaSciWinN4); + FwPrAddActionNode(prDesc, CrIaSciWin_N5, &CrIaSciWinN5); + FwPrAddActionNode(prDesc, CrIaSciWin_N1, &CrIaSciWinN1); + FwPrAddActionNode(prDesc, CrIaSciWin_N9, &CrIaSciWinN9); + FwPrAddActionNode(prDesc, CrIaSciWin_N10, &CrIaSciWinN10); + FwPrAddActionNode(prDesc, CrIaSciWin_N8, &CrIaSciWinN8); + FwPrAddActionNode(prDesc, CrIaSciWin_N2, &CrIaSciWinN2); + FwPrAddActionNode(prDesc, CrIaSciWin_N3, &CrIaSciWinN3); + FwPrAddActionNode(prDesc, CrIaSciWin_N6, &CrIaSciWinN6); + FwPrAddActionNode(prDesc, CrIaSciWin_N5_1, &CrIaSciWinN5_1); + FwPrAddActionNode(prDesc, CrIaSciWin_N5_2, &CrIaSciWinN5_2); + FwPrAddFlowIniToAct(prDesc, CrIaSciWin_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N4, CrIaSciWin_N5, &CrIaSciWinWaitT2); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N5, CrIaSciWin_N5_1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N1, CrIaSciWin_N2, &CrIaSciWinIsSemInStab); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N9, CrIaSciWin_N10, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSciWin_N10, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N8, CrIaSciWin_N9, &CrIaSciWinIsTerm); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N2, CrIaSciWin_N3, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N3, CrIaSciWin_N4, &CrIaSciWinWaitT1); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N6, CrIaSciWin_N8, &CrIaSciWinFlag1And2); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N5_1, CrIaSciWin_N5_2, NULL); + FwPrAddFlowActToAct(prDesc, CrIaSciWin_N5_2, CrIaSciWin_N6, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSciWinCreate.h b/CrIa/src/CrIaPrSm/CrIaSciWinCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..aa86aebc57d7e042045fbdc723e0e3fa102b2bfe --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciWinCreate.h @@ -0,0 +1,193 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSciWin procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaSciWin.png + * + * @author FW Profile code generator version 5.01 + * @date Created on: Jul 16 2018 16:41:56 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSciWinCreate_H_ +#define CrIaSciWinCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSciWin_N1 (1) /* The identifier of action node N1 in procedure CrIaSciWin */ +#define CrIaSciWin_N2 (2) /* The identifier of action node N2 in procedure CrIaSciWin */ +#define CrIaSciWin_N3 (3) /* The identifier of action node N3 in procedure CrIaSciWin */ +#define CrIaSciWin_N4 (4) /* The identifier of action node N4 in procedure CrIaSciWin */ +#define CrIaSciWin_N5 (5) /* The identifier of action node N5 in procedure CrIaSciWin */ +#define CrIaSciWin_N5_1 (6) /* The identifier of action node N5_1 in procedure CrIaSciWin */ +#define CrIaSciWin_N5_2 (7) /* The identifier of action node N5_2 in procedure CrIaSciWin */ +#define CrIaSciWin_N6 (8) /* The identifier of action node N6 in procedure CrIaSciWin */ +#define CrIaSciWin_N8 (9) /* The identifier of action node N8 in procedure CrIaSciWin */ +#define CrIaSciWin_N9 (10) /* The identifier of action node N9 in procedure CrIaSciWin */ +#define CrIaSciWin_N10 (11) /* The identifier of action node N10 in procedure CrIaSciWin */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSciWinCreate(void* prData); + +/** + * Action for node N4. + * Send cmd (220,11) to SEM + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN4(FwPrDesc_t prDesc); + +/** + * Action for node N5. + * <pre> + * Send command GoToCcdWindow + * to SEM Unit State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN5(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * <pre> + * Generate Event Report + * EVT_SC_PR_STRT + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN1(FwPrDesc_t prDesc); + +/** + * Action for node N9. + * <pre> + * Stop Compression/Collection + * and Centroiding Algorithms + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN9(FwPrDesc_t prDesc); + +/** + * Action for node N10. + * <pre> + * Generate Event Report + * EVT_SC_PR_END with + * outcome equal to: "success" + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN10(FwPrDesc_t prDesc); + +/** + * Action for node N8. + * <pre> + * Send command GoToStabilize + * to SEM Unit State Machine + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN8(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Update SEM configuration + * parameters in the data pool + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * Send cmd (220,3) to SEM + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN3(FwPrDesc_t prDesc); + +/** + * Action for node N6. + * <pre> + * Start Compression/Collection + * Algorithm + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN6(FwPrDesc_t prDesc); + +/** + * Action for node N5_1. + * <pre> + * Enable selected + * centroiding algorithm + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN5_1(FwPrDesc_t prDesc); + +/** + * Action for node N5_2. + * Start Centroiding Algorithms + * @param smDesc the procedure descriptor + */ +void CrIaSciWinN5_2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N4 to N5. + * Wait sciWinStackT2 cycles + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciWinWaitT2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N1 to N2. + * SEM State Machine is in STABILIZE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciWinIsSemInStab(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N9 to N10. + * <pre> + * (SEM Operational SM is in STABILIZE) && + * (All sporadic activities have terminated) + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciWinIsTerm(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N3 to N4. + * Wait sciWinStackT1 cycles + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciWinWaitT1(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N6 to N8. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSciWinFlag1And2(FwPrDesc_t prDesc); + +#endif /* CrIaSciWinCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaSciWinFunc.c b/CrIa/src/CrIaPrSm/CrIaSciWinFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..1b65b53cb99cd3e88a693931ec5db0a7dcf6509a --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciWinFunc.c @@ -0,0 +1,375 @@ +/** + * @file CrIaSciWinFunc.c + * @ingroup CrIaPrSci + * @author FW Profile code generator version 5.01; Institute for Astrophysics, 2015-2016 + * @date Created on: Jul 16 2018 16:41:56 + * + * @brief Implementation of the Calibration Full Snap Procedure nodes and guards. + * Perform an observation of type SCI/WIN/STACK or SCI/WIN/SNAP with 'WIN' being any of the window sub-modes. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +#include <FwProfile/FwPrCore.h> /* for FwPrGetCurNode() */ + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> + +/** CrIaSciWin function definitions */ +#include "CrIaSciWinCreate.h" + +#include <CrIaIasw.h> /* for Event Reporting and extern sm and prDescriptors */ +#include <CrIaPrSm/CrIaSemCreate.h> /* for GoToCcdWindow and GoToStabilize */ +#include <CrIaPrSm/CrIaAlgoCreate.h> /* for Start and Stop */ + +#include <IfswDebug.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSciWinN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_SCI_STACK_PR; + + /* Generate event report EVT_SC_PR_STRT */ + + evt_data[0] = ProcId; + evt_data[1] = 0; /* NOT USED */ + + DEBUGP("SciWin N1: Event %d generated to signal start of SCI STACK PR\n", ProcId); + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_STRT, evt_data, 4); + + return; +} + +/** Action for node N2. */ +void CrIaSciWinN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short utemp16; + unsigned int utemp32; + + /* Update SEM configuration parameters in the data pool */ + + DEBUGP("SciWin N3: Update SEM configuration parameters in the data pool\n"); + + /* needed for TC(220/3) CMD_Operation_Parameter */ + + CrIaCopy(SCIWIN_PEXPTIME_ID, &utemp32); + CrIaPaste(PEXPTIME_ID, &utemp32); + + CrIaCopy(SCIWIN_PIMAGEREP_ID, &utemp32); + CrIaPaste(PIMAGEREP_ID, &utemp32); + + CrIaCopy(SCIWIN_PNMBIMAGES_ID, &utemp32); + CrIaPaste(PACQNUM_ID, &utemp32); + + utemp16 = 0; /* means "NO" */ + CrIaPaste(PDATAOS_ID, &utemp16); + + CrIaCopy(SCIWIN_PCCDRDMODE_ID, &utemp16); + CrIaPaste(PCCDRDMODE_ID, &utemp16); + + /* needed for TC(220/11) CMD_Functional_Parameter */ + + CrIaCopy(SCIWIN_PWINPOSX_ID, &utemp16); + CrIaPaste(PWINPOSX_ID, &utemp16); + + CrIaCopy(SCIWIN_PWINPOSY_ID, &utemp16); + CrIaPaste(PWINPOSY_ID, &utemp16); + + CrIaCopy(SCIWIN_PWINSIZEX_ID, &utemp16); + CrIaPaste(PWINSIZEX_ID, &utemp16); + + CrIaCopy(SCIWIN_PWINSIZEY_ID, &utemp16); + CrIaPaste(PWINSIZEY_ID, &utemp16); + + return; +} + +/** Action for node N3. */ +void CrIaSciWinN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* Send cmd (220,3) to SEM */ + /* Changes the SEM Operational Parameter */ + + DEBUGP("SciWin N3: Send cmd (220,3) to SEM\n"); + + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV220, CRSEM_SERV220_CMD_OPER_PARAM, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* NOTE: parameters are set in the cmd update action according to the data pool entries */ + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/** Action for node N4. */ +void CrIaSciWinN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* Send cmd (220,11) to SEM */ + /* Changes the SEM Functional Parameter */ + + DEBUGP("SciWin N4: Send cmd (220,11) to SEM\n"); + + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV220, CRSEM_SERV220_CMD_FUNCT_PARAM, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* NOTE: parameters are set in the cmd update action according to the data pool entries */ + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/** Action for node N5. */ +void CrIaSciWinN5(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send command GoToCcdWindow to SEM Unit State Machine */ + + DEBUGP("SciWin N5: Send command GoToCcdWindow to SEM Unit State Machine\n"); + + FwSmMakeTrans(smDescSem, GoToCcdWindow); + + return; +} + +/** Action for node N5_1. */ +void CrIaSciWinN5_1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char defCentEnabled = 0, dumCentEnabled = 0; + unsigned short pCentSel; + + /* Enable the selected centroiding algorithm */ + + DEBUGP("SciWin N5_1: Enable the selected centroiding algorithm\n"); + + CrIaCopy(SCIWIN_PCENTSEL_ID, &pCentSel); + + if (pCentSel != NO_CENT) + { + if (pCentSel == DUM_CENT) + { + dumCentEnabled = 1; + } + else + { + defCentEnabled = 1; + } + } + + CrIaPaste(ALGOCENT0ENABLED_ID, &dumCentEnabled); + CrIaPaste(ALGOCENT1ENABLED_ID, &defCentEnabled); + + return; +} + +/** Action for node N5_2. */ +void CrIaSciWinN5_2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Start Centroiding Algorithms */ + + DEBUGP("SciWin N5_2: Start Centroiding Algorithms\n"); + + FwSmMakeTrans(smDescAlgoCent0, Start); + FwSmMakeTrans(smDescAlgoCent1, Start); + + return; +} + +/** Action for node N6. */ +void CrIaSciWinN6(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Start Compression/Collection Algorithm */ + + PRDEBUGP("SciWin N6: Start Compression/Collection Algorithm\n"); + + FwSmMakeTrans(smDescAlgoCmpr, Start); + + return; +} + +/** Action for node N8. */ +void CrIaSciWinN8(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Send command GoToStabilize to SEM Unit State Machine */ + + DEBUGP("SciWin N8: Send command GoToStabilize to SEM Unit State Machine\n"); + + FwSmMakeTrans(smDescSem, GoToStabilize); + + return; +} + +/** Action for node N9. */ +void CrIaSciWinN9(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Stop Collection, Compression and Centroiding Algorithms */ + + DEBUGP("SciWin N9: Stop Collection, Compression and Centroiding Algorithms\n"); + + FwSmMakeTrans(smDescAlgoCent0, Stop); + FwSmMakeTrans(smDescAlgoCent1, Stop); + FwSmMakeTrans(smDescAlgoCmpr, Stop); + + return; +} + +/** Action for node N10. */ +void CrIaSciWinN10(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_SCI_STACK_PR; + + /* Generate event report EVT_SC_PR_END with outcome "success" */ + + evt_data[0] = ProcId; + evt_data[1] = 1; /* 1 means success */ + + DEBUGP("SciWin N10: Event %d generated to signal end (but not stop) of SCI STACK PR\n", ProcId); + CrIaEvtRep(1, CRIA_SERV5_EVT_SC_PR_END, evt_data, 4); + + return; +} + +/**************/ +/*** GUARDS ***/ +/**************/ + +/** Guard on the Control Flow from N1 to N2. */ +FwPrBool_t CrIaSciWinIsSemInStab(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state; + + /* [ SEM State Machine is in STABILIZE ] */ + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if (sem_oper_state == CrIaSem_STABILIZE) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N3 to N4. */ +FwPrBool_t CrIaSciWinWaitT1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int sciWinT1; + + CrIaCopy(SCIWINT1_ID, &sciWinT1); + + /* Wait sciWinStackT1 cycles */ + if (FwPrGetNodeExecCnt(prDesc) < sciWinT1) + { + return 0; + } + else + { + return 1; + } +} + +/** Guard on the Control Flow from N4 to N5. */ +FwPrBool_t CrIaSciWinWaitT2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int sciWinT2; + + CrIaCopy(SCIWINT2_ID, &sciWinT2); + + /* Wait sciWinStackT2 cycles */ + if (FwPrGetNodeExecCnt(prDesc) < sciWinT2) + { + return 0; + } + else + { + return 1; + } +} + +/** Guard on the Control Flow from N6 to N8. */ +FwPrBool_t CrIaSciWinFlag1And2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int AcqImageCnt; + unsigned int SciWin_pNmbImages; + unsigned char lstpckt; + + /* [ Flag_1 ] */ + /* Flag_1: is true in cycle in which (acqImageCnt+1) is equal to pNmbImages and LastSemPckt is true */ + + CrIaCopy(ACQIMAGECNT_ID, &AcqImageCnt); + CrIaCopy(SCIWIN_PNMBIMAGES_ID, &SciWin_pNmbImages); + CrIaCopy(LASTSEMPCKT_ID, &lstpckt); + + DEBUGP("%u %u %u\n", AcqImageCnt, SciWin_pNmbImages, lstpckt); + + if (((AcqImageCnt+1) == SciWin_pNmbImages) && (lstpckt == 1)) + return 1; + + return 0; +} + +/** Guard on the Control Flow from N8 to N9. */ +FwPrBool_t CrIaSciWinIsTerm(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sem_oper_state, Cpu2ProcStatus; + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + /* get state of second CPU */ + CrIaCopy(CPU2PROCSTATUS_ID, &Cpu2ProcStatus); + + if (sem_oper_state == CrIaSem_STABILIZE) /* SEM Operational SM is in STABILIZE */ + if (Cpu2ProcStatus == SDP_STATUS_IDLE) /* All sporadic activities have terminated */ + return 1; + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSciWinInit.txt b/CrIa/src/CrIaPrSm/CrIaSciWinInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..c4d6527d5508f50d1c8f44eadb966e9f9b7fdec1 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSciWinInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSciWinCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSciWin is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSciWin is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSdbCreate.c b/CrIa/src/CrIaPrSm/CrIaSdbCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..1b9d832a3cab52d8aa418f908143d941937ec89e --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdbCreate.c @@ -0,0 +1,59 @@ +/** + * @file CrIaSdbCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" + +/** CrIaSdb function definitions */ +#include "CrIaSdbCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t CrIaSdbCreate(void* smData) +{ + const FwSmCounterU2_t N_OUT_OF_UNCONFIGURED = 2; /* The number of transitions out of state UNCONFIGURED */ + const FwSmCounterU2_t N_OUT_OF_CONFIG_FULL = 3; /* The number of transitions out of state CONFIG_FULL */ + const FwSmCounterU2_t CHOICE1 = 1; /* The identifier of choice pseudo-state CHOICE1 in State Machine CrIaSdb */ + const FwSmCounterU2_t N_OUT_OF_CHOICE1 = 2; /* The number of transitions out of the choice-pseudo state CHOICE1 */ + const FwSmCounterU2_t N_OUT_OF_CONFIG_WIN = 3; /* The number of transitions out of state CONFIG_WIN */ + const FwSmCounterU2_t CHOICE2 = 2; /* The identifier of choice pseudo-state CHOICE2 in State Machine CrIaSdb */ + const FwSmCounterU2_t N_OUT_OF_CHOICE2 = 2; /* The number of transitions out of the choice-pseudo state CHOICE2 */ + + /** Create state machine smDesc */ + FwSmDesc_t smDesc = FwSmCreate( + 3, /* NSTATES - The number of states */ + 2, /* NCPS - The number of choice pseudo-states */ + 13, /* NTRANS - The number of transitions */ + 4, /* NACTIONS - The number of state and transition actions */ + 2 /* NGUARDS - The number of transition guards */ + ); + + /** Configure the state machine smDesc */ + FwSmSetData(smDesc, smData); + FwSmAddState(smDesc, CrIaSdb_UNCONFIGURED, N_OUT_OF_UNCONFIGURED, NULL, NULL, NULL, NULL); + FwSmAddState(smDesc, CrIaSdb_CONFIG_FULL, N_OUT_OF_CONFIG_FULL, &CrIaSdbConfigFullEntry, NULL, NULL, NULL); + FwSmAddChoicePseudoState(smDesc, CHOICE1, N_OUT_OF_CHOICE1); + FwSmAddState(smDesc, CrIaSdb_CONFIG_WIN, N_OUT_OF_CONFIG_WIN, &CrIaSdbConfigWinEntry, NULL, NULL, NULL); + FwSmAddChoicePseudoState(smDesc, CHOICE2, N_OUT_OF_CHOICE2); + FwSmAddTransStaToCps(smDesc, ConfigFull, CrIaSdb_UNCONFIGURED, CHOICE1, &CrIaSdbAction1, NULL); + FwSmAddTransStaToCps(smDesc, ConfigWin, CrIaSdb_UNCONFIGURED, CHOICE2, &CrIaSdbAction1, NULL); + FwSmAddTransStaToSta(smDesc, Reset, CrIaSdb_CONFIG_FULL, CrIaSdb_UNCONFIGURED, NULL, NULL); + FwSmAddTransStaToSta(smDesc, ResetFull, CrIaSdb_CONFIG_FULL, CrIaSdb_CONFIG_FULL, NULL, NULL); + FwSmAddTransStaToSta(smDesc, ResetWin, CrIaSdb_CONFIG_FULL, CrIaSdb_CONFIG_WIN, NULL, NULL); + FwSmAddTransIpsToSta(smDesc, CrIaSdb_UNCONFIGURED, NULL); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaSdb_CONFIG_FULL, &CrIaSdbAction2, &CrIaSdbIsConfigSuccess); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaSdb_UNCONFIGURED, NULL, &CrIaSdbIsConfigFailed); + FwSmAddTransStaToSta(smDesc, ResetFull, CrIaSdb_CONFIG_WIN, CrIaSdb_CONFIG_FULL, NULL, NULL); + FwSmAddTransStaToSta(smDesc, Reset, CrIaSdb_CONFIG_WIN, CrIaSdb_UNCONFIGURED, NULL, NULL); + FwSmAddTransStaToSta(smDesc, ResetWin, CrIaSdb_CONFIG_WIN, CrIaSdb_CONFIG_WIN, NULL, NULL); + FwSmAddTransCpsToSta(smDesc, CHOICE2, CrIaSdb_CONFIG_WIN, &CrIaSdbAction2, &CrIaSdbIsConfigSuccess); + FwSmAddTransCpsToSta(smDesc, CHOICE2, CrIaSdb_UNCONFIGURED, NULL, &CrIaSdbIsConfigFailed); + + return smDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSdbCreate.h b/CrIa/src/CrIaPrSm/CrIaSdbCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..eacd08e624f5ffebbb6d98ed9da258fe7f0239a1 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdbCreate.h @@ -0,0 +1,105 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSdb state machine. + * The state machine is configured with a set of function pointers representing the non-default + * actions and guards of the state machine. Some of these functions may also be declared in + * this header file in accordance with the configuration of the state machine in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The state machine created by this file is shown in the figure below. + * @image html CrIaSdb.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSdbCreate_H_ +#define CrIaSdbCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" + +/** State identifiers */ +#define CrIaSdb_CONFIG_FULL 1 /* The identifier of state CONFIG_FULL in State Machine CrIaSdb */ +#define CrIaSdb_CONFIG_WIN 2 /* The identifier of state CONFIG_WIN in State Machine CrIaSdb */ +#define CrIaSdb_UNCONFIGURED 3 /* The identifier of state UNCONFIGURED in State Machine CrIaSdb */ + +/** The identifiers of transition commands (triggers) */ +#define ConfigFull 21 +#define ConfigWin 22 +#define ResetFull 23 +#define Reset 2 +#define ResetWin 24 + +/** + * Create a new state machine descriptor. + * This interface creates the state machine descriptor dynamically. + * @param smData the pointer to the state machine data. + * A value of NULL is legal (note that the default value of the pointer + * to the state machine data when the state machine is created is NULL). + * @return the pointer to the state machine descriptor + */ +FwSmDesc_t CrIaSdbCreate(void* smData); + +/** + * Entry Action for the state CONFIG_FULL. + * <pre> + * Initialize sibIn, sibOut, cibIn and + * gibIn to point to first SIB, CIB and + * GIB for CCD Full images. + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSdbConfigFullEntry(FwSmDesc_t smDesc); + +/** + * Entry Action for the state CONFIG_WIN. + * <pre> + * Initialize sibIn, sibOut, cibIn and + * gibIn to point to first SIB, CIB and + * GIB for CCD Window images. + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSdbConfigWinEntry(FwSmDesc_t smDesc); + +/** + * Action on the transition from UNCONFIGURED to CHOICE1. + * Action_1 + * @param smDesc the state machine descriptor + */ +void CrIaSdbAction1(FwSmDesc_t smDesc); + +/** + * Action on the transition from CHOICE2 to CONFIG_WIN. + * Action_2 + * @param smDesc the state machine descriptor + */ +void CrIaSdbAction2(FwSmDesc_t smDesc); + +/** + * Guard on the transition from CHOICE2 to CONFIG_WIN. + * <pre> + * SDB Configuration was + * successful + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSdbIsConfigSuccess(FwSmDesc_t smDesc); + +/** + * Guard on the transition from CHOICE2 to UNCONFIGURED. + * <pre> + * SDB Configuration + * failed + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSdbIsConfigFailed(FwSmDesc_t smDesc); + +#endif /* CrIaSdbCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSdbFunc.c b/CrIa/src/CrIaPrSm/CrIaSdbFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..7b941882ba87c6fabbae742cf4643454fd3d616d --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdbFunc.c @@ -0,0 +1,304 @@ +/** + * @file CrIaSdbFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" +#include "FwProfile/FwSmCore.h" +#include "CrFwCmpData.h" + +/** CrIaSdb function definitions */ +#include "CrIaSdbCreate.h" + +/* access to data pool */ +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamGetter.h> + +#include "IfswDebug.h" + +#include "Sdp/SdpBuffers.h" + +#include <CrIaIasw.h> /* for *sibAddressFull, ... */ + +#if (__sparc__) +#include <wrap_malloc.h> /* for sram2 address */ +#else +#include "Sdp/SdpBuffers.h" +#endif + +/* needed to tell the guard CrIaSdbIsConfigSuccess about the action1 outcome */ +unsigned int SdbAllocFail = 0; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Entry Action for the state CONFIG_FULL. */ +void CrIaSdbConfigFullEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* initialize cibIn and gibIn to point to first CIB and GIB for CCD Full images. */ + unsigned short SibInFull, SibOutFull, CibInFull, GibInFull, GibOutFull; + unsigned short SdbState; + unsigned int base = 0; + unsigned int gibbase = 0; + + gibbase = GET_ADDR_FROM_RES_OFFSET(0); + base = GET_ADDR_FROM_SDB_OFFSET(0); + + /* set SDB state to FULL */ + SdbState = CrIaSdb_CONFIG_FULL; + CrIaPaste(SDBSTATE_ID, &SdbState); + + /* assign the addresses, note that they are addresses in kiB */ + SibInFull = (unsigned short)(((unsigned int)sibAddressFull - base) >> 10); + SibOutFull = (unsigned short)(((unsigned int)sibAddressFull - base) >> 10); + CibInFull = (unsigned short)(((unsigned int)cibAddressFull - base) >> 10); + GibInFull = (unsigned short)(((unsigned int)gibAddressFull - gibbase) >> 10); + GibOutFull = (unsigned short)(((unsigned int)gibAddressFull - gibbase) >> 10); + + CrIaPaste(SIBIN_ID, &SibInFull); + CrIaPaste(SIBOUT_ID, &SibOutFull); + CrIaPaste(CIBIN_ID, &CibInFull); + CrIaPaste(GIBIN_ID, &GibInFull); + CrIaPaste(GIBOUT_ID, &GibOutFull); + + return; +} + +/** Entry Action for the state CONFIG_WIN. */ +void CrIaSdbConfigWinEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* initialize cibIn and gibIn to point to first CIB and GIB for CCD Window images. */ + unsigned short SibInWin, SibOutWin, CibInWin, GibInWin, GibOutWin; + unsigned short SdbState; + unsigned int base = 0; + unsigned int gibbase = 0; + + gibbase = GET_ADDR_FROM_RES_OFFSET(0); + base = GET_ADDR_FROM_SDB_OFFSET(0); + + /* set SDB state to WIN */ + SdbState = CrIaSdb_CONFIG_WIN; + CrIaPaste(SDBSTATE_ID, &SdbState); + + /* assign the addresses, note that they are addresses in kiB */ + SibInWin = (unsigned short)(((unsigned int)sibAddressWin - base) >> 10); + SibOutWin = (unsigned short)(((unsigned int)sibAddressWin - base) >> 10); + CibInWin = (unsigned short)(((unsigned int)cibAddressFull - base) >> 10); /* NOTE: the CIB is Full+Win together as one block, it starts with Full */ + GibInWin = (unsigned short)(((unsigned int)gibAddressWin - gibbase) >> 10); + GibOutWin = (unsigned short)(((unsigned int)gibAddressWin - gibbase) >> 10); + + CrIaPaste(SIBIN_ID, &SibInWin); + CrIaPaste(SIBOUT_ID, &SibOutWin); + CrIaPaste(CIBIN_ID, &CibInWin); + CrIaPaste(GIBIN_ID, &GibInWin); + CrIaPaste(GIBOUT_ID, &GibOutWin); + + DEBUGP("Entry action into CONFIG_WIN\n"); + + return; +} + +/** Action on the transition from UNCONFIGURED to CHOICE1. */ +void CrIaSdbAction1(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short CibNFull, SibNFull, GibNFull, SibNWin, CibNWin, GibNWin; + unsigned short CibSizeFull, SibSizeFull, GibSizeFull, CibSizeWin, SibSizeWin, GibSizeWin; + unsigned int CibSize, SibSize, GibSize; + unsigned int size; + unsigned short evt_data[2]; + unsigned short ProcId = CRIA_SERV198_CONFIG_SDB_PR; + + DEBUGP("transition from unconfigured to choice1 started\n"); + + /* get the sizes from the data pool, + i.e. these have to be overwritten by the caller before */ + CrIaCopy(CIBNFULL_ID, &CibNFull); + CrIaCopy(CIBSIZEFULL_ID, &CibSizeFull); + CrIaCopy(SIBNFULL_ID, &SibNFull); + CrIaCopy(SIBSIZEFULL_ID, &SibSizeFull); + CrIaCopy(GIBNFULL_ID, &GibNFull); + CrIaCopy(GIBSIZEFULL_ID, &GibSizeFull); + CrIaCopy(SIBNWIN_ID, &SibNWin); + CrIaCopy(SIBSIZEWIN_ID, &SibSizeWin); + CrIaCopy(CIBNWIN_ID, &CibNWin); + CrIaCopy(CIBSIZEWIN_ID, &CibSizeWin); + CrIaCopy(GIBNWIN_ID, &GibNWin); + CrIaCopy(GIBSIZEWIN_ID, &GibSizeWin); + + /* use the larger of full/win for SIB and CIB */ + if (SibNFull * SibSizeFull > SibNWin * SibSizeWin) + SibSize = SibNFull * SibSizeFull; + else + SibSize = SibNWin * SibSizeWin; + + if (CibNFull * CibSizeFull > CibNWin * CibSizeWin) + CibSize = CibNFull * CibSizeFull; + else + CibSize = CibNWin * CibSizeWin; + + /* in the gib the two states win/full need to coexist */ + GibSize = GibNFull * GibSizeFull + GibNWin * GibSizeWin; + + /* now check sizes against the buffer limits */ + SdbAllocFail = 0; + + /* check if the gib setting fits */ + if (GibSize * 1024 > SRAM1_RES_SIZE) + { + /* error, too much RAM is requested */ + SdbAllocFail = 1; + } + + /* check for SIB + CIB */ + if ((CibSize + SibSize)*1024 > SDB_SIZE) /* NOTE: count in kiB */ + { + /* error, too much RAM is requested */ + SdbAllocFail = 1; + } + + if (SdbAllocFail == 1) + { + DEBUGP("transition from unconfigured to choice1 ended with a problem: nothing allocated\n"); + DEBUGP("CibSize (Win) = %u\n", CibSizeWin); + DEBUGP("SibSize (Win) = %u\n", SibSizeWin); + DEBUGP("GibSize (Win) = %u\n", GibSizeWin); + DEBUGP("CibSize (Full) = %u\n", CibSizeFull); + DEBUGP("SibSize (Full) = %u\n", SibSizeFull); + DEBUGP("GibSize (Full) = %u\n", GibSizeFull); + DEBUGP("CibSize (Win+Full) = %u\n", CibSize); + DEBUGP("SibSize (Win+Full) = %u\n", SibSize); + DEBUGP("GibSize (Win+Full) = %u\n", GibSize); + DEBUGP("SDB_SIZE = %u\n", (unsigned int)SDB_SIZE); + + ERRDEBUGP("ERROR allocating SDB\n"); + + evt_data[0] = ProcId; + evt_data[1] = 0; /* NOT USED */ + + CrIaEvtRep(3, CRIA_SERV5_EVT_SDB_CNF_FAIL, evt_data, 4); + + return; + } + + /* + configuration of the SDB. + Science Data Processing is asking to have the CIBs (win/full) in sequence + + So we make the order: + SIB FULL/WIN + CIB FULL/WIN + GIB FULL (in SRAM1) + GIB WIN (in SRAM1) + */ + + /* here we free the previously allocated SDB ram */ +#if (__sparc__) + release (SDB); +#else + sdballoc (0, 1); /* reset on PC */ +#endif + + /* SIB (shared, size defined by the larger of win or full) */ + size = SibSize * 1024; + + if (size != 0) + { + sibAddressFull = SDBALLOC(size, SDB); + sibAddressWin = sibAddressFull; + } + else + { + sibAddressFull = NULL; + sibAddressWin = NULL; + } + + /* CIB (shared, size defined by the larger of win or full */ + size = CibSize * 1024; + + if (size != 0) + { + cibAddressFull = SDBALLOC(size, SDB); + cibAddressWin = cibAddressFull; + } + else + { + cibAddressFull = NULL; + cibAddressWin = NULL; + } + + /* allocate GIB from RES area in SRAM1 */ + + /* first reset it */ +#if (__sparc__) + release (RES); +#else + resalloc (0, 1); /* reset on PC */ +#endif + + /* GIB FULL */ + size = GibNFull * GibSizeFull * 1024; + if (size != 0) + { + gibAddressFull = RESALLOC(size, RES); + } + else + { + gibAddressFull = (unsigned int *)(GET_ADDR_FROM_RES_OFFSET(0)); /* NOTE: the GIB has a physical offset, we must not use NULL here */ + } + + /* GIB WIN */ + size = GibNWin * GibSizeWin * 1024; /* NOTE: we count in kiB */ + if (size != 0) + { + gibAddressWin = RESALLOC(size, RES); + } + else + { + gibAddressWin = (unsigned int *)(GET_ADDR_FROM_RES_OFFSET(0)); /* NOTE: the GIB has a physical offset, we must not use NULL here */ + } + + DEBUGP("transition from unconfigured to choice1 ended -- stuff has been allocated\n"); + + return; +} + +/** Action on the transition from CHOICE2 to CONFIG_WIN. */ +void CrIaSdbAction2(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* this is already done in the Serv198 Proc Start CONFIGURE section */ + + return; +} + +/** Guard on the transition from CHOICE2 to CONFIG_WIN or FULL. */ +FwSmBool_t CrIaSdbIsConfigSuccess(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* configuration succeeded then return 1, else return 0 */ + if (SdbAllocFail == 1) + { + return 0; + } + + return 1; +} + +/** Guard on the transition from CHOICE2 to UNCONFIGURED. */ +FwSmBool_t CrIaSdbIsConfigFailed(FwSmDesc_t __attribute__((unused)) smDesc) +{ + return SdbAllocFail; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSdbInit.txt b/CrIa/src/CrIaPrSm/CrIaSdbInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..1f14a387a262e637eb2f2b13aee33be9252527c3 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdbInit.txt @@ -0,0 +1,23 @@ +{ + /** Define the state machine descriptor (SMD) */ + FwSmDesc_t smDesc = CrIaSdbCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDesc) != smSuccess) { + printf("The state machine CrIaSdb is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The state machine CrIaSdb is properly configured ... SUCCESS\n"); + } + + /** Start the SM, send a few transition commands to it, and execute it */ + FwSmStart(smDesc); + FwSmMakeTrans(smDesc, ConfigFull); + FwSmMakeTrans(smDesc, ConfigWin); + FwSmMakeTrans(smDesc, ResetFull); + FwSmMakeTrans(smDesc, Reset); + FwSmMakeTrans(smDesc, ResetWin); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecCreate.c b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..7c92b127b22fc014def69fddabe5ecba5305170b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecCreate.c @@ -0,0 +1,72 @@ +/** + * @file CrIaSdsEvalAlgoExecCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSdsEvalAlgoExec function definitions */ +#include "CrIaSdsEvalAlgoExecCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to DECISION2. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code57081(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION2 to N2. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code44123(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSdsEvalAlgoExecCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaSdsEvalAlgoExec */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 3; /* The number of control flows out of decision node DECISION1 in procedure CrIaSdsEvalAlgoExec */ + const FwPrCounterU2_t DECISION2 = 2; /* The identifier of decision node DECISION2 in procedure CrIaSdsEvalAlgoExec */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaSdsEvalAlgoExec */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 2, /* N_ANODES - The number of action nodes */ + 2, /* N_DNODES - The number of decision nodes */ + 8, /* N_FLOWS - The number of control flows */ + 2, /* N_ACTIONS - The number of actions */ + 6 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaSdsEvalAlgoExec_N1, &CrIaSdsEvalAlgoExecSetSdsActive); + FwPrAddActionNode(prDesc, CrIaSdsEvalAlgoExec_N2, &CrIaSdsEvalAlgoExecSetSdsInactive); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddFlowIniToDec(prDesc, DECISION1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSdsEvalAlgoExec_N1, &CrIaSdsEvalAlgoExecC1); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSdsEvalAlgoExec_N2, &CrIaSdsEvalAlgoExecC2); + FwPrAddFlowDecToDec(prDesc, DECISION1, DECISION2, &code57081); + FwPrAddFlowActToDec(prDesc, CrIaSdsEvalAlgoExec_N1, DECISION1, &CrIaSdsEvalAlgoExecIsNextExec); + FwPrAddFlowActToDec(prDesc, CrIaSdsEvalAlgoExec_N2, DECISION1, &CrIaSdsEvalAlgoExecIsNextExec); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaSdsEvalAlgoExec_N1, &CrIaSdsEvalAlgoExecC3); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaSdsEvalAlgoExec_N2, &code44123); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecCreate.h b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..4a19a86d72de708414f9abe18a9f8b7e42b18123 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecCreate.h @@ -0,0 +1,90 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSdsEvalAlgoExec procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * + * <b>Note for Control Flow from N1 to DECISION1</b> + * This guard returns true if the Node Execution Counter + * (as returned by FwPrGetNodeExecCnt) is equal to 1. + * + * @image html CrIaSdsEvalAlgoExec.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSdsEvalAlgoExecCreate_H_ +#define CrIaSdsEvalAlgoExecCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSdsEvalAlgoExec_N1 1 /* The identifier of action node N1 in procedure CrIaSdsEvalAlgoExec */ +#define CrIaSdsEvalAlgoExec_N2 2 /* The identifier of action node N2 in procedure CrIaSdsEvalAlgoExec */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSdsEvalAlgoExecCreate(void* prData); + +/** + * Action for node N1. + * isSdsActive = TRUE + * @param smDesc the procedure descriptor + */ +void CrIaSdsEvalAlgoExecSetSdsActive(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * isSdsActive = FALSE + * @param smDesc the procedure descriptor + */ +void CrIaSdsEvalAlgoExecSetSdsInactive(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N1. + * SDS_FORCED && !SDS_INHIBITED + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSdsEvalAlgoExecC1(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N2. + * !SDS_FORCED && SDS_INHIBITED + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSdsEvalAlgoExecC2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N1 to DECISION1. + * Next Execution + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSdsEvalAlgoExecIsNextExec(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N1. + * isSaaActive || EARTH_OCCULT_ACTIVE + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSdsEvalAlgoExecC3(FwPrDesc_t prDesc); + +#endif /* CrIaSdsEvalAlgoExecCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecFunc.c b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..b6e14dcb9740e5f0523785d22578b104562d5f14 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecFunc.c @@ -0,0 +1,127 @@ +/** + * @file CrIaSdsEvalAlgoExecFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaSdsEvalAlgoExec function definitions */ +#include "CrIaSdsEvalAlgoExecCreate.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSdsEvalAlgoExecSetSdsActive(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char isSdsActive; + + /* isSdsActive = TRUE */ + + isSdsActive = 1; + CrIaPaste(ISSDSACTIVE_ID, &isSdsActive); + + return; +} + +/** Action for node N2. */ +void CrIaSdsEvalAlgoExecSetSdsInactive(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char isSdsActive; + + /* isSdsActive = FALSE */ + + isSdsActive = 0; + CrIaPaste(ISSDSACTIVE_ID, &isSdsActive); + + return; +} + +/** Guard on the Control Flow from DECISION1 to N1. */ +FwPrBool_t CrIaSdsEvalAlgoExecC1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char sdsForced, sdsInhibited; + + /* [ SDS_FORCED && !SDS_INHIBITED ] */ + + CrIaCopy(SDS_FORCED_ID, &sdsForced); + CrIaCopy(SDS_INHIBITED_ID, &sdsInhibited); + + if (sdsForced && !sdsInhibited) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION1 to N2. */ +FwPrBool_t CrIaSdsEvalAlgoExecC2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char sdsForced, sdsInhibited; + + /* [ !SDS_FORCED && SDS_INHIBITED ] */ + + CrIaCopy(SDS_FORCED_ID, &sdsForced); + CrIaCopy(SDS_INHIBITED_ID, &sdsInhibited); + + if (!sdsForced && sdsInhibited) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from N1 to DECISION1. */ +FwPrBool_t CrIaSdsEvalAlgoExecIsNextExec(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* [ Next Execution ] */ + + if (FwPrGetNodeExecCnt(prDesc)) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION2 to N1. */ +FwPrBool_t CrIaSdsEvalAlgoExecC3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char isSaaActive, earthOccultActive; + + /* [ isSaaActive || EARTH_OCCULT_ACTIVE ] */ + + CrIaCopy(ISSAAACTIVE_ID, &isSaaActive); + CrIaCopy(EARTH_OCCULT_ACTIVE_ID, &earthOccultActive); + + if (isSaaActive || earthOccultActive) + { + return 1; + } + else + { + return 0; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecInit.txt b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..9c123f71665ec7a45026fbfb67d8301b69991bc1 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSdsEvalAlgoExecInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSdsEvalAlgoExecCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSdsEvalAlgoExec is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSdsEvalAlgoExec is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSduCreate.c b/CrIa/src/CrIaPrSm/CrIaSduCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..a86395b448ec6a3644b7c6c6a7de9d534748c4bd --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSduCreate.c @@ -0,0 +1,63 @@ +/** + * @file CrIaSduCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" + +/** CrIaSdu function definitions */ +#include "CrIaSduCreate.h" + +/** + * Guard on the transition from CHOICE1 to INACTIVE. + * ! Flag_1 + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwSmBool_t code31924(FwSmDesc_t __attribute__((unused)) smDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t CrIaSduCreate(void* smData) +{ + const FwSmCounterU2_t N_OUT_OF_INACTIVE = 2; /* The number of transitions out of state INACTIVE */ + const FwSmCounterU2_t N_OUT_OF_DOWN_TRANSFER = 2; /* The number of transitions out of state DOWN_TRANSFER */ + const FwSmCounterU2_t N_OUT_OF_UP_TRANSFER = 2; /* The number of transitions out of state UP_TRANSFER */ + const FwSmCounterU2_t CHOICE1 = 1; /* The identifier of choice pseudo-state CHOICE1 in State Machine CrIaSdu */ + const FwSmCounterU2_t N_OUT_OF_CHOICE1 = 2; /* The number of transitions out of the choice-pseudo state CHOICE1 */ + + /** Create state machine smDesc */ + FwSmDesc_t smDesc = FwSmCreate( + 3, /* NSTATES - The number of states */ + 1, /* NCPS - The number of choice pseudo-states */ + 9, /* NTRANS - The number of transitions */ + 6, /* NACTIONS - The number of state and transition actions */ + 3 /* NGUARDS - The number of transition guards */ + ); + + /** Configure the state machine smDesc */ + FwSmSetData(smDesc, smData); + FwSmAddState(smDesc, CrIaSdu_INACTIVE, N_OUT_OF_INACTIVE, NULL, NULL, NULL, NULL); + FwSmAddState(smDesc, CrIaSdu_DOWN_TRANSFER, N_OUT_OF_DOWN_TRANSFER, &CrIaSduDownTransferEntry, NULL, &CrIaSduDownTransferDo, NULL); + FwSmAddState(smDesc, CrIaSdu_UP_TRANSFER, N_OUT_OF_UP_TRANSFER, NULL, NULL, NULL, NULL); + FwSmAddChoicePseudoState(smDesc, CHOICE1, N_OUT_OF_CHOICE1); + FwSmAddTransStaToSta(smDesc, StartUpTransfer, CrIaSdu_INACTIVE, CrIaSdu_UP_TRANSFER, NULL, NULL); + FwSmAddTransStaToCps(smDesc, StartDownTransfer, CrIaSdu_INACTIVE, CHOICE1, NULL, NULL); + FwSmAddTransStaToSta(smDesc, Abort, CrIaSdu_DOWN_TRANSFER, CrIaSdu_INACTIVE, &CrIaSduLoad13s4Rep, NULL); + FwSmAddTransStaToSta(smDesc, Execute, CrIaSdu_DOWN_TRANSFER, CrIaSdu_INACTIVE, NULL, &CrIaSduIsTransferFinished); + FwSmAddTransStaToSta(smDesc, Abort, CrIaSdu_UP_TRANSFER, CrIaSdu_INACTIVE, &CrIaSduLoad13s16Rep, NULL); + FwSmAddTransStaToSta(smDesc, Execute, CrIaSdu_UP_TRANSFER, CrIaSdu_INACTIVE, NULL, &CrIaSduIsTransferFinished); + FwSmAddTransIpsToSta(smDesc, CrIaSdu_INACTIVE, &CrIaSduResetSdsCounter); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaSdu_DOWN_TRANSFER, NULL, &CrIaSduIsFlag1); + FwSmAddTransCpsToSta(smDesc, CHOICE1, CrIaSdu_INACTIVE, &CrIaSduIncrSdsCounter, &code31924); + + return smDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSduCreate.h b/CrIa/src/CrIaPrSm/CrIaSduCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..8b49a6464e5b9c5e6724e69688b12046a36ef239 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSduCreate.h @@ -0,0 +1,135 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSdu state machine. + * The state machine is configured with a set of function pointers representing the non-default + * actions and guards of the state machine. Some of these functions may also be declared in + * this header file in accordance with the configuration of the state machine in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The state machine created by this file is shown in the figure below. + * @image html CrIaSdu.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSduCreate_H_ +#define CrIaSduCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" + +/** State identifiers */ +#define CrIaSdu_DOWN_TRANSFER (1) /* The identifier of state DOWN_TRANSFER in State Machine CrIaSdu */ +#define CrIaSdu_INACTIVE (2) /* The identifier of state INACTIVE in State Machine CrIaSdu */ +#define CrIaSdu_UP_TRANSFER (3) /* The identifier of state UP_TRANSFER in State Machine CrIaSdu */ + +/** The identifiers of transition commands (triggers) */ +#define Execute (0) +#define Abort (18) +#define StartDownTransfer (19) +#define StartUpTransfer (20) + +/** + * Create a new state machine descriptor. + * This interface creates the state machine descriptor dynamically. + * @param smData the pointer to the state machine data. + * A value of NULL is legal (note that the default value of the pointer + * to the state machine data when the state machine is created is NULL). + * @return the pointer to the state machine descriptor + */ +FwSmDesc_t CrIaSduCreate(void* smData); + +/** + * Entry Action for the state DOWN_TRANSFER. + * <pre> + * sduxBlockCnt = 0; + * if (down transfer is for SDU2) { + * use as SDU2 the GIB pointed at by gibOut; + * sdu2DownTransferSize = size of most recently updated GIB; + * sdu2RemSize = sdu2DownTransferSize; } + * if (down-transfer is for SDU3) { + * use as SDU3 the HK Storage; + * sdu3DownTransferSize = size of HK Storage; + * sdu3RemSize = sdu3DownTransferSize; } + * if (down-transfer is for SDU4) && (sdu4DownTransferSize==0xFFFFFFF) + * sdu4DownTransferSize = size of valid data of FBF in SDU4; } + * if (down-transfer is for SDU4) && (sdu4DownTransferSize!=0xFFFFFFF) + * sdu4RemSize = sdu4DownTransferSize; } + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSduDownTransferEntry(FwSmDesc_t smDesc); + +/** + * Do Action for the state DOWN_TRANSFER. + * <pre> + * dtSize = 0; + * Retrieve dtCapacity from IBSW; + * if (Flag_2) dtSize = dtCapacity; + * If (dtSize > 0) sduxBlockCnt++ + * sduxRemSize = sduxRemSize - dtSize; + * if ((dtSize>0) && (sduxBlockCnt == 1)) Load TM(13,1) + * if ((dtSize>0) && (sduxBlockCnt > 1) && (sduxRemSize>0)) { + * Load TM(13,2) } + * if ((dtSize>0) && (sduxBlockCnt > 1) && (sduxRemSize<=0)) { + * Load TM(13,3) } + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSduDownTransferDo(FwSmDesc_t smDesc); + +/** + * Action on the transition from DOWN_TRANSFER to INACTIVE. + * <pre> + * + * Load (13,4) Report + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSduLoad13s4Rep(FwSmDesc_t smDesc); + +/** + * Action on the transition from UP_TRANSFER to INACTIVE. + * <pre> + * + * Load (13,16) Report + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSduLoad13s16Rep(FwSmDesc_t smDesc); + +/** + * Guard on the transition from UP_TRANSFER to INACTIVE. + * Transfer is finished + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSduIsTransferFinished(FwSmDesc_t smDesc); + +/** + * Action on the transition from Initial State to INACTIVE. + * sdsCounter = 0 + * @param smDesc the state machine descriptor + */ +void CrIaSduResetSdsCounter(FwSmDesc_t smDesc); + +/** + * Guard on the transition from CHOICE1 to DOWN_TRASFER. + * Flag_1 + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSduIsFlag1(FwSmDesc_t smDesc); + +/** + * Action on the transition from CHOICE1 to INACTIVE. + * sdsCounter++ + * @param smDesc the state machine descriptor + */ +void CrIaSduIncrSdsCounter(FwSmDesc_t smDesc); + +#endif /* CrIaSduCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaSduFunc.c b/CrIa/src/CrIaPrSm/CrIaSduFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..e59affe18a51a5dae56dac0dd36ee63959ff9197 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSduFunc.c @@ -0,0 +1,428 @@ +/** + * @file CrIaSduFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" +#include "FwProfile/FwSmCore.h" +#include "FwProfile/FwSmPrivate.h" /* for sdu comparisons */ + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +/** CrIaSdu function definitions */ +#include "CrIaSduCreate.h" + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamSetter.h> + +#include <CrIaIasw.h> +#include <OutStream/CrFwOutStream.h> /* for CrFwOutStreamGetNOfPendingPckts */ + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* for CrIbMilBusGetLinkCapacity */ +#if (__sparc__) +#include "ibsw_interface.h" +#endif + +#include <Sdp/SdpAlgorithmsImplementation.h> /* for GetNBits32 */ +#include <Sdp/SdpCompressionEntityStructure.h> /* for STREAMPOS_INTEGRITY */ + +#include "IfswDebug.h" + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Entry Action for the state DOWN_TRANSFER. */ +void CrIaSduDownTransferEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sduxBlockCnt, GibOut; + unsigned int sduxRemSize, sdu2DownTransferSize, sdu4DownTransferSize; + + DEBUGP(" We are now in the DownTransferEntry\n"); + DEBUGP(" SO, SMDESC pointer is %08x!\n", (unsigned int)smDesc); + DEBUGP(" SO, SDU2 pointer is %08x!\n", (unsigned int)smDescSdu2); + DEBUGP(" SO, SDU4 pointer is %08x!\n", (unsigned int)smDescSdu4); + DEBUGP(" SO, SMDESC Data is %08x!\n", (unsigned int)(smDesc->smData)); + + sduxBlockCnt = 0; + + if (smDesc == smDescSdu2) + { + DEBUGP(" YES, SDU2 identified %08x!\n", (unsigned int)(smDescSdu2)); + CrIaPaste(SDU2BLOCKCNT_ID, &sduxBlockCnt); + + /* Mantis 1421 / 1626 */ + CrIaCopy(SDU2DOWNTRANSFERSIZE_ID, &sdu2DownTransferSize); + + if (sdu2DownTransferSize == DTSIZE_FROM_HEADER) + { + /* overwrite transfer size from header of data in sdu 2 */ + CrIaCopy(GIBTOTRANSFER_ID, &GibOut); + GetNBits32 (&sdu2DownTransferSize, BITOFFSET_SIZE, 32, (unsigned int *)GET_ADDR_FROM_RES_OFFSET(GibOut)); + } + + /* saturate the downtransfer size at the maximum GIB size */ + if (sdu2DownTransferSize > SRAM1_RES_SIZE) + { + sdu2DownTransferSize = SRAM1_RES_SIZE; + } + + DEBUGP("HERE, the down transfer size is: %d\n", sdu2DownTransferSize); + sduxRemSize = sdu2DownTransferSize; + + /* since SDU2DOWNTRANSFERSIZE can be modified by a compression during the ongoing transfer, + we need to freeze the size here at the beginning */ + CrIaPaste(S2TOTRANSFERSIZE_ID, &sdu2DownTransferSize); + + CrIaPaste(SDU2REMSIZE_ID, &sduxRemSize); + +#ifdef PC_TARGET + /* on the PC, the endianess of the CE in the GIB is wrong, we have to swap it before down transfer */ + { + unsigned int j; + unsigned int *inbuffer; + unsigned char *outbuffer; + unsigned char mybyte1, mybyte2, mybyte3, mybyte4; + + CrIaCopy(GIBTOTRANSFER_ID, &GibOut); + inbuffer = (unsigned int *)GET_ADDR_FROM_RES_OFFSET(GibOut); + outbuffer = (unsigned char *)GET_ADDR_FROM_RES_OFFSET(GibOut); + + for (j=0; j<sdu2DownTransferSize; ) + { + GETBYTE (mybyte1, j*8, inbuffer); + GETBYTE (mybyte2, (j+1)*8, inbuffer); + GETBYTE (mybyte3, (j+2)*8, inbuffer); + GETBYTE (mybyte4, (j+3)*8, inbuffer); + + outbuffer[j] = mybyte1; + outbuffer[j+1] = mybyte2; + outbuffer[j+2] = mybyte3; + outbuffer[j+3] = mybyte4; + + j+=4; + } + } +#endif + + } + +#if (__sparc__) + else /* (smDesc == smDescSdu4) */ + { + DEBUGP(" YES, SDU4 identified! %08x!\n", (unsigned int)(smDescSdu4)); + CrIaPaste(SDU4BLOCKCNT_ID, &sduxBlockCnt); + + /* Mantis 1421 / 1626 */ + CrIaCopy(SDU4DOWNTRANSFERSIZE_ID, &sdu4DownTransferSize); + + if (sdu4DownTransferSize == DTSIZE_FROM_HEADER) + { + /* overwrite transfer size from header of data in sdu 4 */ + GetNBits32 (&sdu4DownTransferSize, BITOFFSET_SIZE, 32, (unsigned int *)SRAM1_FLASH_ADDR); + } + + /* saturate the downtransfer size at the SDU4 size */ + if (sdu4DownTransferSize > SRAM1_FLASH_SIZE) + { + sdu4DownTransferSize = SRAM1_FLASH_SIZE; + } + + sduxRemSize = sdu4DownTransferSize; + + /* freeze the size */ + CrIaPaste(S4TOTRANSFERSIZE_ID, &sdu4DownTransferSize); + + CrIaPaste(SDU4REMSIZE_ID, &sduxRemSize); + } +#else + (void) sdu4DownTransferSize; +#endif + + DEBUGP("We have completed the DownTransferEntry\n"); + + return; +} + + +/** Do Action for the state DOWN_TRANSFER. */ +void CrIaSduDownTransferDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t rep; + CrFwGroup_t group = 3; /* PCAT = 4 */ + + unsigned char SduId = 0; + + unsigned short sduxBlockCnt = 0; + unsigned int dtSize; + int dtCapacity; + unsigned int sduxRemSize; + + DEBUGP("We are now in the DownTransferDo\n"); + + dtSize = 0; + + /* Retrieve dtCapacity from IBSW */ +#if (__sparc__) + dtCapacity = CrIbMilBusGetLinkCapacity() - S13_OVERHEAD; +#else + dtCapacity = 1024 - S13_OVERHEAD; /* always report 1 free slot for PC */ +#endif + + /* Flag_2 is true if there are no pending reports for the ground and if the remaining capacity on the 1553 (as given + by dtCapacity) is greater than S13_MIN_BLOCK_SIZE. Only proceed for slots where more than S13_MIN_BLOCK_SIZE bytes + are available */ + if (dtCapacity > S13_MIN_BLOCK_SIZE) + if (CrFwOutStreamGetNOfPendingPckts(outStreamGrd) == 0) /* prevent S13 packets from going in the outStreamGrd */ + dtSize = dtCapacity; + + if (dtSize == 0) + return; + + /* Identify SDU2 or 4 */ + if (smDesc == smDescSdu2) + { + SduId = 2; + + CrIaCopy(SDU2BLOCKCNT_ID, &sduxBlockCnt); + sduxBlockCnt++; + CrIaPaste(SDU2BLOCKCNT_ID, &sduxBlockCnt); + + CrIaCopy(SDU2REMSIZE_ID, &sduxRemSize); + if (sduxRemSize >= dtSize) + sduxRemSize = sduxRemSize - dtSize; + else + { + dtSize = sduxRemSize; + sduxRemSize = 0; + } + CrIaPaste(SDU2REMSIZE_ID, &sduxRemSize); + } + else /* (smDesc == smDescSdu4) */ + { + SduId = 4; + + CrIaCopy(SDU4BLOCKCNT_ID, &sduxBlockCnt); + sduxBlockCnt++; + CrIaPaste(SDU4BLOCKCNT_ID, &sduxBlockCnt); + + CrIaCopy(SDU4REMSIZE_ID, &sduxRemSize); + if (sduxRemSize >= dtSize) + sduxRemSize = sduxRemSize - dtSize; + else + { + dtSize = sduxRemSize; + sduxRemSize = 0; + } + CrIaPaste(SDU4REMSIZE_ID, &sduxRemSize); + } + + /* Load (13,1), (13,2) and (13,3) Reports */ + rep = NULL; + + if (sduxBlockCnt == 1) /* FIRST packet */ + { + DEBUGP("FIRST\n"); + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV13, CRIA_SERV13_FST_DWLK, 0, dtSize + S13_OVERHEAD); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + /* Set the sduId in the packet, in order that the reports can get the info about the kind of SDU */ + CrIaServ13FstDwlkParamSetSduId(rep, SduId); + } + + if (sduxBlockCnt > 1) + { + if (sduxRemSize > 0) /* INTERMEDIATE packet */ + { + DEBUGP("INTERMEDIATE\n"); + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV13, CRIA_SERV13_INTM_DWLK, 0, dtSize + S13_OVERHEAD); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + /* Set the sduId in the packet, in order that the reports can get the info about the kind of SDU */ + CrIaServ13IntmDwlkParamSetSduId(rep, SduId); + } + else /* sduxRemSize == 0 -> LAST packet */ + { + DEBUGP("LAST\n"); + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV13, CRIA_SERV13_LAST_DWLK, 0, dtSize + S13_OVERHEAD); /* uses the changed dtSize = sduxRemSize */ + if (rep == NULL) + { + DEBUGP("ERROR: S(13,3) cannot make an outgoing packet\n"); + /* handled by Resource FdCheck */ + return; + } + /* Set the sduId in the packet, in order that the reports can get the info about the kind of SDU */ + CrIaServ13LastDwlkParamSetSduId(rep, SduId); + } + } + + /* set APID and destination */ + CrFwOutCmpSetGroup(rep, group); + + CrFwOutCmpSetDest(rep, CR_FW_CLIENT_GRD); + + CrFwOutLoaderLoad(rep); + + DEBUGP("We have completed the DownTransferDo and created a packet with data size %d rem size %d block cnt %d\n", dtSize, sduxRemSize, sduxBlockCnt); + + return; +} + +/** Guard on the transition from CHOICE1 to DOWN_TRANSFER. */ +FwSmBool_t CrIaSduIsFlag1(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short GibOut; + unsigned int *cestream; + unsigned int integrity; + + if (smDesc == smDescSdu2) + { + /* get SDS flag from CE.Integrity */ + CrIaCopy(GIBOUT_ID, &GibOut); + cestream = (unsigned int *) GET_ADDR_FROM_RES_OFFSET(GibOut); + GETNBITS (integrity, STREAMPOS_INTEGRITY, 2, cestream); + + if (integrity == DATA_SUSPEND) + { + return 0; + } + else + { + /* if the Science Data Suspend flag in the header of the image in the GIB is false, return 1 */ + return 1; + } + } + + /* if we come here, smDesc is SDU4 and we want to move on */ + return 1; +} + +/** Action on the transition from DOWN_TRANSFER to INACTIVE. */ +void CrIaSduLoad13s4Rep(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t rep; + unsigned char SduId = 2; /* smDesc == smDescSdu2 */ + + if (smDesc == smDescSdu4) + { + SduId = 4; + } + + /* Abort / Load (13,4) Report */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV13, CRIA_SERV13_DWLK_ABRT, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set the sduId in the packet */ + CrIaServ13DwlkAbrtParamSetSduId(rep, SduId); + + /* set destination */ + CrFwOutCmpSetDest(rep, CR_FW_CLIENT_GRD); + + CrFwOutLoaderLoad(rep); + + DEBUGP("We have aborted the DownTransfer and created a report TM(13,4).\n"); + + return; +} + +/** Action on the transition from UP_TRANSFER to INACTIVE. */ +void CrIaSduLoad13s16Rep(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Abort / Load (13,16) Report */ + + return; +} + +/** Action on the transition from UP_TRANSFER to INACTIVE. */ +void CrIaSduLoadConfigFile(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Update IFSW Configuration with newly uplinked data */ + + return; +} + +/** Guard on the transition from DOWN/UP_TRANSFER to INACTIVE. */ +FwSmBool_t CrIaSduIsTransferFinished(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned int sduxRemSize; + + /* Execute [ Transfer is finished ] */ + /* Up-transfer is finished if command (13,11) was executed in current cycle */ + /* Down-transfer is finished when all data in SDUx have been transferred (sduxRemSize is zero or negative) */ + + /* Mantis 1947: corrected to get rid of unreachable code */ + + /* Identify SDU2 ..4 */ + if (smDesc == smDescSdu2) + { + CrIaCopy(SDU2REMSIZE_ID, &sduxRemSize); + if (sduxRemSize == 0) + { + return 1; + } + } + else /* (smDesc == smDescSdu4) */ + { + CrIaCopy(SDU4REMSIZE_ID, &sduxRemSize); + if (sduxRemSize == 0) + { + return 1; + } + } + + return 0; +} + +/** Action on the transition from Initial State to INACTIVE. */ +void CrIaSduResetSdsCounter(FwSmDesc_t smDesc) +{ + unsigned int sdsCounter; + + CRFW_UNUSED(smDesc); + + sdsCounter = 0; + CrIaPaste(SDSCOUNTER_ID, &sdsCounter); + + return; +} + + +/** Action on the transition from CHOICE1 to INACTIVE. */ +void CrIaSduIncrSdsCounter(FwSmDesc_t smDesc) +{ + unsigned int sdsCounter; + + CRFW_UNUSED(smDesc); + + CrIaCopy(SDSCOUNTER_ID, &sdsCounter); + sdsCounter++; + CrIaPaste(SDSCOUNTER_ID, &sdsCounter); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSduInit.txt b/CrIa/src/CrIaPrSm/CrIaSduInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..ee19d089d39463d7484254f2df97e2c4074eb353 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSduInit.txt @@ -0,0 +1,22 @@ +{ + /** Define the state machine descriptor (SMD) */ + FwSmDesc_t smDesc = CrIaSduCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDesc) != smSuccess) { + printf("The state machine CrIaSdu is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The state machine CrIaSdu is properly configured ... SUCCESS\n"); + } + + /** Start the SM, send a few transition commands to it, and execute it */ + FwSmStart(smDesc); + FwSmMakeTrans(smDesc, Abort); + FwSmMakeTrans(smDesc, StartDownTransfer); + FwSmMakeTrans(smDesc, StartUpTransfer); + FwSmMakeTrans(smDesc, Execute); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPCreate.c b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..aeedc7ddfdcb57204d56ff90aa3b99893dd669c0 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPCreate.c @@ -0,0 +1,72 @@ +/** + * @file CrIaSemAnoEvtRPCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:5 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +#include "CrFramework/CrFwConstants.h" + +/** CrIaSemAnoEvtRP function definitions */ +#include "CrIaSemAnoEvtRPCreate.h" + +/** Action for node N1. */ +void CrIaSemEvtAnoRP1(FwPrDesc_t prDesc) +{ + /* Do Nothing */ + + CRFW_UNUSED(prDesc); + + return; +} + +/** + * Guard on the Control Flow from DECISION1 to N3. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code68320(FwPrDesc_t prDesc) +{ + CRFW_UNUSED(prDesc); + + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSemAnoEvtRPCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaSemAnoEvtRP */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 3; /* The number of control flows out of decision node DECISION1 in procedure CrIaSemAnoEvtRP */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 3, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 7, /* N_FLOWS - The number of control flows */ + 3, /* N_ACTIONS - The number of actions */ + 3 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaSemAnoEvtRP_N1, &CrIaSemEvtAnoRP1); + FwPrAddActionNode(prDesc, CrIaSemAnoEvtRP_N2, &CrIaSemEvtAnoRP2); + FwPrAddActionNode(prDesc, CrIaSemAnoEvtRP_N3, &CrIaSemEvtAnoRP3); + FwPrAddFlowIniToDec(prDesc, DECISION1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSemAnoEvtRP_N1, &CrIaSemAnoEvtRPG1); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSemAnoEvtRP_N2, &CrIaSemAnoEvtRPG2); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSemAnoEvtRP_N3, &code68320); + FwPrAddFlowActToFin(prDesc, CrIaSemAnoEvtRP_N1, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSemAnoEvtRP_N2, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSemAnoEvtRP_N3, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPCreate.h b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..8bfb1297b55124ac156e5bad8b0e5e8a07a1c4fb --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPCreate.h @@ -0,0 +1,86 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSemAnoEvtRP procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaSemAnoEvtRP.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:5 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSemAnoEvtRPCreate_H_ +#define CrIaSemAnoEvtRPCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSemAnoEvtRP_N1 1 /* The identifier of action node N1 in procedure CrIaSemAnoEvtRP */ +#define CrIaSemAnoEvtRP_N2 2 /* The identifier of action node N2 in procedure CrIaSemAnoEvtRP */ +#define CrIaSemAnoEvtRP_N3 3 /* The identifier of action node N3 in procedure CrIaSemAnoEvtRP */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSemAnoEvtRPCreate(void* prData); + +/** + * Action for node N1. + * Do Nothing + * @param smDesc the procedure descriptor + */ +void CrIaSemEvtAnoRP1(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * <pre> + * Send command + * StopSem to IASW SM + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSemEvtAnoRP2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Send command + * StopScience to IASW SM + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSemEvtAnoRP3(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N1. + * semAnoEvtResp_x == NO_ACT + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemAnoEvtRPG1(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N2. + * <pre> + * semAnoEvtResp_x == + * SEM_OFF + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemAnoEvtRPG2(FwPrDesc_t prDesc); + +#endif /* CrIaSemAnoEvtRPCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPFunc.c b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..0455ac7caceb3875b7598c9311b4d540788b3aa3 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPFunc.c @@ -0,0 +1,196 @@ +/** + * @file CrIaSemAnoEvtRPFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:5 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +#include <FwProfile/FwSmConfig.h> + +/** CrIaSemAnoEvtRP function definitions */ +#include "CrIaSemAnoEvtRPCreate.h" + +#include <CrIaIasw.h> +#include <Services/General/CrIaConstants.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> /* for StopSem and StopScience transition of the IASW state machine */ + +extern unsigned short SemAnoEvtId; + + +unsigned short getSemAnoEvtResp(unsigned short evtId) +{ + unsigned short response; + + switch (evtId) + { + case 1: + CrIaCopy(SEMANOEVTRESP_1_ID, &response); + break; + case 2: + CrIaCopy(SEMANOEVTRESP_2_ID, &response); + break; + case 3: + CrIaCopy(SEMANOEVTRESP_3_ID, &response); + break; + case 4: + CrIaCopy(SEMANOEVTRESP_4_ID, &response); + break; + case 5: + CrIaCopy(SEMANOEVTRESP_5_ID, &response); + break; + case 6: + CrIaCopy(SEMANOEVTRESP_6_ID, &response); + break; + case 7: + CrIaCopy(SEMANOEVTRESP_7_ID, &response); + break; + case 8: + CrIaCopy(SEMANOEVTRESP_8_ID, &response); + break; + case 9: + CrIaCopy(SEMANOEVTRESP_9_ID, &response); + break; + case 10: + CrIaCopy(SEMANOEVTRESP_10_ID, &response); + break; + case 11: + CrIaCopy(SEMANOEVTRESP_11_ID, &response); + break; + case 12: + CrIaCopy(SEMANOEVTRESP_12_ID, &response); + break; + case 13: + CrIaCopy(SEMANOEVTRESP_13_ID, &response); + break; + case 14: + CrIaCopy(SEMANOEVTRESP_14_ID, &response); + break; + case 15: + CrIaCopy(SEMANOEVTRESP_15_ID, &response); + break; + case 16: + CrIaCopy(SEMANOEVTRESP_16_ID, &response); + break; + case 17: + CrIaCopy(SEMANOEVTRESP_17_ID, &response); + break; + case 18: + CrIaCopy(SEMANOEVTRESP_18_ID, &response); + break; + case 19: + CrIaCopy(SEMANOEVTRESP_19_ID, &response); + break; + case 20: + CrIaCopy(SEMANOEVTRESP_20_ID, &response); + break; + case 21: + CrIaCopy(SEMANOEVTRESP_21_ID, &response); + break; + case 22: + CrIaCopy(SEMANOEVTRESP_22_ID, &response); + break; + case 23: + CrIaCopy(SEMANOEVTRESP_23_ID, &response); + break; + case 24: + CrIaCopy(SEMANOEVTRESP_24_ID, &response); + break; + case 25: + CrIaCopy(SEMANOEVTRESP_25_ID, &response); + break; + case 26: + CrIaCopy(SEMANOEVTRESP_26_ID, &response); + break; + case 27: + CrIaCopy(SEMANOEVTRESP_27_ID, &response); + break; + case 28: + CrIaCopy(SEMANOEVTRESP_28_ID, &response); + break; + case 29: + CrIaCopy(SEMANOEVTRESP_29_ID, &response); + break; + default: + return 0; + break; + } + + return response; +} + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N2. */ +void CrIaSemEvtAnoRP2(FwPrDesc_t prDesc) +{ + /* Send command StopSem to IASW SM */ + + CRFW_UNUSED(prDesc); + + FwSmMakeTrans(smDescIasw, StopSem); + + return; +} + +/** Action for node N3. */ +void CrIaSemEvtAnoRP3(FwPrDesc_t prDesc) +{ + /* Send command StopScience to IASW SM */ + + CRFW_UNUSED(prDesc); + + FwSmMakeTrans(smDescIasw, StopScience); + + return; +} + +/** Guard on the Control Flow from DECISION1 to N1. */ +FwPrBool_t CrIaSemAnoEvtRPG1(FwPrDesc_t prDesc) +{ + /* semAnoEvtResp_x == NO_ACT */ + + CRFW_UNUSED(prDesc); + + if (getSemAnoEvtResp(SemAnoEvtId) == SEMANOEVT_NO_ACT) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION1 to N2. */ +FwPrBool_t CrIaSemAnoEvtRPG2(FwPrDesc_t prDesc) +{ + /* semAnoEvtResp_x == SEM_OFF */ + + CRFW_UNUSED(prDesc); + + if (getSemAnoEvtResp(SemAnoEvtId) == SEMANOEVT_SEM_OFF) + { + return 1; + } + else + { + return 0; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPInit.txt b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..14fe83199d3d60c385aa3ab165596d22f7617677 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemAnoEvtRPInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSemAnoEvtRPCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSemAnoEvtRP is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSemAnoEvtRP is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemConsCheckCreate.c b/CrIa/src/CrIaPrSm/CrIaSemConsCheckCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..64ebb96e3fd059a06e9df92d11a9ebfbdc151cfd --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemConsCheckCreate.c @@ -0,0 +1,74 @@ +/** + * @file CrIaSemConsCheckCreate.c + * + * @author FW Profile code generator version 5.01 + * @date Created on: Dec 7 2017 0:24:42 + */ + +#include "CrIaSemConsCheckCreate.h" + +/** FW Profile function definitions */ +#include "FwPrSCreate.h" +#include "FwPrConfig.h" + +/** CrIaSemConsCheck function definitions */ +#include <stdlib.h> + +/** + * Guard on the Control Flow from DECISION2 to DECISION3. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code73407(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION3 to N2. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code71767(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSemConsCheckCreate(void* prData) +{ + const FwPrCounterU2_t DECISION2 = 1; /* The identifier of decision node DECISION2 in procedure CrIaSemConsCheck */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaSemConsCheck */ + const FwPrCounterU2_t DECISION3 = 2; /* The identifier of decision node DECISION3 in procedure CrIaSemConsCheck */ + const FwPrCounterU2_t N_OUT_OF_DECISION3 = 2; /* The number of control flows out of decision node DECISION3 in procedure CrIaSemConsCheck */ + + /** Create the procedure */ + FW_PR_INST(prDesc, + 3, /* N_ANODES - The number of action nodes */ + 2, /* N_DNODES - The number of decision nodes */ + 8, /* N_FLOWS - The number of control flows */ + 3, /* N_ACTIONS - The number of actions */ + 4 /* N_GUARDS - The number of guards */ + ); + FwPrInit(&prDesc); + + /** Configure the procedure */ + FwPrSetData(&prDesc, prData); + FwPrAddActionNode(&prDesc, CrIaSemConsCheck_N1, &CrIaSemConsCheckN1); + FwPrAddActionNode(&prDesc, CrIaSemConsCheck_N3, &CrIaSemConsCheckN3); + FwPrAddDecisionNode(&prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddDecisionNode(&prDesc, DECISION3, N_OUT_OF_DECISION3); + FwPrAddActionNode(&prDesc, CrIaSemConsCheck_N2, &CrIaSemConsCheckN2); + FwPrAddFlowIniToAct(&prDesc, CrIaSemConsCheck_N1, NULL); + FwPrAddFlowActToDec(&prDesc, CrIaSemConsCheck_N1, DECISION2, NULL); + FwPrAddFlowActToFin(&prDesc, CrIaSemConsCheck_N3, NULL); + FwPrAddFlowDecToAct(&prDesc, DECISION2, CrIaSemConsCheck_N3, &CrIaSemConsCheckTrState); + FwPrAddFlowDecToDec(&prDesc, DECISION2, DECISION3, &code73407); + FwPrAddFlowDecToAct(&prDesc, DECISION3, CrIaSemConsCheck_N3, &CrIaSemConsCheckSemState); + FwPrAddFlowDecToAct(&prDesc, DECISION3, CrIaSemConsCheck_N2, &code71767); + FwPrAddFlowActToFin(&prDesc, CrIaSemConsCheck_N2, NULL); + + return &prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSemConsCheckCreate.h b/CrIa/src/CrIaPrSm/CrIaSemConsCheckCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..4098eaa7904f1590dc016e008644cab2b0fbeb0e --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemConsCheckCreate.h @@ -0,0 +1,93 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSemConsCheck procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaSemConsCheck.png + * + * @author FW Profile code generator version 5.01 + * @date Created on: Dec 7 2017 0:24:42 + */ + +/** Make sure to include this header file only once */ +#ifndef CRIASEMCONSCHECK_H_ +#define CRIASEMCONSCHECK_H_ + +/** FW Profile function definitions */ +#include "FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSemConsCheck_N1 (1) /* The identifier of action node N1 in procedure CrIaSemConsCheck */ +#define CrIaSemConsCheck_N2 (2) /* The identifier of action node N2 in procedure CrIaSemConsCheck */ +#define CrIaSemConsCheck_N3 (3) /* The identifier of action node N3 in procedure CrIaSemConsCheck */ + +typedef struct { + unsigned char anomaly; +} prDescSemConsFdCheck_t; + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor statically. + * It creates a single static instance of the procedure. + * The function should only be called once. + * If it is called several times, it always reconfigures and returns the same instance. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSemConsCheckCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * semMode = SEM mode as given in the + * latest SEM Default Housekeeping Packet + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSemConsCheckN1(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * Return No Anomaly + * @param smDesc the procedure descriptor + */ +void CrIaSemConsCheckN3(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * Return Anomaly Detected + * @param smDesc the procedure descriptor + */ +void CrIaSemConsCheckN2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N3. + * <pre> + * SEM Operational State Machine + * is in a TR_* State + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemConsCheckTrState(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION3 to N3. + * <pre> + * State of SEM Operational State + * Machine is the same as semState + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemConsCheckSemState(FwPrDesc_t prDesc); + +#endif /* CrIaSemConsCheckCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemConsCheckFunc.c b/CrIa/src/CrIaPrSm/CrIaSemConsCheckFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..8ed94f4615aa0874976d3fa7ecce22193dea9f7b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemConsCheckFunc.c @@ -0,0 +1,197 @@ +/** + * @file CrIaSemConsCheckFunc.c + * + * @author FW Profile code generator version 5.01 + * @date Created on: Dec 7 2017 0:24:42 + */ + +/** CrIaSemConsCheck function definitions */ +#include "CrIaSemConsCheckCreate.h" + +#include <CrFramework/CrFwConstants.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConstants.h> +#include <FwProfile/FwSmDCreate.h> +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwSmCore.h> +#include "FwPrDCreate.h" +#include "FwPrConfig.h" +#include "FwPrCore.h" +#include "FwPrConstants.h" + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <CrIaPrSm/CrIaSemCreate.h> +#include <CrIaPrSm/CrIaSemConsCheckCreate.h> +#include <Services/General/CrSemConstants.h> + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#include <IfswDebug.h> + + +unsigned short hkStatMode; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSemConsCheckN1(FwPrDesc_t prDesc) +{ + CRFW_UNUSED(prDesc); + + /* semMode = SEM mode as given in the latest SEM Default Housekeeping Packet */ + + DEBUGP(" Action for node N1.\n"); + + CrIaCopy(STAT_MODE_ID, &hkStatMode); + + return; +} + +/** Action for node N2. */ +void CrIaSemConsCheckN2(FwPrDesc_t prDesc) +{ + prDescSemConsFdCheck_t* prDataPtr; + + CRFW_UNUSED(prDesc); + + /* Return Anomaly Detected */ + + DEBUGP(" Action for node N2.\n"); + + prDataPtr = (prDescSemConsFdCheck_t*)FwPrGetData(prDesc); + prDataPtr->anomaly = 1; + + return; +} + +/** Action for node N3. */ +void CrIaSemConsCheckN3(FwPrDesc_t prDesc) +{ + prDescSemConsFdCheck_t* prDataPtr; + + CRFW_UNUSED(prDesc); + + /* Return No Anomaly */ + + DEBUGP(" Action for node N3.\n"); + + prDataPtr = (prDescSemConsFdCheck_t*)FwPrGetData(prDesc); + prDataPtr->anomaly = 0; + + return; +} + +/** Guard on the Control Flow from DECISION2 to N3. */ +FwPrBool_t CrIaSemConsCheckTrState(FwPrDesc_t prDesc) +{ + unsigned short sem_oper_state; + + CRFW_UNUSED(prDesc); + + /* SEM Operational State Machine is in a TR_* State */ + + DEBUGP(" Guard on the Control Flow from DECISION2 to N3.\n"); + + /* get current state */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + if ((sem_oper_state == CrIaSem_TR_CCD_FULL) || + (sem_oper_state == CrIaSem_TR_CCD_WINDOW) || + (sem_oper_state == CrIaSem_TR_STABILIZE)) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION3 to N3. */ +FwPrBool_t CrIaSemConsCheckSemState(FwPrDesc_t prDesc) +{ + unsigned short sem_state, sem_oper_state; + + CRFW_UNUSED(prDesc); + + /* State of SEM Operational State Machine is the same as semState */ + + DEBUGP(" Guard on the Control Flow from DECISION3 to N3.\n"); + + /* get current states */ + sem_state = FwSmGetCurState(smDescSem); + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + switch(hkStatMode) + { + case SEM_STATE_SAFE: /* SAFE */ + if (sem_state == CrIaSem_SAFE) + { + return 1; + } + else + { + return 0; + } + case SEM_STATE_STANDBY: /* STANDBY */ + if ((sem_state == CrIaSem_OPER) && (sem_oper_state == CrIaSem_STANDBY)) + { + return 1; + } + else + { + return 0; + } + case SEM_STATE_STABILIZE: /* STABILIZE */ + if ((sem_state == CrIaSem_OPER) && (sem_oper_state == CrIaSem_STABILIZE)) + { + return 1; + } + else + { + return 0; + } + case SEM_STATE_SC_STAR_FAINT: /* SC_STAR_FAINT */ + case SEM_STATE_SC_STAR_BRIGHT: /* SC_STAR_BRIGHT */ + case SEM_STATE_SC_STAR_ULTBRT: /* SC_STAR_ULTRBR */ + if ((sem_state == CrIaSem_OPER) && (sem_oper_state == CrIaSem_CCD_WINDOW)) + { + return 1; + } + else + { + return 0; + } + case SEM_STATE_CCD_FULL: /* CCD_FULL */ + if ((sem_state == CrIaSem_OPER) && (sem_oper_state == CrIaSem_CCD_FULL)) + { + return 1; + } + else + { + return 0; + } + case SEM_STATE_DIAGNOSTIC: /* DIAGNOSTIC */ + if ((sem_state == CrIaSem_OPER) && (sem_oper_state == CrIaSem_DIAGNOSTICS)) + { + return 1; + } + else + { + return 0; + } + } + + /* NOTE: SEM state USER_DEFINED can not be checked */ + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemCreate.c b/CrIa/src/CrIaPrSm/CrIaSemCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..789854efbe5d0f8e992afec578a83a9365617ea3 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemCreate.c @@ -0,0 +1,102 @@ +/** + * @file CrIaSemCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwSmDCreate.h" +#include "FwProfile/FwSmConfig.h" + +/** CrIaSem function definitions */ +#include "CrIaSemCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t CrIaSemCreate(void* smData) +{ + const FwSmCounterU2_t N_OUT_OF_STANDBY = 1; /* The number of transitions out of state STANDBY */ + const FwSmCounterU2_t N_OUT_OF_TR_STABILIZE = 1; /* The number of transitions out of state TR_STABILIZE */ + const FwSmCounterU2_t N_OUT_OF_STABILIZE = 3; /* The number of transitions out of state STABILIZE */ + const FwSmCounterU2_t N_OUT_OF_TR_CCD_WINDOW = 2; /* The number of transitions out of state TR_CCD_WINDOW */ + const FwSmCounterU2_t N_OUT_OF_TR_CCD_FULL = 2; /* The number of transitions out of state TR_CCD_FULL */ + const FwSmCounterU2_t N_OUT_OF_DIAGNOSTICS = 1; /* The number of transitions out of state DIAGNOSTICS */ + const FwSmCounterU2_t N_OUT_OF_CCD_WINDOW = 2; /* The number of transitions out of state CCD_WINDOW */ + const FwSmCounterU2_t N_OUT_OF_CCD_FULL = 2; /* The number of transitions out of state CCD_FULL */ + + /** Create state machine EsmDesc1, which is embedded in OPER */ + FwSmDesc_t EsmDesc1 = FwSmCreate( + 8, /* NSTATES - The number of states */ + 0, /* NCPS - The number of choice pseudo-states */ + 15, /* NTRANS - The number of transitions */ + 15, /* NACTIONS - The number of state and transition actions */ + 4 /* NGUARDS - The number of transition guards */ + ); + + /* unit sm */ + const FwSmCounterU2_t N_OUT_OF_OFF = 2; /* The number of transitions out of state OFF */ + const FwSmCounterU2_t N_OUT_OF_INIT = 2; /* The number of transitions out of state INIT */ + const FwSmCounterU2_t N_OUT_OF_SAFE = 2; /* The number of transitions out of state SAFE */ + const FwSmCounterU2_t N_OUT_OF_SHUTDOWN = 1; /* The number of transitions out of state SHUTDOWN */ + const FwSmCounterU2_t N_OUT_OF_OPER = 4; /* The number of transitions out of state OPER */ + + /** Create state machine smDesc */ + FwSmDesc_t smDesc = FwSmCreate( + 5, /* NSTATES - The number of states */ + 0, /* NCPS - The number of choice pseudo-states */ + 12, /* NTRANS - The number of transitions */ + 10, /* NACTIONS - The number of state and transition actions */ + 3 /* NGUARDS - The number of transition guards */ + ); + + /** Configure the state machine EsmDesc1, which is embedded in OPER */ + FwSmSetData(EsmDesc1, smData); + FwSmAddState(EsmDesc1, CrIaSem_STANDBY, N_OUT_OF_STANDBY, &CrIaSemOperLdTransEvt, NULL, NULL, NULL); + FwSmAddState(EsmDesc1, CrIaSem_TR_STABILIZE, N_OUT_OF_TR_STABILIZE, &CrIaSemOperLdTransEvt, NULL, &CrIaSemOperTrStabilizeDo, NULL); + FwSmAddState(EsmDesc1, CrIaSem_STABILIZE, N_OUT_OF_STABILIZE, &CrIaSemOperStabilizeEntry, NULL, NULL, NULL); + FwSmAddState(EsmDesc1, CrIaSem_TR_CCD_WINDOW, N_OUT_OF_TR_CCD_WINDOW, &CrIaSemOperTrCcdWindowEntry, NULL, NULL, NULL); + FwSmAddState(EsmDesc1, CrIaSem_TR_CCD_FULL, N_OUT_OF_TR_CCD_FULL, &CrIaSemOperTrCcdFullEntry, NULL, NULL, NULL); + FwSmAddState(EsmDesc1, CrIaSem_DIAGNOSTICS, N_OUT_OF_DIAGNOSTICS, &CrIaSemOperLdTransEvt, NULL, NULL, NULL); + FwSmAddState(EsmDesc1, CrIaSem_CCD_WINDOW, N_OUT_OF_CCD_WINDOW, &CrIaSemOperCcdWindowEntry, &CrIaSemOperCcdWindowExit, &CrIaSemOperCcdWindowDo, NULL); + FwSmAddState(EsmDesc1, CrIaSem_CCD_FULL, N_OUT_OF_CCD_FULL, &CrIaSemOperCcdFullEntry, &CrIaSemOperCcdFullExit, &CrIaSemOperCcdFullDo, NULL); + FwSmAddTransIpsToSta(EsmDesc1, CrIaSem_STANDBY, NULL); + FwSmAddTransStaToSta(EsmDesc1, GoToStabilize, CrIaSem_STANDBY, CrIaSem_TR_STABILIZE, &CrIaSemOperCmdTempControlEnable, NULL); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_TR_STABILIZE, CrIaSem_STABILIZE, NULL, &CrIaSemOperIsTempStabilized); + FwSmAddTransStaToSta(EsmDesc1, GoToCcdWindow, CrIaSem_STABILIZE, CrIaSem_TR_CCD_WINDOW, &CrIaSemOperCmdCcdDataEnable, NULL); + FwSmAddTransStaToSta(EsmDesc1, GoToCcdFull, CrIaSem_STABILIZE, CrIaSem_TR_CCD_FULL, &CrIaSemOperCmdCcdDataEnable, NULL); + FwSmAddTransStaToSta(EsmDesc1, GoToDiagnostics, CrIaSem_STABILIZE, CrIaSem_DIAGNOSTICS, &CrIaSemOperCmdDiagEnable, NULL); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_TR_CCD_WINDOW, CrIaSem_STABILIZE, NULL, &CrIaSemOperIsInStabilize); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_TR_CCD_WINDOW, CrIaSem_CCD_WINDOW, NULL, &CrIaSemOperIsInScience); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_TR_CCD_FULL, CrIaSem_STABILIZE, NULL, &CrIaSemOperIsInStabilize); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_TR_CCD_FULL, CrIaSem_CCD_FULL, NULL, &CrIaSemOperIsInCcdFull); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_DIAGNOSTICS, CrIaSem_STABILIZE, NULL, &CrIaSemOperIsInStabilize); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_CCD_WINDOW, CrIaSem_STABILIZE, NULL, &CrIaSemOperIsInStabilize); + FwSmAddTransStaToSta(EsmDesc1, GoToStabilize, CrIaSem_CCD_WINDOW, CrIaSem_TR_CCD_WINDOW, &CrIaSemOperCmdCcdDataDisable, NULL); + FwSmAddTransStaToSta(EsmDesc1, Execute, CrIaSem_CCD_FULL, CrIaSem_STABILIZE, NULL, &CrIaSemOperIsInStabilize); + FwSmAddTransStaToSta(EsmDesc1, GoToStabilize, CrIaSem_CCD_FULL, CrIaSem_TR_CCD_FULL, &CrIaSemOperCmdCcdDataDisable, NULL); + + + /** Configure the state machine smDesc */ + FwSmSetData(smDesc, smData); + FwSmAddState(smDesc, CrIaSem_OFF, N_OUT_OF_OFF, &CrIaSemLdTransEvt, NULL, NULL, NULL); + FwSmAddState(smDesc, CrIaSem_INIT, N_OUT_OF_INIT, &CrIaSemInitEntry, &CrIaSemInitExit, &CrIaSemInitDo, NULL); + FwSmAddState(smDesc, CrIaSem_SAFE, N_OUT_OF_SAFE, &CrIaSemLdTransEvt, NULL, NULL, NULL); + FwSmAddState(smDesc, CrIaSem_SHUTDOWN, N_OUT_OF_SHUTDOWN, &CrIaSemShutdownEntry, NULL, &CrIaSemShutdownDo, NULL); + FwSmAddState(smDesc, CrIaSem_OPER, N_OUT_OF_OPER, &CrIaSemLdTransEvt, &CrIaSemOperExit, NULL, EsmDesc1); + FwSmAddTransIpsToSta(smDesc, CrIaSem_OFF, NULL); + FwSmAddTransStaToSta(smDesc, SwitchOn, CrIaSem_OFF, CrIaSem_INIT, &CrIaSemStartSemInitPr, NULL); + FwSmAddTransStaToSta(smDesc, SwitchOff, CrIaSem_OFF, CrIaSem_SHUTDOWN, NULL, NULL); + FwSmAddTransStaToSta(smDesc, SwitchOff, CrIaSem_INIT, CrIaSem_SHUTDOWN, NULL, NULL); + FwSmAddTransStaToSta(smDesc, Execute, CrIaSem_INIT, CrIaSem_OPER, NULL, &CrIaSemIsSemInStandby); + FwSmAddTransStaToSta(smDesc, SwitchOff, CrIaSem_SAFE, CrIaSem_SHUTDOWN, NULL, NULL); + FwSmAddTransStaToSta(smDesc, GoToStandby, CrIaSem_SAFE, CrIaSem_INIT, &CrIaSemGoToStandby, NULL); + FwSmAddTransStaToSta(smDesc, Execute, CrIaSem_SHUTDOWN, CrIaSem_OFF, NULL, &CrIaSemIsShutdownTerm); + FwSmAddTransStaToSta(smDesc, SwitchOff, CrIaSem_OPER, CrIaSem_SHUTDOWN, NULL, NULL); + FwSmAddTransStaToSta(smDesc, Execute, CrIaSem_OPER, CrIaSem_SAFE, NULL, &CrIaSemIsSemInSafe); + FwSmAddTransStaToSta(smDesc, GoToSafe, CrIaSem_OPER, CrIaSem_SAFE, &CrIaSemGoToSafe, NULL); + FwSmAddTransStaToSta(smDesc, GoToStandby, CrIaSem_OPER, CrIaSem_INIT, &CrIaSemGoToStandby, NULL); + + return smDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSemCreate.h b/CrIa/src/CrIaPrSm/CrIaSemCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..4531e9f4fb04017a4491846fa969420243df62fe --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemCreate.h @@ -0,0 +1,381 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSem state machine. + * The state machine is configured with a set of function pointers representing the non-default + * actions and guards of the state machine. Some of these functions may also be declared in + * this header file in accordance with the configuration of the state machine in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The state machine created by this file is shown in the figure below. + * + * <b>Note for state OPER</b> + * State OPER contains an embedded state + * machine (the SEM Operation State Machine). + * + * @image html CrIaSem.png + * + * @author FW Profile code generator version 5.01 + * @date Created on: Aug 13 2018 18:55:30 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSemCreate_H_ +#define CrIaSemCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwSmConstants.h" + +/** State identifiers */ +#define CrIaSem_STOPPED (0) +#define CrIaSem_CCD_FULL (1) /* The identifier of state CCD_FULL in State Machine CrIaSem */ +#define CrIaSem_CCD_WINDOW (2) /* The identifier of state CCD_WINDOW in State Machine CrIaSem */ +#define CrIaSem_DIAGNOSTICS (3) /* The identifier of state DIAGNOSTICS in State Machine CrIaSem */ +#define CrIaSem_STABILIZE (4) /* The identifier of state STABILIZE in State Machine CrIaSem */ +#define CrIaSem_STANDBY (5) /* The identifier of state STANDBY in State Machine CrIaSem */ +#define CrIaSem_TR_CCD_FULL (6) /* The identifier of state TR_CCD_FULL in State Machine CrIaSem */ +#define CrIaSem_TR_CCD_WINDOW (7) /* The identifier of state TR_CCD_WINDOW in State Machine CrIaSem */ +#define CrIaSem_TR_STABILIZE (8) /* The identifier of state TR_STABILIZE in State Machine CrIaSem */ +#define CrIaSem_INIT (1) /* The identifier of state INIT in State Machine CrIaSem */ +#define CrIaSem_OFF (2) /* The identifier of state OFF in State Machine CrIaSem */ +#define CrIaSem_OPER (3) /* The identifier of state OPER in State Machine CrIaSem */ +#define CrIaSem_SAFE (4) /* The identifier of state SAFE in State Machine CrIaSem */ +#define CrIaSem_SHUTDOWN (5) /* The identifier of state SHUTDOWN in State Machine CrIaSem */ + +/** The identifiers of transition commands (triggers) */ +#define Execute (0) +#define SwitchOn (6) +#define SwitchOff (7) +#define GoToSafe (8) +#define GoToStandby (9) +#define GoToStabilize (10) +#define GoToCcdWindow (11) +#define GoToCcdFull (12) +#define GoToDiagnostics (13) + +/** + * Create a new state machine descriptor. + * This interface creates the state machine descriptor dynamically. + * @param smData the pointer to the state machine data. + * A value of NULL is legal (note that the default value of the pointer + * to the state machine data when the state machine is created is NULL). + * @return the pointer to the state machine descriptor + */ +FwSmDesc_t CrIaSemCreate(void* smData); + +/** + * Entry Action for the state STANDBY. + * Load EVT_SEMOP_TR + * @param smDesc the state machine descriptor + */ +void CrIaSemOperLdTransEvt(FwSmDesc_t smDesc); + +/** + * Do Action for the state TR_STABILIZE. + * <pre> + * if (Flag_3) { Send command + * FPM_Power_Enable to SEM; + * Send cmd(220,11) to SEM } + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperTrStabilizeDo(FwSmDesc_t smDesc); + +/** + * Entry Action for the state STABILIZE. + * <pre> + * Load EVT_SEMOP_TR; + * Disable TTM FdCheck; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperStabilizeEntry(FwSmDesc_t smDesc); + +/** + * Entry Action for the state TR_CCD_WINDOW. + * <pre> + * Load EVT_SEMOP_TR + * Enable TTM FdCheck; + * acqImageCnt = 0; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperTrCcdWindowEntry(FwSmDesc_t smDesc); + +/** + * Entry Action for the state TR_CCD_FULL. + * <pre> + * Load EVT_SEMOP_TR + * Enable TTM FdCheck; + * acqImageCnt = 0; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperTrCcdFullEntry(FwSmDesc_t smDesc); + +/** + * Entry Action for the state CCD_WINDOW. + * <pre> + * Load EVT_SEMOP_TR; + * imageCycleCnt = -1; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCcdWindowEntry(FwSmDesc_t smDesc); + +/** + * Exit Action for the state CCD_WINDOW. + * ImageCycleCnt = -1 + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCcdWindowExit(FwSmDesc_t smDesc); + +/** + * Do Action for the state CCD_WINDOW. + * <pre> + * if (Flag_4) imageCycleCnt++; + * if (Flag_1) { + * acqImageCnt++; + * imageCycleCnt = 0 }; + * if (Flag_2) + * notify Sporadic Activity 2; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCcdWindowDo(FwSmDesc_t smDesc); + +/** + * Entry Action for the state CCD_FULL. + * <pre> + * Load EVT_SEMOP_TR; + * imageCycleCnt = -1; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCcdFullEntry(FwSmDesc_t smDesc); + +/** + * Exit Action for the state CCD_FULL. + * ImageCycleCnt = -1 + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCcdFullExit(FwSmDesc_t smDesc); + +/** + * Do Action for the state CCD_FULL. + * <pre> + * if (Flag_4) imageCycleCnt++; + * if (Flag_1) { + * acqImageCnt++; + * imageCycleCnt = 0 }; + * if (imageCycleCnt == ACQ_PH) + * notify Sporadic Activity 1; + * if (Flag_2) + * notify Sporadic Activity 2; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCcdFullDo(FwSmDesc_t smDesc); + +/** + * Action on the transition from STANDBY to TR_STABILIZE. + * CMD_Temp_Control_Enable + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCmdTempControlEnable(FwSmDesc_t smDesc); + +/** + * Guard on the transition from TR_STABILIZE to STABILIZE. + * Flag_4 + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSemOperIsTempStabilized(FwSmDesc_t smDesc); + +/** + * Action on the transition from STABILIZE to TR_CCD_WINDOW. + * CMD_CCD_Data_Enable + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCmdCcdDataEnable(FwSmDesc_t smDesc); + +/** + * Action on the transition from STABILIZE to DIAGNOSTICS. + * CMD_Diagnostics_Enable + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCmdDiagEnable(FwSmDesc_t smDesc); + +/** + * Guard on the transition from TR_CCD_WINDOW to STABILIZE. + * <pre> + * SEM Evt + * Confirms + * STABILIZE + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSemOperIsInStabilize(FwSmDesc_t smDesc); + +/** + * Guard on the transition from TR_CCD_WINDOW to CCD_WINDOW. + * <pre> + * SEM + * Evt Confirms + * SCIENCE + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSemOperIsInScience(FwSmDesc_t smDesc); + +/** + * Guard on the transition from TR_CCD_FULL to CCD_FULL. + * <pre> + * SEM + * Evt Confirms + * CCD_FULL + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSemOperIsInCcdFull(FwSmDesc_t smDesc); + +/** + * Action on the transition from CCD_WINDOW to TR_CCD_WINDOW. + * <pre> + * + * CMD_CCD_Data_Disable + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemOperCmdCcdDataDisable(FwSmDesc_t smDesc); + +/** + * Entry Action for the state OFF. + * <pre> + * if (Entry in OFF is not part of Starting + * the SM) then Load EVT_SEM_TR + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemLdTransEvt(FwSmDesc_t smDesc); + +/** + * Entry Action for the state INIT. + * <pre> + * Load EVT_SEM_TR; + * Reset Source Seq. Counter for SEM + * Enable SEM Comm. Error FdCheck; + * Enable SEM Mode Time-Out FdCheck; + * Enable SEM Safe Mode FdCheck; + * Enable SEM Anomaly Event FdCheck; + * Enable TM Packet SEM_ABS_HK; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemInitEntry(FwSmDesc_t smDesc); + +/** + * Exit Action for the state INIT. + * <pre> + * Stop SEM Initialization Procedure; + * Enable SEM Alive FdCheck; + * Enable SEM Limit FdCheck; + * Load TC(9,129) to SEM; + * Enable SEM Mode Cons. FdCheck + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemInitExit(FwSmDesc_t smDesc); + +/** + * Do Action for the state INIT. + * Execute SEM Initialization Procedure + * @param smDesc the state machine descriptor + */ +void CrIaSemInitDo(FwSmDesc_t smDesc); + +/** + * Entry Action for the state SHUTDOWN. + * <pre> + * Load EVT_SEM_TR; + * Start SEM ShutdownProcedure; + * Disable SEM-related FdChecks; + * Disable TM Packet SEM_ABS_HK; + * </pre> + * @param smDesc the state machine descriptor + */ +void CrIaSemShutdownEntry(FwSmDesc_t smDesc); + +/** + * Do Action for the state SHUTDOWN. + * Execute SEM Shutdown Procedure + * @param smDesc the state machine descriptor + */ +void CrIaSemShutdownDo(FwSmDesc_t smDesc); + +/** + * Exit Action for the state OPER. + * Disable TTM FdCheck + * @param smDesc the state machine descriptor + */ +void CrIaSemOperExit(FwSmDesc_t smDesc); + +/** + * Action on the transition from OFF to INIT. + * Start SEM Initialization Proc. + * @param smDesc the state machine descriptor + */ +void CrIaSemStartSemInitPr(FwSmDesc_t smDesc); + +/** + * Guard on the transition from INIT to OPER. + * <pre> + * SEM Evnt Confirms + * Entry into STANDBY + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSemIsSemInStandby(FwSmDesc_t smDesc); + +/** + * Guard on the transition from SHUTDOWN to OFF. + * <pre> + * SEM Shutdown + * Proc. Terminated + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSemIsShutdownTerm(FwSmDesc_t smDesc); + +/** + * Guard on the transition from OPER to SAFE. + * <pre> + * SEM Evt Confirms + * Entry into SAFE + * </pre> + * @param smDesc the state machine descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwSmBool_t CrIaSemIsSemInSafe(FwSmDesc_t smDesc); + +/** + * Action on the transition from OPER to SAFE. + * CMD_Safe_Enter + * @param smDesc the state machine descriptor + */ +void CrIaSemGoToSafe(FwSmDesc_t smDesc); + +/** + * Action on the transition from OPER to INIT. + * CMD_Standby_Enter + * @param smDesc the state machine descriptor + */ +void CrIaSemGoToStandby(FwSmDesc_t smDesc); + +#endif /* CrIaSemCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrCreate.c b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..74c2340c16ae1ad285bba720e21e78c3b225254d --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrCreate.c @@ -0,0 +1,55 @@ +/** + * @file CrIaSemEvtUpdPrCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSemEvtUpdPr function definitions */ +#include "CrIaSemEvtUpdPrCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to Final Node. + * ! Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code30022(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSemEvtUpdPrCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaSemEvtUpdPr */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaSemEvtUpdPr */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 2, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 5, /* N_FLOWS - The number of control flows */ + 2, /* N_ACTIONS - The number of actions */ + 2 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaSemEvtUpdPr_N1, &CrIaSemEvtUpdPrPush); + FwPrAddActionNode(prDesc, CrIaSemEvtUpdPr_N2, &CrIaSemEvtUpdPrForward); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddFlowIniToAct(prDesc, CrIaSemEvtUpdPr_N1, NULL); + FwPrAddFlowActToDec(prDesc, CrIaSemEvtUpdPr_N1, DECISION1, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSemEvtUpdPr_N2, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSemEvtUpdPr_N2, &CrIaSemEvtUpdPrFlag1); + FwPrAddFlowDecToFin(prDesc, DECISION1, &code30022); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrCreate.h b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..8e45d07790bf28824d35c828a9481eb833316cb1 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrCreate.h @@ -0,0 +1,69 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSemEvtUpdPr procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * + * <b>Note for node N2</b> + * If <code>pckt</code> is the packet holding the report + * to be forwarded, then this function uses function + * <code>CrFwOutStreamSend</code> on <code>OutStreamGrd</code> + * (the OutStream managing packets going to the ground) + * to re-route the packet to the ground. + * + * @image html CrIaSemEvtUpdPr.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSemEvtUpdPrCreate_H_ +#define CrIaSemEvtUpdPrCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSemEvtUpdPr_N1 1 /* The identifier of action node N1 in procedure CrIaSemEvtUpdPr */ +#define CrIaSemEvtUpdPr_N2 2 /* The identifier of action node N2 in procedure CrIaSemEvtUpdPr */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSemEvtUpdPrCreate(void* prData); + +/** + * Action for node N1. + * Push event report onto SEM Event Store + * @param smDesc the procedure descriptor + */ +void CrIaSemEvtUpdPrPush(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * Forward event report to Ground + * @param smDesc the procedure descriptor + */ +void CrIaSemEvtUpdPrForward(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N2. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemEvtUpdPrFlag1(FwPrDesc_t prDesc); + +#endif /* CrIaSemEvtUpdPrCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrFunc.c b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..2bad181ce6b308a5d38acd45d825a49327cab52b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrFunc.c @@ -0,0 +1,41 @@ +/** + * @file CrIaSemEvtUpdPrFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaSemEvtUpdPr function definitions */ +#include "CrIaSemEvtUpdPrCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSemEvtUpdPrPush(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Action for node N2. */ +void CrIaSemEvtUpdPrForward(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Guard on the Control Flow from DECISION1 to N2. */ +FwPrBool_t CrIaSemEvtUpdPrFlag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrInit.txt b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..6d8b1278773db4aaeb45c4812d1a1c57f43736f0 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemEvtUpdPrInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSemEvtUpdPrCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSemEvtUpdPr is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSemEvtUpdPr is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemFunc.c b/CrIa/src/CrIaPrSm/CrIaSemFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..a971858506a7b057b8764b24bea589519c89800b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemFunc.c @@ -0,0 +1,480 @@ +/** + * @file CrIaSemFunc.c + * @ingroup CrIaSm + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Feb 11 2016 22:56:45 + * + * @brief Implementation of the SEM Unit State Machine actions and guards. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConstants.h> +#include <FwProfile/FwSmDCreate.h> +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwSmCore.h> + +#include <FwProfile/FwPrCore.h> /* for FwPrGetCurNode() */ + +/** Cordet FW function definitions */ +#include <CrFramework/InStream/CrFwInStream.h> +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +/** CrIaSem + Oper function definitions */ +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <CrIaIasw.h> + +#include <IfswDebug.h> + +#if(__sparc__) +#include <ibsw_interface.h> +#endif + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemParamSetter.h> +#include <Services/General/CrSemConstants.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaSemEvents.h> + +#define SID_SEM_ABS_HK 6 +#define SEM_UNIT_SM_STATE_OFF 2 + +/* imported global variables */ +extern unsigned short SemTransition; +extern unsigned short SemHkIaswStateExecCnt; +extern FwSmBool_t semShutdownProcTerminated; +extern FwSmBool_t flagDelayedSemHkPacket; +extern CrFwBool_t signalSemStateStandby; + + +/****************************************************************************************/ +/******************************** SEM Unit State Machine ********************************/ +/****************************************************************************************/ + +/** Entry Action for the state OFF / OPER / SAFE. */ +void CrIaSemLdTransEvt(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_state_prev; + unsigned short sem_state; + + unsigned short evt_data[2]; + unsigned int timestamp; + + sem_state = FwSmGetCurState(smDescSem); + + + CrIaCopy(SEMSTATE_ID, &sem_state_prev); + CrIaPaste(SEMSTATE_ID, &sem_state); + + + if (sem_state_prev != CrIaSem_STOPPED) + { + evt_data[0] = sem_state_prev; + evt_data[1] = sem_state; + + DEBUGP("HERE COMES THE EVENT THAT YOU WANTED TO SEE!\n"); + CrIaEvtRep(1, CRIA_SERV5_EVT_SEM_TR, evt_data, 4); + } + + /* Reset variable SemTransition */ + SemTransition = 0; + + if (sem_state == CrIaSem_OFF) + { + /* Reset variable SemPowerOnTimeStamp */ + timestamp = 0; + CrIaPaste(SEMPWRONTIMESTAMP_ID, ×tamp); + } + + return; +} + +/** Entry Action for the state INIT. */ +void CrIaSemInitEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_state_prev; + unsigned short sem_state; + + unsigned short evt_data[2]; + + unsigned char FdCheckComErrIntEn, FdCheckTimeOutIntEn, FdCheckSafeModeIntEn, FdCheckSemAnoEvtIntEn; + + unsigned char sid, rdlSid, rdlSlot, rdlEnabled; + unsigned int rdlCycCnt; + + FwSmDesc_t smDescInStreamSem; + CrFwGroup_t group; + CrFwSeqCnt_t seqCnt; + + sem_state = FwSmGetCurState(smDescSem); + + CrIaCopy(SEMSTATE_ID, &sem_state_prev); + CrIaPaste(SEMSTATE_ID, &sem_state); + + evt_data[0] = sem_state_prev; + evt_data[1] = sem_state; + + CrIaEvtRep(1, CRIA_SERV5_EVT_SEM_TR, evt_data, 4); + + /* Reset Source Seq. Counter for SEM */ + smDescInStreamSem = inStreamSem; + group = 0; /* All reports from the SEM have PCAT = 0x1 and group = PCAT - 1 = 0x0 */ + seqCnt = 0; /* Reset value of the Sequence Counter */ + CrFwInStreamSetSeqCnt(smDescInStreamSem, group, seqCnt); + + /* Enable SEM communication error FdCheck */ + FdCheckComErrIntEn = 1; + CrIaPaste(FDCHECKCOMERRINTEN_ID, &FdCheckComErrIntEn); + + /* Enable SEM mode timeout FdCheck */ + FdCheckTimeOutIntEn = 1; + CrIaPaste(FDCHECKTIMEOUTINTEN_ID, &FdCheckTimeOutIntEn); + + /* Reset variable SemTransition */ + SemTransition = 0; + /* Reset CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET */ + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET = 0; + + /* Enable SEM safe mode FdCheck */ + FdCheckSafeModeIntEn = 1; + CrIaPaste(FDCHECKSAFEMODEINTEN_ID, &FdCheckSafeModeIntEn); + + /* Enable SEM anomaly event FdCheck */ + FdCheckSemAnoEvtIntEn = 1; + CrIaPaste(FDCHECKSEMANOEVTINTEN_ID, &FdCheckSemAnoEvtIntEn); + + /* Enable TM Packet SEM_ABS_HK */ + + sid = SID_SEM_ABS_HK; + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* sid not found in list */ + if (rdlSlot == RDL_SIZE) + { + DEBUGP("SID %d not found!\n", sid); + return; + } + + rdlEnabled = 1; + CrIaPasteArrayItem(RDLENABLEDLIST_ID, &rdlEnabled, rdlSlot); + + rdlCycCnt = 0; + CrIaPasteArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + + return; +} + +/** Exit Action for the state INIT. */ +void CrIaSemInitExit(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char FdCheckAliveIntEn, FdCheckSemLimitIntEn, FdCheckSemConsIntEn; + unsigned char SemTick; + + /* Stop SEM Initialization procedure */ + FwPrStop(prDescSemInit); + + /* Enable SEM alive FdCheck */ + FdCheckAliveIntEn = 1; + CrIaPaste(FDCHECKALIVEINTEN_ID, &FdCheckAliveIntEn); + /* Set flag for FdCheck to increase the margin for number of cycles to handle delayed first SEM HK packet */ + flagDelayedSemHkPacket = 1; + /* Reset IASW cycle counter information when last SEM HK was received */ + SemHkIaswStateExecCnt = FwSmGetExecCnt(smDescIasw); + + /* Enable SEM Limit FdCheck */ + FdCheckSemLimitIntEn = 1; + CrIaPaste(FDCHECKSEMLIMITINTEN_ID, &FdCheckSemLimitIntEn); + + /* Enable SEM Mode Consistency FdCheck */ + FdCheckSemConsIntEn = 1; + CrIaPaste(FDCHECKSEMCONSINTEN_ID, &FdCheckSemConsIntEn); + + /* Load TC(9,129) to SEM, see Mantis 1193 */ + /* NOTE: the time is set in the update action of serv 9 outCmd */ + CrIaLoadSemTimeCmd(); + + /* enable time propagation */ + SemTick = 1; + CrIaPaste(SEMTICK_ID, &SemTick); + + return; +} + +/** Do Action for the state INIT. */ +void CrIaSemInitDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + DEBUGP("SEM SM: Execute SEM Init Procedure\n"); + + /* Execute SEM Init Procedure */ + FwPrExecute(prDescSemInit); + + return; +} + +/** Entry Action for the state SHUTDOWN. */ +void CrIaSemShutdownEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_state_prev; + unsigned short sem_state; + + unsigned short evt_data[2]; + + unsigned char FdCheckComErrIntEn, FdCheckTimeOutIntEn, FdCheckAliveIntEn, FdCheckSafeModeIntEn, FdCheckSemLimitIntEn, FdCheckSemAnoEvtIntEn, FdCheckSemConsIntEn; + + unsigned char sid, rdlSid, rdlSlot, rdlEnabled; + unsigned int rdlCycCnt; + + /* Get the current state of the SEM Unit SM */ + sem_state = FwSmGetCurState(smDescSem); + + /* Get the previous state of the SEM Unit SM */ + CrIaCopy(SEMSTATE_ID, &sem_state_prev); + + /* update current state of SEM Unit SM in data pool */ + CrIaPaste(SEMSTATE_ID, &sem_state); + + /* Load EVT_SEM_TR */ + evt_data[0] = sem_state_prev; + evt_data[1] = sem_state; + + CrIaEvtRep(1,CRIA_SERV5_EVT_SEM_TR, evt_data, 4); + + /* Start SEM Shutdown Procedure */ + FwPrStart(prDescSemShutdown); + + /* Disable SEM-related FdChecks */ + /* SEM_COM_ERR */ + FdCheckComErrIntEn = 0; + CrIaPaste(FDCHECKCOMERRINTEN_ID, &FdCheckComErrIntEn); + /* SEM_MODE_TIMEOUT */ + FdCheckTimeOutIntEn = 0; + CrIaPaste(FDCHECKTIMEOUTINTEN_ID, &FdCheckTimeOutIntEn); + /* SEM_ALIVE */ + FdCheckAliveIntEn = 0; + CrIaPaste(FDCHECKALIVEINTEN_ID, &FdCheckAliveIntEn); + /* SEM_SM */ + FdCheckSafeModeIntEn = 0; + CrIaPaste(FDCHECKSAFEMODEINTEN_ID, &FdCheckSafeModeIntEn); + /* SEM_LIMIT */ + FdCheckSemLimitIntEn = 0; + CrIaPaste(FDCHECKSEMLIMITINTEN_ID, &FdCheckSemLimitIntEn); + /* SEM_ANO_EVT */ + FdCheckSemAnoEvtIntEn = 0; + CrIaPaste(FDCHECKSEMANOEVTINTEN_ID, &FdCheckSemAnoEvtIntEn); + /* SEM_CONS */ + FdCheckSemConsIntEn = 0; + CrIaPaste(FDCHECKSEMCONSINTEN_ID, &FdCheckSemConsIntEn); + + DEBUGP("***** Power off SEM. ENTRY *****\n"); + + /* Disable TM Packet SEM_ABS_HK */ + + sid = SID_SEM_ABS_HK; + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* sid not found in list */ + if (rdlSlot == RDL_SIZE) + { + DEBUGP("SID %d not found!\n", sid); + return; + } + + rdlEnabled = 0; + CrIaPasteArrayItem(RDLENABLEDLIST_ID, &rdlEnabled, rdlSlot); + + rdlCycCnt = 0; + CrIaPasteArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + + return; +} + +/** Do Action for the state SHUTDOWN. */ +void CrIaSemShutdownDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* Execute SEM Shutdown Procedure */ + FwPrExecute(prDescSemShutdown); + + return; +} + +/** Exit Action for the state OPER. */ +void CrIaSemOperExit(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char FdCheckTtmIntEn; + + /* Disable TTM FdCheck */ + FdCheckTtmIntEn = 0; + CrIaPaste(FDCHECKTTMINTEN_ID, &FdCheckTtmIntEn); + + return; +} + +/** Action on the transition from OFF to INIT. */ +void CrIaSemStartSemInitPr(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned int timestamp; + CrFwTimeStamp_t time; + + /* Start SEM Initialization Procedure */ + FwPrStart(prDescSemInit); + + /* save timestamp */ + time = CrIbGetCurrentTime(); + timestamp = ((uint32_t)time.t[0] << 24) | ((uint32_t)time.t[1] << 16) | ((uint32_t)time.t[2] << 8) | (uint32_t)time.t[3]; + CrIaPaste(SEMPWRONTIMESTAMP_ID, ×tamp); + + /* PRDEBUGP("SEM power on: %d\n", SemPowerOnTimeStamp); */ + + /* prevent to signal SEM State Transition to STANDBY at boot up */ + signalSemStateStandby = 0; + + return; +} + + +/** Guard on the transition from INIT to OPER. */ +FwSmBool_t CrIaSemIsSemInStandby(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* if (CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY_SET) not necessary, see mantis 1179 */ + + DEBUGP("Guard on the transition from INIT to OPER.\n"); + + /* SEM Event Confirms Entry into STANDBY */ + if (CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET || (SemTransition == SEM_STATE_STANDBY)) + { + DEBUGP("*** STARTUP: received event! CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET = %d, SemTransition = %d\n", CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET, SemTransition); + + /* clear events here, see Mantis 1178 */ + /* CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY_SET = 0; */ + /* CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET = 0; */ + + /* Reset variable SemTransition */ + SemTransition = 0; + + return 1; + } + + return 0; +} + +/** Guard on the transition from SHUTDOWN to OFF. */ +FwSmBool_t CrIaSemIsShutdownTerm(FwSmDesc_t __attribute__((unused)) smDesc) +{ + DEBUGP("***** Power OFF GUARD. *****\n"); + + return (FwPrGetCurNode(prDescSemShutdown) == PR_STOPPED); +} + +/** Guard on the transition from OPER to SAFE. */ +FwSmBool_t CrIaSemIsSemInSafe(FwSmDesc_t __attribute__((unused)) smDesc) +{ + DEBUGP("Guard on the transition from INIT/OPER to SAFE.\n"); + + /* SEM Event Confirms Entry into SAFE */ + if (SemTransition == SEM_STATE_SAFE) + { + DEBUGP("*** SAFE: received event!\n"); + + return 1; + } + + return 0; +} + +/** Action on the transition from OPER to SAFE. */ +void CrIaSemGoToSafe(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* GoToSafe / CMD_Safe_Enter */ + + DEBUGP("SEM SM from OPER to SAFE\n"); + + /* reset variable SemTransition */ + SemTransition = 0; + + /* send CMD_Safe_Enter */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV221, CRSEM_SERV221_CMD_SAFE_ENTER, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + /* Signal FdCheck SEM Mode Time-Out that CMD_Safe_enter was sent */ + CMD_MODE_TRANSITION_TO_SAFE_Flag = 1; + + return; +} + +/** Action on the transition from OPER to INIT. */ +void CrIaSemGoToStandby(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* GoToStandby / CMD_Standby_Enter */ + + DEBUGP("SEM SM from OPER to INIT\n"); + + /* reset variable SemTransition */ + SemTransition = 0; + + /* send CMD_Standby_Enter */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV221, CRSEM_SERV221_CMD_STANDBY_ENTER, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + /* Signal FdCheck SEM Mode Time-Out that CMD_Standby_enter was sent */ + CMD_MODE_TRANSITION_TO_STANDBY_Flag = 1; + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrCreate.c b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..a505f060c43e45c6c7e05c64132c4224b47880f9 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrCreate.c @@ -0,0 +1,55 @@ +/** + * @file CrIaSemHkUpdPrCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSemHkUpdPr function definitions */ +#include "CrIaSemHkUpdPrCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to Final Node. + * ! Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code7325(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSemHkUpdPrCreate(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaSemHkUpdPr */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaSemHkUpdPr */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 2, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 5, /* N_FLOWS - The number of control flows */ + 2, /* N_ACTIONS - The number of actions */ + 2 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaSemHkUpdPr_N1, &CrIaSemHkUpdPrCopy); + FwPrAddActionNode(prDesc, CrIaSemHkUpdPr_N2, &CrIaSemHkUpdPrForward); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddFlowIniToAct(prDesc, CrIaSemHkUpdPr_N1, NULL); + FwPrAddFlowActToDec(prDesc, CrIaSemHkUpdPr_N1, DECISION1, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSemHkUpdPr_N2, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaSemHkUpdPr_N2, &CrIaSemHkUpdPrFlag1); + FwPrAddFlowDecToFin(prDesc, DECISION1, &code7325); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrCreate.h b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..c0949fef6d01b0173de2566c9f01046406ce553c --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrCreate.h @@ -0,0 +1,75 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSemHkUpdPr procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * + * <b>Note for node N1</b> + * This function knows the mapping of the + * parameters in the two SEM housekeeping + * reports to parameters in the data pool. + * The report's time-stamp is also copied to the + * data pool. + * + * <b>Note for node N2</b> + * If pckt is the packet holding the report to be forwarded, + * this function uses function CrFwOutStreamSend on + * OutStreamGrd (the OutStream managing packets + * going to the ground) to re-route the packet to the ground. + * + * @image html CrIaSemHkUpdPr.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSemHkUpdPrCreate_H_ +#define CrIaSemHkUpdPrCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSemHkUpdPr_N1 1 /* The identifier of action node N1 in procedure CrIaSemHkUpdPr */ +#define CrIaSemHkUpdPr_N2 2 /* The identifier of action node N2 in procedure CrIaSemHkUpdPr */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSemHkUpdPrCreate(void* prData); + +/** + * Action for node N1. + * Copy HK report to Data Pool + * @param smDesc the procedure descriptor + */ +void CrIaSemHkUpdPrCopy(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * Forward HK report to Ground + * @param smDesc the procedure descriptor + */ +void CrIaSemHkUpdPrForward(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N2. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemHkUpdPrFlag1(FwPrDesc_t prDesc); + +#endif /* CrIaSemHkUpdPrCreate_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrFunc.c b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..f2ec109e720bf568baa0f904dcc287915e7e782c --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrFunc.c @@ -0,0 +1,41 @@ +/** + * @file CrIaSemHkUpdPrFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaSemHkUpdPr function definitions */ +#include "CrIaSemHkUpdPrCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSemHkUpdPrCopy(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Action for node N2. */ +void CrIaSemHkUpdPrForward(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return; +} + +/** Guard on the Control Flow from DECISION1 to N2. */ +FwPrBool_t CrIaSemHkUpdPrFlag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrInit.txt b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..f7ecde0a8a82572c425dbde50dd6016f785b0515 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemHkUpdPrInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSemHkUpdPrCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSemHkUpdPr is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSemHkUpdPr is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemInit.txt b/CrIa/src/CrIaPrSm/CrIaSemInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..53a35b7532a9d9dcca29078c16c9933b1a0c3d9b --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemInit.txt @@ -0,0 +1,27 @@ +{ + /** Define the state machine descriptor (SMD) */ + FwSmDesc_t smDesc = CrIaSemCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDesc) != smSuccess) { + printf("The state machine CrIaSem is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The state machine CrIaSem is properly configured ... SUCCESS\n"); + } + + /** Start the SM, send a few transition commands to it, and execute it */ + FwSmStart(smDesc); + FwSmMakeTrans(smDesc, SwitchOn); + FwSmMakeTrans(smDesc, SwitchOff); + FwSmMakeTrans(smDesc, Execute); + FwSmMakeTrans(smDesc, GoToSafe); + FwSmMakeTrans(smDesc, GoToStandby); + FwSmMakeTrans(smDesc, GoToStabilize); + FwSmMakeTrans(smDesc, GoToCcdWindow); + FwSmMakeTrans(smDesc, GoToCcdFull); + FwSmMakeTrans(smDesc, GoToDiagnostics); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemInitCreate.c b/CrIa/src/CrIaPrSm/CrIaSemInitCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..28feefc90aacfd0fb020fab53b16adf220a22627 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemInitCreate.c @@ -0,0 +1,37 @@ +/** + * @file CrIaSemInitCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:4 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSemInit function definitions */ +#include "CrIaSemInitCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSemInitCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 1, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 2, /* N_FLOWS - The number of control flows */ + 1, /* N_ACTIONS - The number of actions */ + 2 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaSemInit_N1, &CrIaSemInitCloseSwitch); + FwPrAddFlowIniToAct(prDesc, CrIaSemInit_N1, &CrIaSemInitWaitT1); + FwPrAddFlowActToFin(prDesc, CrIaSemInit_N1, &CrIaSemInitWaitT2); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSemInitCreate.h b/CrIa/src/CrIaPrSm/CrIaSemInitCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..515a0042b989c4128470944d1b5a5ba2b5ee1556 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemInitCreate.h @@ -0,0 +1,64 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSemInit procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaSemInit.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:4 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSemInitCreate_H_ +#define CrIaSemInitCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSemInit_N1 1 /* The identifier of action node N1 in procedure CrIaSemInit */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSemInitCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * Close External SEM Power Switch + * and FPM Heater Power Switch + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSemInitCloseSwitch(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from Initial Node to N1. + * Wait SEM_INIT_T1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemInitWaitT1(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N1 to Final Node. + * Wait SEM_INIT_T2 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemInitWaitT2(FwPrDesc_t prDesc); + +#endif /* CrIaSemInitCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaSemInitFunc.c b/CrIa/src/CrIaPrSm/CrIaSemInitFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..3a89bb0852539b81641472bdf775169db022c694 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemInitFunc.c @@ -0,0 +1,135 @@ +/** + * @file CrIaSemInitFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:4 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwPrConstants.h> +#include <FwProfile/FwPrDCreate.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> /* for FwPrGetCurNode() */ + +/** CrIaSemInit function definitions */ +#include "CrIaSemInitCreate.h" + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +#include <CrIaIasw.h> + +#if(__sparc__) +#include <ibsw_interface.h> +#endif + +#include <IfswDebug.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrSemConstants.h> + +/* imported global variables */ +extern unsigned short SemTransition; + +unsigned short smDescSemInitExecCntOld = 0; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSemInitCloseSwitch(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Close External SEM Power Switch and FPM Power Switch */ + +#if(__sparc__) + + /* Mantis 1983: reset SPW */ + CrIbResetSEMSpW(); + + /* reset variable SemTransition */ + SemTransition = 0; + + /* NOTE: the power on/off passwords are fetched inside CrIbSemLowLevelOp */ + + CrIbSemLowLevelOp (SWITCH_ON); + CrIbSemLowLevelOp (HEATER_ON); + +#else + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + DEBUGP("***** Power on SEM. *****\n"); + + /* reset variable SemTransition */ + SemTransition = 0; + + /* Send CMD_STANDBY_Enter to SEM: TC(221,2) */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV221, CRSEM_SERV221_CMD_STANDBY_ENTER, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); +#endif + + /* Signal FdCheck SEM Mode Time-Out that Power was switched on */ + CMD_MODE_TRANSITION_TO_POWERON_Flag = 1; + + return; +} + +/** Guard on the Control Flow from Initial Node to N1. */ +FwPrBool_t CrIaSemInitWaitT1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short delay_t1 = 0; + + /* Wait SEM_INIT_T1 */ + + CrIaCopy(SEM_INIT_T1_ID, &delay_t1); + + DEBUGP ("SEM_INIT_T1: Guard on the Control Flow from Initial Node to N1. delay_t1_cnt / delay_t1 = %d / %d\n", FwPrGetNodeExecCnt(prDesc), delay_t1); + + if (FwPrGetNodeExecCnt(prDesc) < delay_t1) + { + return 0; + } + else + { + return 1; + } +} + +/** Guard on the Control Flow from N1 to Final Node. */ +FwPrBool_t CrIaSemInitWaitT2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short delay_t2 = 0; + + /* Wait SEM_INIT_T2 */ + + CrIaCopy(SEM_INIT_T2_ID, &delay_t2); + + DEBUGP ("SEM_INIT_T2: Guard on the Control Flow from N1 to Final Node. delay_t2_cnt / delay_t2 = %d / %d\n", FwPrGetNodeExecCnt(prDesc), delay_t2); + + if (FwPrGetNodeExecCnt(prDesc) < delay_t2) + { + return 0; + } + else + { + return 1; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemInitInit.txt b/CrIa/src/CrIaPrSm/CrIaSemInitInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..f0f1d3b3536510bc8fbdea00dd10e4fafd714a52 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemInitInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSemInitCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSemInit is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSemInit is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemOperFunc.c b/CrIa/src/CrIaPrSm/CrIaSemOperFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..2f212efcbbafdd3dcdec2fbb7801108e9a86fb17 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemOperFunc.c @@ -0,0 +1,684 @@ +/** + * @file CrIaSemOperFunc.c + * @ingroup CrIaSm + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Feb 11 2016 22:56:45 + * + * @brief Implementation of the SEM Unit State Machine actions and guards. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConstants.h> +#include <FwProfile/FwSmDCreate.h> +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwSmCore.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +/** CrIaSem (Oper) function definitions */ +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <CrIaIasw.h> + +#include <IfswDebug.h> +#if(__sparc__) +#include <ibsw_interface.h> +#endif + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemParamSetter.h> +#include <Services/General/CrSemConstants.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaSemEvents.h> + +static unsigned char transitionFromStabFlag; + +/* imported global variables */ +extern unsigned short SemTransition; + +#ifdef PC_TARGET +extern unsigned int *ShmRequestAcquisitionPTR; /* shared memory for fork() */ +extern unsigned int *ShmRequestCompressionPTR; /* shared memory for fork() */ +#endif /* PC_TARGET */ + + +/****************************************************************************************/ +/******************************** SEM Operational State Machine *************************/ +/****************************************************************************************/ + +/** Entry Action for the state STANDBY, TR_STABILIZE and DIAGNOSTICS. */ +void CrIaSemOperLdTransEvt(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_oper_state_prev, sem_oper_state; + unsigned short evt_data[2]; + + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + CrIaCopy(SEMOPERSTATE_ID, &sem_oper_state_prev); + CrIaPaste(SEMOPERSTATE_ID, &sem_oper_state); + + evt_data[0] = sem_oper_state_prev; + evt_data[1] = sem_oper_state; + CrIaEvtRep(1, CRIA_SERV5_EVT_SEMOP_TR, evt_data, 4); +} + +/** Do Action for the state TR_STABILIZE. */ +void CrIaSemOperTrStabilizeDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + DEBUGP("TR_STABILIZE Do Action\n"); + + /* if (Flag_3) Send command FPM_Power_Enable (221,3) and CMD_FUNCT_PARAM (220,11) to SEM */ + /* Flag_3 is true if SEM confirming entry into STABILIZE */ + + if (SemTransition == SEM_STATE_STABILIZE) + { + DEBUGP("SEM to STABILIZE received. Send command FPM_Power_Enable (221,3) to SEM . Send command CMD_FUNCT_PARAM (220,11) to SEM. \n"); + + /* send TC (221,3) FPM Power Enable to SEM */ + + /* Create out component */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV221, CRSEM_SERV221_CMD_FPM_POWER_ENABLE, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + + CrFwOutLoaderLoad(cmd); + + /* send TC(220,11) SEM Functional Parameter to SEM (see Mantis 2098) */ + + /* Create out component */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV220, CRSEM_SERV220_CMD_FUNCT_PARAM, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + + CrFwOutLoaderLoad(cmd); + + /* reset the SemTransition variable, in order to generate TC(221,3) and TC(220,11) only once */ + SemTransition = 0; + + } + else + { + DEBUGP("NO event report from SEM received.\n"); + } + + return; +} + +/** Entry Action for the state STABILIZE. */ +void CrIaSemOperStabilizeEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_oper_state_prev, sem_oper_state; + unsigned short evt_data[2]; + + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + CrIaCopy(SEMOPERSTATE_ID, &sem_oper_state_prev); + CrIaPaste(SEMOPERSTATE_ID, &sem_oper_state); + + evt_data[0] = sem_oper_state_prev; + evt_data[1] = sem_oper_state; + CrIaEvtRep(1, CRIA_SERV5_EVT_SEMOP_TR, evt_data, 4); + + return; +} + +/** Entry Action for the state TR_CCD_WINDOW. */ +void CrIaSemOperTrCcdWindowEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_oper_state_prev, sem_oper_state; + unsigned short evt_data[2]; + unsigned char FdCheckTtmIntEn; + unsigned int AcqImageCnt; + + /* Load EVT_SEMOP_TR */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + CrIaCopy(SEMOPERSTATE_ID, &sem_oper_state_prev); + CrIaPaste(SEMOPERSTATE_ID, &sem_oper_state); + + evt_data[0] = sem_oper_state_prev; + evt_data[1] = sem_oper_state; + CrIaEvtRep(1, CRIA_SERV5_EVT_SEMOP_TR, evt_data, 4); + + /* Enable TTM FdCheck */ + FdCheckTtmIntEn = 1; + CrIaPaste(FDCHECKTTMINTEN_ID, &FdCheckTtmIntEn); + + /* init variable and DP */ + AcqImageCnt = 0; + CrIaPaste(ACQIMAGECNT_ID, &AcqImageCnt); + + S21LastAcqId = 0xffffffff; + + if (transitionFromStabFlag == 1) /* if coming from STABILIZE ... */ + { + /* Signal FdCheck SEM Mode Time-Out that CMD_CCD_Data_Enable was sent (Mantis 2125) */ + CMD_MODE_TRANSITION_TO_CCDWIN_Flag = 1; + + transitionFromStabFlag = 0; + } + + return; +} + +/** Entry Action for the state TR_CCD_FULL. */ +void CrIaSemOperTrCcdFullEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_oper_state_prev, sem_oper_state; + unsigned short evt_data[2]; + unsigned char FdCheckTtmIntEn; + unsigned int AcqImageCnt; + + PRDEBUGP("HELLO Full Entry!\n"); + + /* Load EVT_SEMOP_TR */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + CrIaCopy(SEMOPERSTATE_ID, &sem_oper_state_prev); + CrIaPaste(SEMOPERSTATE_ID, &sem_oper_state); + + evt_data[0] = sem_oper_state_prev; + evt_data[1] = sem_oper_state; + CrIaEvtRep(1, CRIA_SERV5_EVT_SEMOP_TR, evt_data, 4); + + /* Enable TTM FdCheck */ + FdCheckTtmIntEn = 1; + CrIaPaste(FDCHECKTTMINTEN_ID, &FdCheckTtmIntEn); + + /* init variable and DP */ + AcqImageCnt = 0; + CrIaPaste(ACQIMAGECNT_ID, &AcqImageCnt); + + S21LastAcqId = 0xffffffff; + + if (transitionFromStabFlag == 1) /* if coming from STABILIZE ... */ + { + /* ... signal FdCheck SEM Mode Time-Out that CMD_CCD_Data_Enable was sent (Mantis 2125) */ + CMD_MODE_TRANSITION_TO_CCDFULL_Flag = 1; + + transitionFromStabFlag = 0; + } + + return; +} + +/** Entry Action for the state CCD_WINDOW. */ +void CrIaSemOperCcdWindowEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_oper_state_prev, sem_oper_state, uint16; + unsigned short evt_data[2]; + unsigned int ImageCycleCnt; + + PRDEBUGP("HELLO Window Entry!\n"); + + /* Load EVT_SEMOP_TR */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + CrIaCopy(SEMOPERSTATE_ID, &sem_oper_state_prev); + CrIaPaste(SEMOPERSTATE_ID, &sem_oper_state); + + evt_data[0] = sem_oper_state_prev; + evt_data[1] = sem_oper_state; + CrIaEvtRep(1, CRIA_SERV5_EVT_SEMOP_TR, evt_data, 4); + + DEBUGP("CCD WIN Entry Action, resetting counters\n"); + + /* init variable and DP */ + CrIaCopy (PWINSIZEX_ID, &uint16); + CrIaPaste (CE_SEMWINDOWSIZEX_ID, &uint16); + + CrIaCopy (PWINSIZEY_ID, &uint16); + CrIaPaste (CE_SEMWINDOWSIZEY_ID, &uint16); + + CrIaCopy (PWINPOSX_ID, &uint16); + CrIaPaste (CE_SEMWINDOWPOSX_ID, &uint16); + + CrIaCopy (PWINPOSY_ID, &uint16); + CrIaPaste (CE_SEMWINDOWPOSY_ID, &uint16); + + ImageCycleCnt = 0xffffffff; + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + + S21_Flag1 = 0; + +#ifdef PC_TARGET + ShmRequestCompressionPTR[0] = 0; + ShmRequestAcquisitionPTR[0] = 0; +#endif /* PC_TARGET */ + + return; +} + +/** Exit Action for the state CCD_WINDOW. */ +void CrIaSemOperCcdWindowExit(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned int ImageCycleCnt; + + ImageCycleCnt = 0xffffffff; + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + + DEBUGP("CCD WIN Exit Action, reset image cycle cnt\n"); + + return; +} + +/** Do Action for the state CCD_WINDOW. */ +void CrIaSemOperCcdWindowDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned int ImageCycleCnt, AcqImageCnt; + unsigned short StckOrder; + unsigned char lstpckt; + + CrIaCopy(IMAGECYCLECNT_ID, &ImageCycleCnt); + CrIaCopy(ACQIMAGECNT_ID, &AcqImageCnt); + + DEBUGP("CcdWinDo, ICC++=%d, AIC=%d, S21 Flag1 = %d\n", ImageCycleCnt, AcqImageCnt, S21_Flag1); + + /* + We only want to increment the ImageCycleCnt as soon as images are coming in. + This situation is established when S21LastAcqId != initial value. + S21LastAcqId is updated in the CrIaSciDataUpdFunc with the first packet of an incoming image + */ + + if (S21LastAcqId != 0xffffffff) + { + ImageCycleCnt += 1; + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + } + + /* wait for the signal from service 21 for a first packet of a new image */ + if (S21_Flag1 != 0) + { + AcqImageCnt += 1; + ImageCycleCnt = 0; + + CrIaPaste(ACQIMAGECNT_ID, &AcqImageCnt); + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + + /* clear Flag1 */ + S21_Flag1 = 0; + } + + /* COLLECTION = SCIENCE */ + CrIaCopy(STCK_ORDER_ID, &StckOrder); + CrIaCopy(LASTSEMPCKT_ID, &lstpckt); + + if (lstpckt == 1) + { + if (((AcqImageCnt + 1) % StckOrder) == 0) + { + PRDEBUGP("notify SCIENCE (case b)%d %d %d\n", ImageCycleCnt, AcqImageCnt, StckOrder); +#ifdef PC_TARGET + ShmRequestCompressionPTR[0]++; +#else + execute_compression(); +#endif /* PC_TARGET */ + PRDEBUGP("notified\n"); + } + } + + return; +} + +/** Entry Action for the state CCD_FULL. */ +void CrIaSemOperCcdFullEntry(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_oper_state_prev, sem_oper_state, uint16; + unsigned short evt_data[2]; + unsigned int ImageCycleCnt; + + /* Load EVT_SEMOP_TR */ + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + + CrIaCopy(SEMOPERSTATE_ID, &sem_oper_state_prev); + CrIaPaste(SEMOPERSTATE_ID, &sem_oper_state); + + evt_data[0] = sem_oper_state_prev; + evt_data[1] = sem_oper_state; + CrIaEvtRep(1, CRIA_SERV5_EVT_SEMOP_TR, evt_data, 4); + + DEBUGP("CCD FULL Entry Action, resetting counters\n"); + + /* init variable and DP */ + uint16 = FULL_SIZE_X; + CrIaPaste (CE_SEMWINDOWSIZEX_ID, &uint16); + + uint16 = FULL_SIZE_Y; + CrIaPaste (CE_SEMWINDOWSIZEY_ID, &uint16); + + uint16 = 0; + CrIaPaste (CE_SEMWINDOWPOSX_ID, &uint16); + + uint16 = 0; + CrIaPaste (CE_SEMWINDOWPOSY_ID, &uint16); + + ImageCycleCnt = 0xffffffff; + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + + S21_Flag1 = 0; + +#ifdef PC_TARGET + ShmRequestCompressionPTR[0] = 0; + ShmRequestAcquisitionPTR[0] = 0; +#endif /* PC_TARGET */ + + return; +} + +/** Exit Action for the state CCD_FULL. */ +void CrIaSemOperCcdFullExit(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned int ImageCycleCnt; + + ImageCycleCnt = 0xffffffff; + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + + DEBUGP("CCD FULL Exit Action, reset image cycle cnt\n"); + + return; +} + +/** Do Action for the state CCD_FULL. */ +void CrIaSemOperCcdFullDo(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned int ImageCycleCnt, AcqImageCnt; + unsigned short acquisitionPhase; + unsigned short StckOrder; + unsigned char lstpckt; + + CrIaCopy(IMAGECYCLECNT_ID, &ImageCycleCnt); + CrIaCopy(ACQIMAGECNT_ID, &AcqImageCnt); + + /* + We only want to increment the ImageCycleCnt as soon as images are coming in. + This situation is established when S21LastAcqId != initial value. + S21LastAcqId is updated in the CrIaSciDataUpdFunc with the first packet of an incoming image + */ + if (S21LastAcqId != 0xffffffff) + { + ImageCycleCnt += 1; + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + } + + PRDEBUGP("CcdFullDo, ICC++=%d, AIC=%d, S21 Flag1 = %d\n", ImageCycleCnt, AcqImageCnt, S21_Flag1); + + /* wait for the signal from service 21 for a first packet of a new image */ + if (S21_Flag1 != 0) + { + AcqImageCnt += 1; + ImageCycleCnt = 0; + + CrIaPaste(ACQIMAGECNT_ID, &AcqImageCnt); + CrIaPaste(IMAGECYCLECNT_ID, &ImageCycleCnt); + + /* clear Flag1 */ + S21_Flag1 = 0; + } + + /* ACQUISITION */ + CrIaCopy(ACQ_PH_ID, &acquisitionPhase); + + if(ImageCycleCnt == (unsigned int)acquisitionPhase) + { + /* notify acquisition algorithm */ + DEBUGP("notify Full Frame ACQUISITION\n"); + +#ifdef PC_TARGET + ShmRequestAcquisitionPTR[0]++; +#else + execute_acquisition(); +#endif /* PC_TARGET */ + + PRDEBUGP("notified\n"); + } + + /* COLLECTION */ + CrIaCopy(STCK_ORDER_ID, &StckOrder); + CrIaCopy(LASTSEMPCKT_ID, &lstpckt); + + if (lstpckt == 1) + { + if (((AcqImageCnt + 1) % StckOrder) == 0) + { + DEBUGP("notify Full Frame SCIENCE (case b)%d %d\n", ImageCycleCnt, AcqImageCnt); +#ifdef PC_TARGET + ShmRequestCompressionPTR[0]++; +#else + execute_compression(); +#endif /* PC_TARGET */ + DEBUGP("notified\n"); + } + } + + return; +} + + +/** Action on the transition from STANDBY to TR_STABILIZE. */ +void CrIaSemOperCmdTempControlEnable(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short sem_oper_state; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + FwSmDesc_t cmd; + + /* GoToStabilize */ + + sem_oper_state = FwSmGetCurStateEmb(smDescSem); + CrIaPaste(SEMOPERSTATE_ID, &sem_oper_state); + + /* create the CMD_Temp_Control_Enable command for SEM: TC(220,4) */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp (CRSEM_SERV220, CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + /* Signal FdCheck SEM Mode Time-Out that CMD_Temp_Control_Enable was sent */ + CMD_MODE_TRANSITION_TO_STAB_Flag = 1; + CMD_MODE_TRANSITION_TO_TEMP_Flag = 1; + + return; +} + +/** Guard on the transition from TR_STABILIZE to STABILIZE. */ +FwSmBool_t CrIaSemOperIsTempStabilized(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short tsCounterUpperLimit; + + CrIaCopy(SEM_OPER_T1_ID, &tsCounterUpperLimit); /* see Mantis 1625 */ + + /* check if SEM Event Report (5,1,CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY) is received */ + /* CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY = 42008 */ + + if (CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_SET) + { + DEBUGP("(5,1,42008) event report from SEM received.\n"); + CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_SET = 0; + return 1; + } + else + { + DEBUGP("NO event report from SEM received.\n"); + DEBUGP(" faking countdown to thermal stability... %d\n", FwSmGetStateExecCnt(smDesc)); + if (FwSmGetStateExecCnt(smDesc) >= tsCounterUpperLimit) + { + return 1; + } + else + { + return 0; + } + } +} + +/** Action on the transition from STABILIZE to TR_CCD_WINDOW / TR_CCD_FULL . */ +void CrIaSemOperCmdCcdDataEnable(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* GoToCcdWindow / GoToCcdFull */ + + /* reset variable SemTransition */ + SemTransition = 0; + + /* create the CMD_CCD_Data_Enable command for SEM: TC(21,1) */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp (CRSEM_SERV21, CRSEM_SERV21_CMD_CCD_DATA_ENABLE, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + /* signal coming from STABILIZE */ + transitionFromStabFlag = 1; + + return; +} + +/** Action on the transition from STABILIZE to DIAGNOSTICS. */ +void CrIaSemOperCmdDiagEnable(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* GoToDiagnostics */ + + /* reset variable SemTransition */ + SemTransition = 0; + + /* create the CMD_Diagnostics_Enable command for SEM: TC(222,3) */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp (CRSEM_SERV222, CRSEM_SERV222_CMD_DIAG_ENABLE, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + /* Signal FdCheck SEM Mode Time-Out that CMD_Diagnostics_Enable was sent */ + CMD_MODE_TRANSITION_TO_DIAG_Flag = 1; + + return; +} + +/** Guard on the transition from TR_CCD_WINDOW / TR_CCD_FULL / DIAGNOSTICS to STABILIZE. */ +FwSmBool_t CrIaSemOperIsInStabilize(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* SEM Evt Confirms STABILIZE */ + if (SemTransition == SEM_STATE_STABILIZE) + return 1; + + return 0; +} + +/** Guard on the transition from TR_CCD_WINDOW to CCD_WINDOW. */ +FwSmBool_t CrIaSemOperIsInScience(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* SEM Evt Confirms SCIENCE */ + /* SEM has no science state, but 4 states that can be seen as such */ + + switch (SemTransition) + { + case SEM_STATE_SC_STAR_FAINT : + case SEM_STATE_SC_STAR_BRIGHT : + case SEM_STATE_SC_STAR_ULTBRT : + + return 1; + + default: + break; + } + + return 0; +} + +/** Guard on the transition from TR_CCD_FULL to CCD_FULL. */ +FwSmBool_t CrIaSemOperIsInCcdFull(FwSmDesc_t __attribute__((unused)) smDesc) +{ + /* SEM Evt Confirms CCD_FULL */ + if (SemTransition == SEM_STATE_CCD_FULL) + return 1; + + return 0; +} + +/** Action on the transition from CCD_WINDOW / CCD_FULL to TR_CCD_WINDOW / TR_CCD_FULL . */ +void CrIaSemOperCmdCcdDataDisable(FwSmDesc_t __attribute__((unused)) smDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + /* GoToStabilize */ + + /* reset variable SemTransition */ + SemTransition = 0; + + /* create the CMD_CCD_Data_Disable command for SEM: TC(21,2) */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp (CRSEM_SERV21, CRSEM_SERV21_CMD_CCD_DATA_DISABLE, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemOperInit.txt b/CrIa/src/CrIaPrSm/CrIaSemOperInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..796589390b54ce17fee72d3ae5f3e6eb701de8b4 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemOperInit.txt @@ -0,0 +1,23 @@ +{ + /** Define the state machine descriptor (SMD) */ + FwSmDesc_t smDesc = CrIaSemOperCreate(NULL); + + /** Check that the SM is properly configured */ + if (FwSmCheckRec(smDesc) != smSuccess) { + printf("The state machine CrIaSemOper is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The state machine CrIaSemOper is properly configured ... SUCCESS\n"); + } + + /** Start the SM, send a few transition commands to it, and execute it */ + FwSmStart(smDesc); + FwSmMakeTrans(smDesc, GoToStabilize); + FwSmMakeTrans(smDesc, Execute); + FwSmMakeTrans(smDesc, GoToCcdWindow); + FwSmMakeTrans(smDesc, GoToCcdFull); + FwSmMakeTrans(smDesc, GoToDiagnostics); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaSemShutdownCreate.c b/CrIa/src/CrIaPrSm/CrIaSemShutdownCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..11285aedee296dff55298c88eb3175cfd87c65d4 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemShutdownCreate.c @@ -0,0 +1,39 @@ +/** + * @file CrIaSemShutdownCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaSemShutdown function definitions */ +#include "CrIaSemShutdownCreate.h" + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaSemShutdownCreate(void* prData) +{ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 2, /* N_ANODES - The number of action nodes */ + 0, /* N_DNODES - The number of decision nodes */ + 3, /* N_FLOWS - The number of control flows */ + 2, /* N_ACTIONS - The number of actions */ + 2 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaSemShutdown_N1, &CrIaSemShutdownOpenSwitch); + FwPrAddActionNode(prDesc, CrIaSemShutdown_N2, &CrIaSemShutdownN2); + FwPrAddFlowIniToAct(prDesc, CrIaSemShutdown_N2, NULL); + FwPrAddFlowActToFin(prDesc, CrIaSemShutdown_N1, &CrIaSemShutdownWaitT2); + FwPrAddFlowActToAct(prDesc, CrIaSemShutdown_N2, CrIaSemShutdown_N1, &CrIaSemShutdownAfterN2); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaSemShutdownCreate.h b/CrIa/src/CrIaPrSm/CrIaSemShutdownCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..8977172f6e7f3b233b288494fceeeb5eb63e42fe --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemShutdownCreate.h @@ -0,0 +1,72 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaSemShutdown procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaSemShutdown.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:4 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSemShutdownCreate_H_ +#define CrIaSemShutdownCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaSemShutdown_N1 (1) /* The identifier of action node N1 in procedure CrIaSemShutdown */ +#define CrIaSemShutdown_N2 (2) /* The identifier of action node N2 in procedure CrIaSemShutdown */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaSemShutdownCreate(void* prData); + +/** + * Action for node N1. + * <pre> + * Open External SEM Power Switch + * and FPM Heater Power Switch + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaSemShutdownOpenSwitch(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * Send CMD_Standby_Enter to SEM + * @param smDesc the procedure descriptor + */ +void CrIaSemShutdownN2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N1 to Final Node. + * Wait SEM_SHUTDOWN_T2 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemShutdownWaitT2(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N2 to N1. + * Flag_1 || Flag_2 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaSemShutdownAfterN2(FwPrDesc_t prDesc); + +#endif /* CrIaSemShutdownCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaSemShutdownFunc.c b/CrIa/src/CrIaPrSm/CrIaSemShutdownFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..6d45eed1c345ce2b29e47f32938f65ed1b93c451 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemShutdownFunc.c @@ -0,0 +1,159 @@ +/** + * @file CrIaSemShutdownFunc.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwPrConstants.h> +#include <FwProfile/FwPrDCreate.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> /* for FwPrGetCurNode() */ + +/** CrIaSemShutdown function definitions */ +#include "CrIaSemShutdownCreate.h" + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +#include <CrIaIasw.h> + +#if(__sparc__) +#include <ibsw_interface.h> +#endif + +#include <IfswDebug.h> + +#include <Services/General/CrSemConstants.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaSemEvents.h> + +/* imported global variables */ +extern unsigned short SemTransition; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaSemShutdownOpenSwitch(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int timestamp; + CrFwTimeStamp_t time; + unsigned char SemTick; + unsigned short semShutdownT11; + + /* Open external SEM Power Switch and FPM Heater Power Switch */ + +#if(__sparc__) + + CrIbSemLowLevelOp (HEATER_OFF); + CrIbSemLowLevelOp (SWITCH_OFF); /* note: this also stops the SpW time code signal */ + +#else + + /* NOTE: signal SEM Simulator that it should be in state OFF (no HK) */ + +#endif + + /* Mantis 1684: stop time propagation after switch off */ + SemTick = 0; + CrIaPaste(SEMTICK_ID, &SemTick); + + /* Mantis 2073: we stop the SpW ticking here */ +#if (__sparc__) + CrIbDisableSpWTick(); +#endif + + /* record time of shutdown */ + time = CrIbGetCurrentTime(); + timestamp = ((uint32_t)time.t[0] << 24) | ((uint32_t)time.t[1] << 16) | ((uint32_t)time.t[2] << 8) | (uint32_t)time.t[3]; + CrIaPaste(SEMPWROFFTIMESTAMP_ID, ×tamp); + + /* Set SEM_SHUTDOWN_T1 equal to SEM_SHUTDOWN_T11 */ + CrIaCopy(SEM_SHUTDOWN_T11_ID, &semShutdownT11); + CrIaPaste(SEM_SHUTDOWN_T1_ID, &semShutdownT11); + + DEBUGP("POWER OFF!\n"); + + return; +} + +/** Action for node N2. */ +void CrIaSemShutdownN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + FwSmDesc_t cmd; + CrFwBool_t accept=1, start=0, progress=0, term=1; + + DEBUGP("***** Powering off SEM. *****\n"); + + /* reset variable SemTransition */ + SemTransition = 0; + + /* Send Cmd_STANDBY_Enter to SEM: TC(221,2) */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRSEM_SERV221, CRSEM_SERV221_CMD_STANDBY_ENTER, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetAckLevel(cmd, accept, start, progress, term); + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + return; +} + +/** Guard on the Control Flow from N1 to Final Node. */ +FwPrBool_t CrIaSemShutdownWaitT2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short delay_t2 = 0; + + /* Wait SEM_SHUTDOWN_T2 */ + + CrIaCopy(SEM_SHUTDOWN_T2_ID, &delay_t2); + + DEBUGP ("SEM_SHUTDOWN_T2: Guard on the Control Flow from N1 to Final Node: %d/%d\n", FwPrGetNodeExecCnt(prDesc), delay_t2); + + if (FwPrGetNodeExecCnt(prDesc) < delay_t2) + { + return 0; + } + else + { + return 1; + } + +} + +/** Guard on the Control Flow from N2 to N1. */ +FwPrBool_t CrIaSemShutdownAfterN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short delay_t1 = 0; + + /* Wait: SEM_SHUTDOWN_T1 cycles after the SEM Shutdown Procedure was startet execution or + until an event report from SEM have been received confirming entry into STANDBY */ + + CrIaCopy(SEM_SHUTDOWN_T1_ID, &delay_t1); + + DEBUGP ("SEM_SHUTDOWN_T1/3: Guard on the Control Flow from N2 to N1. FwPrGetNodeExecCnt(prDesc) = %d; SemTransition = %d\n", FwPrGetNodeExecCnt(prDesc), SemTransition); + + if ((FwPrGetNodeExecCnt(prDesc) > delay_t1) || (SemTransition == SEM_STATE_STANDBY)) + { + return 1; + } + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaSemShutdownInit.txt b/CrIa/src/CrIaPrSm/CrIaSemShutdownInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..1141bde0db346a9c5ed41c6ea3af0f698252a973 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaSemShutdownInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaSemShutdownCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaSemShutdown is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaSemShutdown is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaTTC1Create.c b/CrIa/src/CrIaPrSm/CrIaTTC1Create.c new file mode 100644 index 0000000000000000000000000000000000000000..e3aadada027bce616391e0819c40d8b61499555e --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC1Create.c @@ -0,0 +1,58 @@ +/** + * @file CrIaTTC1Create.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaTTC1 function definitions */ +#include "CrIaTTC1Create.h" + +/** + * Guard on the Control Flow from DECISION1 to Final Node. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code27565(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaTTC1Create(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaTTC1 */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 3; /* The number of control flows out of decision node DECISION1 in procedure CrIaTTC1 */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 3, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 7, /* N_FLOWS - The number of control flows */ + 3, /* N_ACTIONS - The number of actions */ + 3 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaTTC1_N1, &CrIaTTC1ComputeTemp); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaTTC1_N4, &CrIaTTC1SwitchOff); + FwPrAddActionNode(prDesc, CrIaTTC1_N3, &CrIaTTC1SwitchOn); + FwPrAddFlowIniToAct(prDesc, CrIaTTC1_N1, NULL); + FwPrAddFlowActToDec(prDesc, CrIaTTC1_N1, DECISION1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaTTC1_N3, &CrIaTTC1IsTempTooLow); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaTTC1_N4, &CrIaTTC1IsTempTooHigh); + FwPrAddFlowDecToFin(prDesc, DECISION1, &code27565); + FwPrAddFlowActToFin(prDesc, CrIaTTC1_N4, NULL); + FwPrAddFlowActToFin(prDesc, CrIaTTC1_N3, NULL); + + return prDesc; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaTTC1Create.h b/CrIa/src/CrIaPrSm/CrIaTTC1Create.h new file mode 100644 index 0000000000000000000000000000000000000000..96b9d21640e69208a21b2d409fffbc5c2f86ba1d --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC1Create.h @@ -0,0 +1,92 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaTTC1 procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * + * <b>Note for Control Flow from DECISION1 to N4</b> + * This procedure may run either on the aft + * thermistors and the aft heaters or on the + * front thermistors and the front heaters. + * + * @image html CrIaTTC1.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaTTC1Create_H_ +#define CrIaTTC1Create_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaTTC1_N1 1 /* The identifier of action node N1 in procedure CrIaTTC1 */ +#define CrIaTTC1_N3 2 /* The identifier of action node N3 in procedure CrIaTTC1 */ +#define CrIaTTC1_N4 3 /* The identifier of action node N4 in procedure CrIaTTC1 */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaTTC1Create(void* prData); + +/** + * Action for node N1. + * <pre> + * T = average of two middle + * values of thermistor readings + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTTC1ComputeTemp(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * <pre> + * Ask IBSW to + * switch off the heaters + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTTC1SwitchOff(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Ask IBSW to + * switch on the heaters + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTTC1SwitchOn(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N3. + * T is below lower limit + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTTC1IsTempTooLow(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N4. + * T is above upper limit + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTTC1IsTempTooHigh(FwPrDesc_t prDesc); + +#endif /* CrIaTTC1Create_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaTTC1Func.c b/CrIa/src/CrIaPrSm/CrIaTTC1Func.c new file mode 100644 index 0000000000000000000000000000000000000000..c1e2707dce502a9ec40d90bf796eca0a68606c02 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC1Func.c @@ -0,0 +1,377 @@ +/** + * @file CrIaTTC1Func.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:46 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaTTC1 function definitions */ +#include "CrIaTTC1Create.h" + +/* DataPool */ +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaIasw.h> + +#include <IfswUtilities.h> /* for sort4float() */ +#include <IfswConversions.h> /* for convertToTempEngVal() */ + +#include <IfswDebug.h> + +#if (__sparc__) +#include <iwf_fpga.h> +#endif + +float median_Temp_EngVal; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaTTC1ComputeTemp(FwPrDesc_t __attribute__((unused)) prDesc) +{ + float Temp[4]; + float Temp1=0, Temp2=0, Temp3=0, Temp4=0; /* initialize variables with default values */ +#ifdef PC_TARGET + short Temp1short=0, Temp2short=0, Temp3short=0, Temp4short=0; /* initialize variables with default values */ +#endif + + /* T = average of two middle values of thermistor readings */ + /* Four temperature measurements are available, the middle two are taken (majority voted) and then averaged */ + + /*DEBUGP("TTC1: Calculate T = average of two middle values of thermistor readings\n");*/ + + /*********************************/ + /* TTC1 aft thermistors/heaters */ + /*********************************/ + if (prDesc == prDescTtc1aft) + { + /* Get temperature measurements from data pool */ +#ifdef PC_TARGET + /* NOTE: B=AFT */ + CrIaCopy(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + /* Convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1B_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2B_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3B_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4B_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1B_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2B_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3B_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4B_ID, &Temp4); +#else + /* NOTE: B=AFT */ + CrIaCopy(ADC_TEMPOH1B_ID, &Temp1); + CrIaCopy(ADC_TEMPOH2B_ID, &Temp2); + CrIaCopy(ADC_TEMPOH3B_ID, &Temp3); + CrIaCopy(ADC_TEMPOH4B_ID, &Temp4); +#endif + + Temp[0] = Temp1; + Temp[1] = Temp2; + Temp[2] = Temp3; + Temp[3] = Temp4; + } + + if (prDesc == prDescTtc1front) + { + /* Get temperature measurements from data pool */ +#ifdef PC_TARGET + /* NOTE: A=FRT */ + CrIaCopy(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + /* Convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1A_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2A_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3A_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4A_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1A_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2A_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3A_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4A_ID, &Temp4); +#else + /* NOTE: A=FRT */ + CrIaCopy(ADC_TEMPOH1A_ID, &Temp1); + CrIaCopy(ADC_TEMPOH2A_ID, &Temp2); + CrIaCopy(ADC_TEMPOH3A_ID, &Temp3); + CrIaCopy(ADC_TEMPOH4A_ID, &Temp4); +#endif + + Temp[0] = Temp1; + Temp[1] = Temp2; + Temp[2] = Temp3; + Temp[3] = Temp4; + } + + sort4float (Temp); + + /* Calculate the average of the two middle temperature values */ + median_Temp_EngVal = (Temp[1] + Temp[2])*0.5; + + if (prDesc == prDescTtc1aft) + { + CrIaPaste(TTC1AVTEMPAFT_ID, &median_Temp_EngVal); + } + if (prDesc == prDescTtc1front) + { + CrIaPaste(TTC1AVTEMPFRT_ID, &median_Temp_EngVal); + } + + return; +} + +/** Action for node N4. */ +void CrIaTTC1SwitchOff(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Ask IBSW to switch off the heaters */ + + /* + DEBUGP("TTC1: heaters off\n"); + */ + + if (prDesc == prDescTtc1aft) + { + /* switch off aft heaters */ + CrIaHeaterOff(HEATER_3); + CrIaHeaterOff(HEATER_4); +#ifdef PC_TARGET +{ + float Temp1, Temp2, Temp3, Temp4; + short Temp1short, Temp2short, Temp3short, Temp4short; + + CrIaCopy(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + Temp1short -= 3; + Temp2short -= 3; + Temp3short -= 3; + Temp4short -= 3; + + CrIaPaste(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaPaste(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaPaste(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaPaste(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + /* Convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1B_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2B_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3B_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4B_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1B_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2B_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3B_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4B_ID, &Temp4); +} +#endif /* PC_TARGET */ + } + + if (prDesc == prDescTtc1front) + { + /* switch off front heaters */ + CrIaHeaterOff(HEATER_1); + CrIaHeaterOff(HEATER_2); +#ifdef PC_TARGET +{ + float Temp1, Temp2, Temp3, Temp4; + short Temp1short, Temp2short, Temp3short, Temp4short; + + CrIaCopy(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + Temp1short -= 3; + Temp2short -= 3; + Temp3short -= 3; + Temp4short -= 3; + + CrIaPaste(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaPaste(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaPaste(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaPaste(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + /* Convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1A_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2A_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3A_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4A_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1A_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2A_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3A_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4A_ID, &Temp4); +} +#endif /* PC_TARGET */ + } + + return; +} + +/** Action for node N3. */ +void CrIaTTC1SwitchOn(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Ask IBSW to switch on the heaters */ + + /* + DEBUGP("TTC1: heaters on\n"); + */ + + if (prDesc == prDescTtc1aft) + { + /* switch on aft heaters */ + CrIaHeaterOn(HEATER_3); + CrIaHeaterOn(HEATER_4); +#ifdef PC_TARGET +{ + float Temp1, Temp2, Temp3, Temp4; + short Temp1short, Temp2short, Temp3short, Temp4short; + + CrIaCopy(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + Temp1short += 3; + Temp2short += 3; + Temp3short += 3; + Temp4short += 3; + + CrIaPaste(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaPaste(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaPaste(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaPaste(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + /* Convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1B_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2B_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3B_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4B_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1B_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2B_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3B_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4B_ID, &Temp4); +} +#endif /* PC_TARGET */ + } + + if (prDesc == prDescTtc1front) + { + /* switch on front heaters */ + CrIaHeaterOn(HEATER_1); + CrIaHeaterOn(HEATER_2); +#ifdef PC_TARGET +{ + float Temp1, Temp2, Temp3, Temp4; + short Temp1short, Temp2short, Temp3short, Temp4short; + + CrIaCopy(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + Temp1short += 3; + Temp2short += 3; + Temp3short += 3; + Temp4short += 3; + + CrIaPaste(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaPaste(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaPaste(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaPaste(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + /* Convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1A_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2A_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3A_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4A_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1A_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2A_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3A_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4A_ID, &Temp4); +} +#endif /* PC_TARGET */ + } + + return; +} + +/** Guard on the Control Flow from DECISION1 to N3. */ +FwPrBool_t CrIaTTC1IsTempTooLow(FwPrDesc_t __attribute__((unused)) prDesc) +{ + float lowerLevel_Temp = -100.0f; /* choose a safe (in case of doubt switch off) init value to calm CLANG */ + + /* T < TTC1_LL */ + + if (prDesc == prDescTtc1aft) + { + CrIaCopy(TTC1_LL_AFT_ID, &lowerLevel_Temp); + } + + if (prDesc == prDescTtc1front) + { + CrIaCopy(TTC1_LL_FRT_ID, &lowerLevel_Temp); + } + + if (median_Temp_EngVal < lowerLevel_Temp) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION1 to N4. */ +FwPrBool_t CrIaTTC1IsTempTooHigh(FwPrDesc_t __attribute__((unused)) prDesc) +{ + float upperLevel_Temp = -100.0f; /* choose a safe (in case of doubt switch off) init value to calm CLANG */ + + /* T > TTC1_UL */ + + if (prDesc == prDescTtc1aft) + { + CrIaCopy(TTC1_UL_AFT_ID, &upperLevel_Temp); + } + + if (prDesc == prDescTtc1front) + { + CrIaCopy(TTC1_UL_FRT_ID, &upperLevel_Temp); + } + + if (median_Temp_EngVal > upperLevel_Temp) + { + return 1; + } + else + { + return 0; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaTTC1Init.txt b/CrIa/src/CrIaPrSm/CrIaTTC1Init.txt new file mode 100644 index 0000000000000000000000000000000000000000..a444e1dac52bee6609838c6ffd6db62e6776bdc7 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC1Init.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaTTC1Create(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaTTC1 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaTTC1 is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaTTC2Create.c b/CrIa/src/CrIaPrSm/CrIaTTC2Create.c new file mode 100644 index 0000000000000000000000000000000000000000..a2be7dfe7f952b3e20fdf9728e606aa428e124bc --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC2Create.c @@ -0,0 +1,91 @@ +/** + * @file CrIaTTC2Create.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaTTC2 function definitions */ +#include "CrIaTTC2Create.h" + +/** + * Guard on the Control Flow from DECISION1 to Final Node. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code31109(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION2 to DECISION3. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code98960(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/** + * Guard on the Control Flow from DECISION3 to Final Node. + * ! Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code9404(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaTTC2Create(void* prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaTTC2 */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaTTC2 */ + const FwPrCounterU2_t DECISION2 = 2; /* The identifier of decision node DECISION2 in procedure CrIaTTC2 */ + const FwPrCounterU2_t N_OUT_OF_DECISION2 = 2; /* The number of control flows out of decision node DECISION2 in procedure CrIaTTC2 */ + const FwPrCounterU2_t DECISION3 = 3; /* The identifier of decision node DECISION3 in procedure CrIaTTC2 */ + const FwPrCounterU2_t N_OUT_OF_DECISION3 = 2; /* The number of control flows out of decision node DECISION3 in procedure CrIaTTC2 */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 4, /* N_ANODES - The number of action nodes */ + 3, /* N_DNODES - The number of decision nodes */ + 11, /* N_FLOWS - The number of control flows */ + 4, /* N_ACTIONS - The number of actions */ + 6 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaTTC2_N1, &CrIaTTC2ComputeTemp); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaTTC2_N4, &CrIaTTC2SwitchOn); + FwPrAddActionNode(prDesc, CrIaTTC2_N3, &CrIaTTC2SwitchOff); + FwPrAddDecisionNode(prDesc, DECISION2, N_OUT_OF_DECISION2); + FwPrAddActionNode(prDesc, CrIaTTC2_N2, &CrIaTTC2ComputeOnTime); + FwPrAddDecisionNode(prDesc, DECISION3, N_OUT_OF_DECISION3); + FwPrAddFlowIniToDec(prDesc, DECISION2, NULL); + FwPrAddFlowActToAct(prDesc, CrIaTTC2_N1, CrIaTTC2_N2, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaTTC2_N4, &CrIaTTC2IsOnTimeGreaterThanZero); + FwPrAddFlowDecToFin(prDesc, DECISION1, &code31109); + FwPrAddFlowActToFin(prDesc, CrIaTTC2_N4, NULL); + FwPrAddFlowActToFin(prDesc, CrIaTTC2_N3, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION2, CrIaTTC2_N1, &CrIaTTC2IsFirstCycle); + FwPrAddFlowDecToDec(prDesc, DECISION2, DECISION3, &code98960); + FwPrAddFlowActToDec(prDesc, CrIaTTC2_N2, DECISION1, NULL); + FwPrAddFlowDecToAct(prDesc, DECISION3, CrIaTTC2_N3, &CrIaTTC2Flag1); + FwPrAddFlowDecToFin(prDesc, DECISION3, &code9404); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaTTC2Create.h b/CrIa/src/CrIaPrSm/CrIaTTC2Create.h new file mode 100644 index 0000000000000000000000000000000000000000..54feb13839ce70bd2003d955cad1fd1f4c037ed0 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC2Create.h @@ -0,0 +1,105 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaTTC2 procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaTTC2.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaTTC2Create_H_ +#define CrIaTTC2Create_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaTTC2_N1 1 /* The identifier of action node N1 in procedure CrIaTTC2 */ +#define CrIaTTC2_N2 2 /* The identifier of action node N2 in procedure CrIaTTC2 */ +#define CrIaTTC2_N3 3 /* The identifier of action node N3 in procedure CrIaTTC2 */ +#define CrIaTTC2_N4 4 /* The identifier of action node N4 in procedure CrIaTTC2 */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaTTC2Create(void* prData); + +/** + * Action for node N1. + * <pre> + * T = average of two middle + * values of thermistor readings + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTTC2ComputeTemp(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * <pre> + * Ask IBSW to + * switch on the heaters + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTTC2SwitchOn(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * <pre> + * Ask IBSW to + * switch off the heaters + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTTC2SwitchOff(FwPrDesc_t prDesc); + +/** + * Action for node N2. + * Compute onTime + * @param smDesc the procedure descriptor + */ +void CrIaTTC2ComputeOnTime(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N4. + * onTime > 0 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTTC2IsOnTimeGreaterThanZero(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION2 to N1. + * <pre> + * Current cycle is first cycle in an + * acquisition cycle + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTTC2IsFirstCycle(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION3 to N3. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTTC2Flag1(FwPrDesc_t prDesc); + +#endif /* CrIaTTC2Create_H_ */ \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaTTC2Func.c b/CrIa/src/CrIaPrSm/CrIaTTC2Func.c new file mode 100644 index 0000000000000000000000000000000000000000..1e0753c77aeec3ee6597db499a9f875f309fdc01 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC2Func.c @@ -0,0 +1,481 @@ +/** + * @file CrIaTTC2Func.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Feb 11 2016 22:56:45 + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" +#include "FwProfile/FwPrCore.h" + +/** CrIaTTC2 function definitions */ +#include "CrIaTTC2Create.h" + +/* DataPool */ +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaIasw.h> + +#include <IfswUtilities.h> /* for sort4float() */ +#include <IfswConversions.h> /* for convertToTempEngVal() */ +#include <IfswDebug.h> + +#if (__sparc__) +#include <iwf_fpga.h> +#endif + +/** CrIaTTC2 global variables for aft temperature */ +float prevDelTemp_Aft, prevIntTemp_Aft, onTime_Aft, curOnTime_Aft; +/** CrIaTTC2 global variables for front temperature */ +float prevDelTemp_Frt, prevIntTemp_Frt, onTime_Frt, curOnTime_Frt; +#if PC_TARGET +CrFwBool_t heater_Aft, heater_Frt; +#endif /* PC_TARGET */ + +float median_Temp_Aft_EngVal; +float median_Temp_Frt_EngVal; + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaTTC2ComputeTemp(FwPrDesc_t __attribute__((unused)) prDesc) +{ + float Temp[4]; + float Temp1=0, Temp2=0, Temp3=0, Temp4=0; /* initialize variables with default values */ +#ifdef PC_TARGET + short Temp1short=0, Temp2short=0, Temp3short=0, Temp4short=0; /* initialize variables with default values */ +#endif + + /* T = average of two middle values of thermistor readings */ + /* Four temperature measurements are available, the middle two are taken (majority voted) and then averaged */ + + + /***********************************/ + /* TTC2 aft thermistors/heaters */ + /***********************************/ + if (prDesc == prDescTtc2aft) + { + /* Get temperature measurements from data pool */ +#ifdef PC_TARGET + /* B=AFT */ + CrIaCopy(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + /* convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1B_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2B_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3B_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4B_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1B_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2B_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3B_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4B_ID, &Temp4); +#else + /* B=AFT */ + CrIaCopy(ADC_TEMPOH1B_ID, &Temp1); + CrIaCopy(ADC_TEMPOH2B_ID, &Temp2); + CrIaCopy(ADC_TEMPOH3B_ID, &Temp3); + CrIaCopy(ADC_TEMPOH4B_ID, &Temp4); +#endif + + Temp[0] = Temp1; + Temp[1] = Temp2; + Temp[2] = Temp3; + Temp[3] = Temp4; + + sort4float (Temp); + + /* Calculate the average of the two middle temperature values */ + median_Temp_Aft_EngVal = (Temp[1] + Temp[2])*0.5; + + } + + /***********************************/ + /* TTC2 front thermistors/heaters */ + /***********************************/ + if (prDesc == prDescTtc2front) + { + /* Get temperature measurements from data pool */ +#ifdef PC_TARGET + /* A=FRT */ + CrIaCopy(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + /* convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1A_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2A_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3A_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4A_ID) + CONVERT_KTODEGC; + + CrIaPaste(ADC_TEMPOH1A_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2A_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3A_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4A_ID, &Temp4); +#else + /* A=FRT */ + CrIaCopy(ADC_TEMPOH1A_ID, &Temp1); + CrIaCopy(ADC_TEMPOH2A_ID, &Temp2); + CrIaCopy(ADC_TEMPOH3A_ID, &Temp3); + CrIaCopy(ADC_TEMPOH4A_ID, &Temp4); +#endif + + Temp[0] = Temp1; + Temp[1] = Temp2; + Temp[2] = Temp3; + Temp[3] = Temp4; + + sort4float (Temp); + + /* Calculate the average of the two middle temperature values */ + median_Temp_Frt_EngVal = (Temp[1] + Temp[2])*0.5; + + } + + return; +} + +/** Action for node N2. */ +void CrIaTTC2ComputeOnTime(FwPrDesc_t __attribute__((unused)) prDesc) +{ + float coeffTtc2P = 1.0f, coeffTtc2D = 1.0f, coeffTtc2I = 1.0f; + int ttc2ExecPer; + float curDelTemp, curIntTemp, refTemp, offset_Aft, offset_Frt; + + /* Compute onTime; onTime is computed by a PID controller */ + + /* Get PID coefficients from data pool */ + if (prDesc == prDescTtc2aft) + { + CrIaCopy(TTC2_PA_ID, &coeffTtc2P); + CrIaCopy(TTC2_DA_ID, &coeffTtc2D); + CrIaCopy(TTC2_IA_ID, &coeffTtc2I); + } + if (prDesc == prDescTtc2front) + { + CrIaCopy(TTC2_PF_ID, &coeffTtc2P); + CrIaCopy(TTC2_DF_ID, &coeffTtc2D); + CrIaCopy(TTC2_IF_ID, &coeffTtc2I); + } + + /* Get TTC2_EXEC_PER from data pool */ + CrIaCopy(TTC2_EXEC_PER_ID, &ttc2ExecPer); + + /* Get TTC2_REF_TEMP from data pool */ + CrIaCopy(TTC2_REF_TEMP_ID, &refTemp); + + if (prDesc == prDescTtc2aft) + { + curOnTime_Aft = 0.0f; /* reset current onTime, used in Guard out of DECISION3 (Mantis 2108) */ + + CrIaCopy(TTC2_OFFSETA_ID, &offset_Aft); + + curDelTemp = refTemp - median_Temp_Aft_EngVal; + + curIntTemp = prevIntTemp_Aft + curDelTemp * ttc2ExecPer * 0.125f; + + onTime_Aft = offset_Aft + coeffTtc2P * curDelTemp + coeffTtc2D * (curDelTemp - prevDelTemp_Aft) / (ttc2ExecPer * 0.125f) + coeffTtc2I * curIntTemp; + + prevIntTemp_Aft = curIntTemp; + prevDelTemp_Aft = curDelTemp; + + /* copy new calculated values of onTime and intTemp to data pool */ + CrIaPaste(ONTIMEAFT_ID, &onTime_Aft); + CrIaPaste(INTTIMEAFT_ID, &curIntTemp); + } + + if (prDesc == prDescTtc2front) + { + curOnTime_Frt = 0.0f; /* reset current onTime, used in Guard out of DECISION3 (Mantis 2108) */ + + CrIaCopy(TTC2_OFFSETF_ID, &offset_Frt); + + curDelTemp = refTemp - median_Temp_Frt_EngVal; + + curIntTemp = prevIntTemp_Frt + curDelTemp * ttc2ExecPer * 0.125f; + + onTime_Frt = offset_Frt + coeffTtc2P * curDelTemp + coeffTtc2D * (curDelTemp - prevDelTemp_Frt) / (ttc2ExecPer * 0.125f) + coeffTtc2I * curIntTemp; + + prevIntTemp_Frt = curIntTemp; + prevDelTemp_Frt = curDelTemp; + + /* copy new calculated values of onTime and intTemp to data pool */ + CrIaPaste(ONTIMEFRONT_ID, &onTime_Frt); + CrIaPaste(INTTIMEFRONT_ID, &curIntTemp); + + } + + return; +} + +/** Action for node N3. */ +void CrIaTTC2SwitchOff(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Ask IBSW to switch off the heaters */ + + if (prDesc == prDescTtc2aft) + { +#ifdef PC_TARGET + heater_Aft = 0; +#else + /* switch off aft heaters */ + CrIaHeaterOff(HEATER_3); + CrIaHeaterOff(HEATER_4); +#endif /* PC_TARGET */ + } + + if (prDesc == prDescTtc2front) + { +#ifdef PC_TARGET + heater_Frt = 0; +#else + /* switch off front heaters */ + CrIaHeaterOff(HEATER_1); + CrIaHeaterOff(HEATER_2); +#endif /* PC_TARGET */ + } + + return; +} + +/** Action for node N4. */ +void CrIaTTC2SwitchOn(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* Ask IBSW to switch on the heaters */ + + if (prDesc == prDescTtc2aft) + { +#ifdef PC_TARGET + heater_Aft = 1; +#else + /* switch on aft heaters */ + CrIaHeaterOn(HEATER_3); + CrIaHeaterOn(HEATER_4); +#endif /* PC_TARGET */ + } + + if (prDesc == prDescTtc2front) + { +#ifdef PC_TARGET + heater_Frt = 1; +#else + /* switch on front heaters */ + CrIaHeaterOn(HEATER_1); + CrIaHeaterOn(HEATER_2); +#endif /* PC_TARGET */ + } + + return; +} + +/********** + * GUARDS * + **********/ + +/** Guard on the Control Flow from DECISION2 to N1. */ +FwPrBool_t CrIaTTC2IsFirstCycle(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* [ Current cycle is first cycle in an acquisition cycle ] */ + + if (firstCycleAcqCycTtc2) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION1 to N4. */ +FwPrBool_t CrIaTTC2IsOnTimeGreaterThanZero(FwPrDesc_t __attribute__((unused)) prDesc) +{ + float onTime = 0.0f; + + /* [ onTime > 0 ] */ + + /* get onTime */ + if (prDesc == prDescTtc2aft) + { + onTime = onTime_Aft; + } + if (prDesc == prDescTtc2front) + { + onTime = onTime_Frt; + } + + if (onTime > 0.0f) + { + return 1; + } + else + { + return 0; + } +} + +/** Guard on the Control Flow from DECISION3 to N3. */ +FwPrBool_t CrIaTTC2Flag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + /* [ Flag_1 ] */ + /* Flag_1: (the heaters are currently on) && (the requested onTime terminates in the current cycle) */ + + /* check if heaters are on */ +#ifdef PC_TARGET + { + float Temp1=0.0f, Temp2=0.0f, Temp3=0.0f, Temp4=0.0f; + short Temp1short, Temp2short, Temp3short, Temp4short; + float Temp[4]; + + (void) Temp; + + if (prDesc == prDescTtc2aft) + { + CrIaCopy(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + if (heater_Aft == 0) + { + Temp1short -= 3; + Temp2short -= 3; + Temp3short -= 3; + Temp4short -= 3; + } + else + { + Temp1short += 3; + Temp2short += 3; + Temp3short += 3; + Temp4short += 3; + } + + CrIaPaste(ADC_TEMPOH1B_RAW_ID, &Temp1short); + CrIaPaste(ADC_TEMPOH2B_RAW_ID, &Temp2short); + CrIaPaste(ADC_TEMPOH3B_RAW_ID, &Temp3short); + CrIaPaste(ADC_TEMPOH4B_RAW_ID, &Temp4short); + + /* convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1B_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2B_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3B_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4B_ID) + CONVERT_KTODEGC; + } + + if (prDesc == prDescTtc2front) + { + CrIaCopy(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaCopy(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaCopy(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaCopy(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + if (heater_Frt == 0) + { + Temp1short -= 3; + Temp2short -= 3; + Temp3short -= 3; + Temp4short -= 3; + } + else + { + Temp1short += 3; + Temp2short += 3; + Temp3short += 3; + Temp4short += 3; + } + + CrIaPaste(ADC_TEMPOH1A_RAW_ID, &Temp1short); + CrIaPaste(ADC_TEMPOH2A_RAW_ID, &Temp2short); + CrIaPaste(ADC_TEMPOH3A_RAW_ID, &Temp3short); + CrIaPaste(ADC_TEMPOH4A_RAW_ID, &Temp4short); + + /* convert raw value to engineering value */ + Temp1 = convertToTempEngVal(Temp1short, ADC_TEMPOH1A_ID) + CONVERT_KTODEGC; + Temp2 = convertToTempEngVal(Temp2short, ADC_TEMPOH2A_ID) + CONVERT_KTODEGC; + Temp3 = convertToTempEngVal(Temp3short, ADC_TEMPOH3A_ID) + CONVERT_KTODEGC; + Temp4 = convertToTempEngVal(Temp4short, ADC_TEMPOH4A_ID) + CONVERT_KTODEGC; + } + + Temp[0] = Temp1; + Temp[1] = Temp2; + Temp[2] = Temp3; + Temp[3] = Temp4; + + if (prDesc == prDescTtc2aft) + { + CrIaPaste(ADC_TEMPOH1B_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2B_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3B_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4B_ID, &Temp4); + } + + if (prDesc == prDescTtc2front) + { + CrIaPaste(ADC_TEMPOH1A_ID, &Temp1); + CrIaPaste(ADC_TEMPOH2A_ID, &Temp2); + CrIaPaste(ADC_TEMPOH3A_ID, &Temp3); + CrIaPaste(ADC_TEMPOH4A_ID, &Temp4); + } + + } +#endif /* PC_TARGET */ + + + if (prDesc == prDescTtc2aft) + { +#ifdef PC_TARGET + if (heater_Aft) +#else + if (CrIaHeaterStatus(HEATER_3) && CrIaHeaterStatus(HEATER_4)) +#endif /* PC_TARGET */ + { + if (curOnTime_Aft >= onTime_Aft) + { + return 1; + } + else + { + curOnTime_Aft += 0.125f; /* add one cycle to current onTime */ + return 0; + } + } + } + + if (prDesc == prDescTtc2front) + { +#ifdef PC_TARGET + if (heater_Frt == 1) +#else + if (CrIaHeaterStatus(HEATER_1) && CrIaHeaterStatus(HEATER_2)) +#endif /* PC_TARGET */ + { + if (curOnTime_Frt >= onTime_Frt) + { + return 1; + } + else + { + curOnTime_Frt += 0.125f; /* add one cycle to current onTime */ + return 0; + } + } + } + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaTTC2Init.txt b/CrIa/src/CrIaPrSm/CrIaTTC2Init.txt new file mode 100644 index 0000000000000000000000000000000000000000..8851f51b61b713efcac3fe0cc23e1bd0ebe8683a --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTTC2Init.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaTTC2Create(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaTTC2 is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaTTC2 is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundCreate.c b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..2dae2bb1724b8b9eabe8f194c942c7776af00c75 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundCreate.c @@ -0,0 +1,59 @@ +/** + * @file CrIaTransferFbfToGroundCreate.c + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:4 + */ + +#include <stdlib.h> + +/** FW Profile function definitions */ +#include "FwProfile/FwPrDCreate.h" +#include "FwProfile/FwPrConfig.h" + +/** CrIaTransferFbfToGround function definitions */ +#include "CrIaTransferFbfToGroundCreate.h" + +/** + * Guard on the Control Flow from DECISION1 to Final Node. + * Else + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +static FwPrBool_t code3618(FwPrDesc_t __attribute__((unused)) prDesc) +{ + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t CrIaTransferFbfToGroundCreate(void* __attribute__((unused)) prData) +{ + const FwPrCounterU2_t DECISION1 = 1; /* The identifier of decision node DECISION1 in procedure CrIaTransferFbfToGround */ + const FwPrCounterU2_t N_OUT_OF_DECISION1 = 2; /* The number of control flows out of decision node DECISION1 in procedure CrIaTransferFbfToGround */ + + /** Create the procedure */ + FwPrDesc_t prDesc = FwPrCreate( + 4, /* N_ANODES - The number of action nodes */ + 1, /* N_DNODES - The number of decision nodes */ + 7, /* N_FLOWS - The number of control flows */ + 4, /* N_ACTIONS - The number of actions */ + 4 /* N_GUARDS - The number of guards */ + ); + + /** Configure the procedure */ + FwPrSetData(prDesc, prData); + FwPrAddActionNode(prDesc, CrIaTransferFbfToGround_N2, &CrIaTransferFbfToGroundN2); + FwPrAddActionNode(prDesc, CrIaTransferFbfToGround_N3, &CrIaTransferFbfToGroundN3); + FwPrAddDecisionNode(prDesc, DECISION1, N_OUT_OF_DECISION1); + FwPrAddActionNode(prDesc, CrIaTransferFbfToGround_N1, &CrIaTransferFbfToGroundN1); + FwPrAddActionNode(prDesc, CrIaTransferFbfToGround_N4, &CrIaTransferFbfToGroundN4); + FwPrAddFlowIniToAct(prDesc, CrIaTransferFbfToGround_N1, NULL); + FwPrAddFlowActToAct(prDesc, CrIaTransferFbfToGround_N2, CrIaTransferFbfToGround_N3, &CrIaTransferFbfToGroundIsCompleted); + FwPrAddFlowActToDec(prDesc, CrIaTransferFbfToGround_N3, DECISION1, &CrIaTransferFbfToGroundIsFlag1); + FwPrAddFlowDecToAct(prDesc, DECISION1, CrIaTransferFbfToGround_N4, &CrIaTransferFbfToGroundIsContinue); + FwPrAddFlowDecToFin(prDesc, DECISION1, &code3618); + FwPrAddFlowActToAct(prDesc, CrIaTransferFbfToGround_N1, CrIaTransferFbfToGround_N2, NULL); + FwPrAddFlowActToAct(prDesc, CrIaTransferFbfToGround_N4, CrIaTransferFbfToGround_N2, NULL); + + return prDesc; +} diff --git a/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundCreate.h b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..ababb9c9be0e87b75bb068bb474344ecbf0ffe34 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundCreate.h @@ -0,0 +1,107 @@ +/** + * @file + * This header file declares the function to create one instance of the CrIaTransferFbfToGround procedure. + * The procedure is configured with a set of function pointers representing the non-default + * actions and guards of the procedure. Some of these functions may also be declared in + * this header file in accordance with the configuration of the procedure in the FW Profile + * Editor. In the latter case, the user has to provide an implementation for these functions + * in a user-supplied body file. + * + * This header file has been automatically generated by the FW Profile Editor. + * The procedure created by this file is shown in the figure below. + * @image html CrIaTransferFbfToGround.png + * + * @author FW Profile code generator version 4.63 + * @date Created on: Jun 3 2016 19:48:4 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaTransferFbfToGroundCreate_H_ +#define CrIaTransferFbfToGroundCreate_H_ + +/** FW Profile function definitions */ +#include "FwProfile/FwPrConstants.h" + +/** Action node identifiers */ +#define CrIaTransferFbfToGround_N1 1 /* The identifier of action node N1 in procedure CrIaTransferFbfToGround */ +#define CrIaTransferFbfToGround_N2 2 /* The identifier of action node N2 in procedure CrIaTransferFbfToGround */ +#define CrIaTransferFbfToGround_N3 3 /* The identifier of action node N3 in procedure CrIaTransferFbfToGround */ +#define CrIaTransferFbfToGround_N4 4 /* The identifier of action node N4 in procedure CrIaTransferFbfToGround */ + +/** + * Create a new procedure descriptor. + * This interface creates the procedure descriptor dynamically. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (note that the default value of the pointer + * to the procedure data when the procedure is created is NULL). + * @return the pointer to the procedure descriptor + */ +FwPrDesc_t CrIaTransferFbfToGroundCreate(void* prData); + +/** + * Action for node N2. + * <pre> + * Start FBF Load Proc. + * to load FBF identified by + * FBF Counter into SDU4 + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTransferFbfToGroundN2(FwPrDesc_t prDesc); + +/** + * Action for node N3. + * Start Down-Transfer of SDU4 + * @param smDesc the procedure descriptor + */ +void CrIaTransferFbfToGroundN3(FwPrDesc_t prDesc); + +/** + * Action for node N1. + * <pre> + * Set FBF Counter to identifier of + * first FBF to be transferred to ground + * </pre> + * @param smDesc the procedure descriptor + */ +void CrIaTransferFbfToGroundN1(FwPrDesc_t prDesc); + +/** + * Action for node N4. + * Increment FBF Counter + * @param smDesc the procedure descriptor + */ +void CrIaTransferFbfToGroundN4(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N2 to N3. + * <pre> + * FBF Load Procedure + * has completed + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTransferFbfToGroundIsCompleted(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from N3 to DECISION1. + * Flag_1 + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTransferFbfToGroundIsFlag1(FwPrDesc_t prDesc); + +/** + * Guard on the Control Flow from DECISION1 to N4. + * <pre> + * Number of images + * transferred to ground + * is smaller than pNmbImages + * </pre> + * @param smDesc the procedure descriptor + * @return 1 if the guard is fulfilled, otherwise 0. + */ +FwPrBool_t CrIaTransferFbfToGroundIsContinue(FwPrDesc_t prDesc); + +#endif /* CrIaTransferFbfToGroundCreate_H_ */ diff --git a/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundFunc.c b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundFunc.c new file mode 100644 index 0000000000000000000000000000000000000000..427cb5be8eace8cc8ba1a09ca633ae35620561be --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundFunc.c @@ -0,0 +1,225 @@ +/** + * @file CrIaTransferFbfToGroundFunc.c + * @ingroup CrIaPrSci + * @authors FW Profile code generator version 4.63; Institute for Astrophysics, 2015-2016 + * @date Created on: Jun 3 2016 19:48:4 + * + * @brief Implementation of the Transfer FBF To Ground Procedure nodes and guards. + * Transfer a pre-defined number of Flash-Based Files to ground. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwPrConstants.h> +#include <FwProfile/FwPrDCreate.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> + +/** CrIaTransferFbfToGround function definitions */ +#include <CrIaPrSm/CrIaTransferFbfToGroundCreate.h> + +#include <CrIaPrSm/CrIaSduCreate.h> /* for StartDownTransfer and CrIaSdu_INACTIVE */ + +#include <CrIaIasw.h> /* for Event Reporting and extern sm and prDescriptors */ +#if (__sparc__) +#include "wrap_malloc.h" +#else +#define FLASH_BLOCKSIZE 0 +#define SRAM1_FLASH_ADDR 0 +#endif + +#include <IfswDebug.h> + + +/* ----------------------------------------------------------------------------------------------------------------- */ + +/** Action for node N1. */ +void CrIaTransferFbfToGroundN1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId, fbfEnb; + unsigned char pNmbFbf; + unsigned char nmbFbfEnb; + int i; + + /* Set FBF Counter to identifier of first FBF to be transfered to ground */ + + CrIaCopy(TRANSFBFTOGRND_PFBFINIT_ID, &fbfId); + CrIaPaste(FBFLOAD_PFBFID_ID, &fbfId); + nmbFbfEnb = 1; /* the initial FBF will be transmitted regardless of its enabled status */ + + /* Check how many enabled FBF are available */ + CrIaCopy(TRANSFBFTOGRND_PNMBFBF_ID, &pNmbFbf); + + /* get number of enabled FBFs disregarding the initial one */ + for (i = 0; i<250; i++) /* NOTE: could use GetDataPoolMult(FBF_ENB_ID) */ + { + if (i != fbfId-1) /* do not count the initial one */ + { + /* check if FBF is enabled */ + CrIaCopyArrayItem(FBF_ENB_ID, &fbfEnb, i); + if (fbfEnb == 1) + { + nmbFbfEnb += 1; + } + } + } + + if (nmbFbfEnb < pNmbFbf) + { + pNmbFbf = nmbFbfEnb; + } + + CrIaPaste(TRANSFBFTOGRND_PNMBFBF_ID, &pNmbFbf); + + + return; +} + + +/** Action for node N2. */ +void CrIaTransferFbfToGroundN2(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned int fbfRamAddr; + unsigned char fbfNBlocks; + + fbfRamAddr = SRAM1_FLASH_ADDR; /* this is SDU4 */ + CrIaPaste(FBFLOAD_PFBFRAMADDR_ID, &fbfRamAddr); + + /* Mantis 2129: this was: fbfNBlocks = FBF_SIZE */ + CrIaCopy(TRANSFBFTOGRND_PFBFSIZE_ID, &fbfNBlocks); + + CrIaPaste(FBFLOAD_PFBFNBLOCKS_ID, &fbfNBlocks); + + /* Mantis 2239: modification to skip empty FBFs + was reverted. We start the FBF Load Proc unconditionally */ + + /* Start FBF Load Proc. to load FBF identified by FBF Counter into SDU4 */ + FwPrStart(prDescFbfLoad); + + return; +} + + +/** Action for node N3. */ +void CrIaTransferFbfToGroundN3(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char pNmbFbf; + + /* due to Mantis 1421 / 1626 we no longer set the size here */ + + /* Start Down-Transfer of SDU4 */ + + FwSmMakeTrans(smDescSdu4, StartDownTransfer); + + /* reduce number of FBFs to be transfered, which will be checked by the Guard on the */ + /* Control Flow from DECISION1 to N4. */ + CrIaCopy(TRANSFBFTOGRND_PNMBFBF_ID, &pNmbFbf); + pNmbFbf -= 1; + CrIaPaste(TRANSFBFTOGRND_PNMBFBF_ID, &pNmbFbf); + + return; +} + +/** Action for node N4. */ +void CrIaTransferFbfToGroundN4(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char fbfId, fbfEnb; + int i, k; + + /* Increment FBF Counter skipping disabled FBFs */ + + CrIaCopy(FBFLOAD_PFBFID_ID, &fbfId); + + for (k=0; k<249; k++) /* do not check and/or transfer initial FBF again, therefore use only (250-1) FBFs */ + { + + if (fbfId == 250) /* NOTE: could use GetDataPoolMult(FBF_ENB_ID) */ + { + i = 0; /* wrap index */ + fbfId = 1; /* wrap ID */ + } + else + { + i = fbfId; /* set index to next possible one */ + fbfId += 1; /* set ID to next possible one */ + } + + /* check if FBF is enabled */ + CrIaCopyArrayItem(FBF_ENB_ID, &fbfEnb, i); + + if (fbfEnb == 1) + { + CrIaPaste(FBFLOAD_PFBFID_ID, &fbfId); + break; + } + + } + + return; +} + +/** Guard on the Control Flow from N2 to N3. */ +FwPrBool_t CrIaTransferFbfToGroundIsCompleted(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short status; + + /* [ FBF Load Procedure has completed ] */ + status = FwPrIsStarted(prDescFbfLoad); + + if (status != PR_STOPPED) + return 0; + + return 1; +} + +/** Guard on the Control Flow from N3 to DECISION1. */ +FwPrBool_t CrIaTransferFbfToGroundIsFlag1(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned short sdu4State; + + /* Flag_1 = Down-Transfer of SDU4 has completed (i.e. SDU4 State Machine is in state INACTIVE) */ + + sdu4State = FwSmGetCurState(smDescSdu4); + + if (sdu4State == CrIaSdu_INACTIVE) + return 1; + + return 0; +} + +/** Guard on the Control Flow from DECISION1 to N4. */ +FwPrBool_t CrIaTransferFbfToGroundIsContinue(FwPrDesc_t __attribute__((unused)) prDesc) +{ + unsigned char pNmbFbf; + + /* (Number of FBFs transferred to ground is smaller than pNmbFbf) && */ + /* (There is at least one enabled FBF still to be transferred) ... NOTE: this is already done in N1 by setting pNmbFbf */ + + CrIaCopy(TRANSFBFTOGRND_PNMBFBF_ID, &pNmbFbf); + + if (pNmbFbf > 0) + return 1; + + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ + diff --git a/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundInit.txt b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundInit.txt new file mode 100644 index 0000000000000000000000000000000000000000..e13ddee8c48ee026d56104145634ac0e3e9c98a8 --- /dev/null +++ b/CrIa/src/CrIaPrSm/CrIaTransferFbfToGroundInit.txt @@ -0,0 +1,20 @@ +{ + /** Define the procedure descriptor (PRD) */ + FwPrDesc_t prDesc = CrIaTransferFbfToGroundCreate(NULL); + + /** Check that the procedure is properly configured */ + if (FwPrCheck(prDesc) != prSuccess) { + printf("The procedure CrIaTransferFbfToGround is NOT properly configured ... FAILURE\n"); + return EXIT_FAILURE; + } + else { + printf("The procedure CrIaTransferFbfToGround is properly configured ... SUCCESS\n"); + } + + /** Start the procedure, and execute it */ + FwPrStart(prDesc); + // FwPrExecute(prDesc); + // FwPrExecute(prDesc); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/CrIa/src/CrIaPrSm/codeextract.sh b/CrIa/src/CrIaPrSm/codeextract.sh new file mode 100755 index 0000000000000000000000000000000000000000..6ce64a7fbbbd35583d221274fc3e55e0f2ea7aee --- /dev/null +++ b/CrIa/src/CrIaPrSm/codeextract.sh @@ -0,0 +1,22 @@ +#!/bin/bash + + +if [[ $# != 1 ]] +then + echo "please give Module name, e.g. CrIaPrepSci" + echo + echo "or clear all .h .c .txt files and do sth. like:" + echo 'for i in `ls | grep CrIa` ; do ./codeextract.sh $i ; done' + echo + exit +fi + +# copy the xx part from the procedure or sm +cat $1/$1.h | sed -e "s/$1_H_/$1Create_H_/" > $1Create.h +cat $1/$1.c | sed -e "s/$1\.h/$1Create.h/" -e "s/$1\.c/$1Create.c/" > $1Create.c + +# copy the functions from the pr or sm +cat $1/$1Main.c | sed -n -e "/int main(void)/q;p" | sed -e "s/$1\.h/$1Create.h/" -e "s/$1Main\.c/$1Func.c/" > $1Func.c +cat $1/$1Main.c | sed -e "1,/int main(void)/d" > $1Init.txt + + diff --git a/CrIa/src/CrIaPrSm/codeextraction.ods b/CrIa/src/CrIaPrSm/codeextraction.ods new file mode 100644 index 0000000000000000000000000000000000000000..8297e165445f95cdc9674cb39614592d85b3b3cf Binary files /dev/null and b/CrIa/src/CrIaPrSm/codeextraction.ods differ diff --git a/CrIa/src/CrIaSemEvents.c b/CrIa/src/CrIaSemEvents.c new file mode 100644 index 0000000000000000000000000000000000000000..7eef73e2360d837dd455e91c7062c2b91965f559 --- /dev/null +++ b/CrIa/src/CrIaSemEvents.c @@ -0,0 +1,91 @@ +/** + * @file CrIaSemEvents.c + * + * @author UVIE + * @date Created on: Nov 18 2015 + */ + +#include <CrIaSemEvents.h> + +unsigned char CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY_SET; +unsigned char CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY_SET; +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_SET; +unsigned char CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED_SET; +unsigned char CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_SET; +unsigned char CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET; +unsigned char CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_FPM_OFF_ONLY_PATTERN_SET; +unsigned char CRSEM_SERV5_EVENT_WAR_PACK_ENCODE_FAILURE_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_DMA_DATA_TRANSF_FAIL_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_DATA_BIAS_VOLT_WRONG_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_FEESCU_SYNC_FAIL_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_FEE_SCRIPT_ERROR_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_SCU_POWER_SWITCH_FAIL_SET; +unsigned char CRSEM_SERV5_EVENT_ERR_SPW_TIME_CODE_MISS_SET; + + +/** + * Clear all SEM event flags + */ +void CrIaClearSemEventFlags(void) +{ + CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY_SET = 0; + CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY_SET = 0; /* see Mantis 1178 */ + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_SET = 0; + CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED_SET = 0; + CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_SET = 0; + CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET = 0; /* see Mantis 1178 */ + CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL_SET = 0; + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT_SET = 0; + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_SET = 0; + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_SET = 0; + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG_SET = 0; + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG_SET = 0; + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG_SET = 0; + CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY_SET = 0; + CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH_SET = 0; + CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME_SET = 0; + CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD_SET = 0; + CRSEM_SERV5_EVENT_WAR_FPM_OFF_ONLY_PATTERN_SET = 0; + CRSEM_SERV5_EVENT_WAR_PACK_ENCODE_FAILURE_SET = 0; + CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR_SET = 0; + CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE_SET = 0; + CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT_SET = 0; + CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE_SET = 0; + CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR_SET = 0; + CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT_SET = 0; + CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG_SET = 0; + CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG_SET = 0; + CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED_SET = 0; + CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL_SET = 0; + CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL_SET = 0; + CRSEM_SERV5_EVENT_ERR_DMA_DATA_TRANSF_FAIL_SET = 0; + CRSEM_SERV5_EVENT_ERR_DATA_BIAS_VOLT_WRONG_SET = 0; + CRSEM_SERV5_EVENT_ERR_FEESCU_SYNC_FAIL_SET = 0; + CRSEM_SERV5_EVENT_ERR_FEE_SCRIPT_ERROR_SET = 0; + CRSEM_SERV5_EVENT_ERR_SCU_POWER_SWITCH_FAIL_SET = 0; + CRSEM_SERV5_EVENT_ERR_SPW_TIME_CODE_MISS_SET = 0; + + return; +} diff --git a/CrIa/src/CrIaSemEvents.h b/CrIa/src/CrIaSemEvents.h new file mode 100644 index 0000000000000000000000000000000000000000..895d534ab3f633d8233cb0e203566097440d25cd --- /dev/null +++ b/CrIa/src/CrIaSemEvents.h @@ -0,0 +1,64 @@ +/** + * @file CrIaSemEvents.h + * + * @author UVIE + * @date Created on: Nov 18 2015 + */ + +/** Make sure to include this header file only once */ +#ifndef CrIaSemEvents_H_ +#define CrIaSemEvents_H_ + +extern unsigned char CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY_SET; +extern unsigned char CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY_SET; +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_SET; +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_SET; /* needed for FdCheck SAFE Mode (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_FD_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STAB_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDWIN_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDFULL_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_DIAG_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED_SET; +extern unsigned char CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_SET; +extern unsigned char CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_FD_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET; +extern unsigned char CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_FD_SET; /* needed for FdCheck SEM Mode Time-Out (NOTE: should be not cleared here) */ +extern unsigned char CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_FPM_OFF_ONLY_PATTERN_SET; +extern unsigned char CRSEM_SERV5_EVENT_WAR_PACK_ENCODE_FAILURE_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_DMA_DATA_TRANSF_FAIL_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_DATA_BIAS_VOLT_WRONG_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_FEESCU_SYNC_FAIL_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_FEE_SCRIPT_ERROR_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_SCU_POWER_SWITCH_FAIL_SET; +extern unsigned char CRSEM_SERV5_EVENT_ERR_SPW_TIME_CODE_MISS_SET; + + +/** + * Clear all SEM event flags + */ +void CrIaClearSemEventFlags(void); + +#endif /* CrIaSemEvents_H_ */ diff --git a/CrIa/src/EngineeringAlgorithms.c b/CrIa/src/EngineeringAlgorithms.c new file mode 100644 index 0000000000000000000000000000000000000000..bb328646e907de630bb056a424843415088ede2b --- /dev/null +++ b/CrIa/src/EngineeringAlgorithms.c @@ -0,0 +1,875 @@ +/** +* @file EngineeringAlgorithms.c +* @ingroup EngineeringAlgorithms +* @author Roland Ottensamer (roland.ottensamer@univie.ac.at) +* @date May, 2017 +* +* @copyright +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* +* @defgroup EngineeringAlgorithms Engineering algorithms providing a centroid +* @ingroup EngineeringAlgorithms +* +* @brief Engineering algorithms are @ref Centroiding and @ref TargetAcquisition. They are used in different situations and provide a centroid packet to the spacecraft. +* +* +* ## Overview +* +* In CHEOPS, precise pointing information from the instrument telescope is used by the AOCS (Attitude and Orbital Control System). +* There are basically two different usage scenarios of that type of information. Number one is when a new star is to be observed. +* The spacecraft slews to the new target and starts guiding using its star trackers, but the target star may be off in the instrument field of view +* in the order of up to 100 arcseconds (in CHEOPS, 1" is about 1 pixel) due to thermoelastic deformations. For that reason the instrument has +* to tell the spacecraft the @ref Offset between the intended position (the @ref TargetLocation) and the actually measured position. +* In the described case, full CCD frames are acquired and the @TargetAcquisition algorithm is run to identify the target star and move it to +* the intedned location on the CCD. This activity, the "Acquisition", is the first part of a nominal science procedure. +* +* ### Centroiding +* +* As soon as the target star is stably positioned on the CCD, the science measurement can start. The science frames are no longer full CCD images, +* but smaller windows of ~200x200 pixels, which are centred on the @ref TargetLocation. In this case the @ref Centroiding algorithm is used. +* It is faster than the @ref TargetAcquisition and it provides a high precision measurement of the offset, but it has no identification capabilities. +* It assumes that the target is the brightest source in the ROI (region of interest, a small area around the @ref TargetLocation) and that consequently +* the centre of gravity measurement of that area is the location of the target star. @ref Centroiding is run whenever a new science image +* has been acquired. +* +* Assume that we are in nominal science and science windows are coming in. We also assume that the Centroiding algorithm has been enabled in the data pool +* and the corresponding top-level framework algorithm has been started. Then, the first service 21 packet of a new window from the @ref SEM will trigger a +* countdown for the @ref Centroiding to run. This counts in IASW cycles up to the phase of the centroiding algorithm. The transfer of a SEM window +* takes 1-2 IASW cycles, thus Centroiding should not run until the transfer is complete. This top-level control algorithm is described in the IASW Spec. +* As soon as the @ref Centroiding function is called, the order of events and steps is the following: +* +* 1. Several parameters are fetched from the data pool. +* - CENT_DIM_X and CENT_DIM_Y define the size of the ROI (default = 51x51) +* - CENT_CHECKS is a boolean to switch the validity checks of the algorithm on/off (default = 1) +* - CENT_MEDIANFILTER is a flag to switch the 2D median filter on the ROI on/off (default = 1) +* - TARGETLOCATIONX and ...Y are needed to center the ROI. (set by the StarMap command) +* - CE_SEMWINDOWPOSX and ...Y are needed to know where to cut out the ROI from (set by the @ref CrIaSemOperCcdFullEntry and @ref CrIaSemOperCcdWindowEntry functions). +* 2. The AUX buffer located in SRAM1 is released and the work buffers (for the ROI and the median filter) are allocated. +* Note that AUX buffer is only used by the EngineeringAlgorithms, which never run simultaneously. +* 3. the coordinates needed to crop the ROI from the image are calculated using the @ref getStartCoord function. +* 4. the ROI is copied accordingly from the @ref SIB. +* 5. the ROI is checked using @ref CheckRoiForStar. +* 6. the ROI is filtered using @ref MedFilter3x3. +* 7. the minimum pixel value is found in the ROI and subtracted from all pixels +* 8. @ref IntensityWeightedCenterOfGravity2D is called to calculate the center of gravity +* 9. @ref PrepareSibCentroid is called to copy the results into the data pool. +* +* The results are then picked up by the top-level centroiding algorithm in the framework and output via a Centroid packet. +*/ + + +#include "EngineeringAlgorithms.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "SdpAlgorithmsImplementation.h" +#include "SdpAlgorithmsImplementationLlc.h" /* for bits_used */ + +#ifndef GROUNDSW +#include <CrIaIasw.h> /* for sibAddressFull and Win */ +#include <CrIaPrSm/CrIaSdbCreate.h> /* for CONFIG_FULL etc. */ +#include "IfswDebug.h" +#endif + +#if (__sparc__) +#include <wrap_malloc.h> +#endif + +#include "IfswMath.h" /* for roundf */ + +#ifdef DEBUGFILES +/* used to save the intermediate debug images on PC */ +#include <stdio.h> /* for sprintf */ +#endif + +#ifdef PC_TARGET +unsigned int pc_roi[256*256]; +unsigned int pc_filtered[256*256]; +#include <stdio.h> +#endif + + +/** + * @brief get minimum and maximum value of an unsigned int buffer + * @param data array of input samples + * @param len number of samples + * @param min[out] calculated minimum + * @param max[out] calculated maximum + * + * @note If len is 0 then min = 0 and max = 0xffffffff. + */ + +void MinMaxU32 (unsigned int *data, unsigned int len, unsigned int *min, unsigned int *max) +{ + unsigned int i; + + *min = 0xffffffffu; + *max = 0x0u; + + for (i=0; i < len; i++) + { + *min = *min > data[i] ? data[i] : *min; + *max = *max < data[i] ? data[i] : *max; + } + + return; +} + + +/** + * @brief make basic checks on the ROI to predict the validity of the centroid + * + * Function to analyze an image and return a code carrying the validity of the centroid that will be calculated from this image. + * The image is binned to 3x3 pixels, then the following checks are carried out: + * + * 1. Check for constant image (is the minumum equal to the maximum?) + * 2. Check for a star (the mean must be larger than the median) + * 3. The star must be a distinct feature (the maximum should be larger than median + 2 sigma) + * 4. The range of values must be larger than a certain span + * 5. The sigma must be larger than a certain span + * + * @param data array of input samples + * @param xdim size in x + * @param ydim size in y + * + * @returns validity code of centroid + */ + +int CheckRoiForStar (unsigned int *data, unsigned int xdim, unsigned int ydim) +{ + unsigned int i; + unsigned int binned[9], median, minimum, maximum; + unsigned int binwidth, binheight, binx, biny, x, y, xstart, ystart; + float mean, sigma; + unsigned int CenSignalLimit, CenSigmaLimit; + + CrIaCopy(CEN_SIGNALLIMIT_ID, &CenSignalLimit); + CrIaCopy(CEN_SIGMALIMIT_ID, &CenSigmaLimit); + + if ((xdim >= 3) && (xdim >= 3)) /* 3x3 bins make no sense for images < 3x3 */ + { + binwidth = xdim / 3; + binheight = ydim / 3; + } + else + { + return (int)CEN_INV_INPUT; + } + + /* Note: For dimensions which are not divisible by 3, the remainder is ignored. + Example: in a 15 by 14 image each of the bins will sample 5 pixels in x * 4 pixels in y + and the rest is ignored */ + + /* clear the binned array first */ + for (i=0; i < 9; i++) + { + binned[i] = 0; + } + + /* bin to 3x3 */ + for (biny = 0; biny < 3; biny++) + { + for (y = 0; y < binheight; y++) + { + for (binx = 0; binx < 3; binx++) + { + for (x = 0; x < binwidth; x++) + { + xstart = x + binx*binwidth; + ystart = (y + biny*binheight) * xdim; + binned[binx + 3*biny] += data[xstart + ystart]; + } + } + } + } + + /* convert the sums to averages */ + for (i=0; i < 9; i++) + { + binned[i] /= (binwidth * binheight); + } + + MeanSigma ((int *)binned, 9, &mean, &sigma); + + median = Median ((int *)binned, 9); + + MinMaxU32 (binned, 9, &minimum, &maximum); + + /* DEBUGP("CEN: Mean %f Sig: %f Med: %u Min: %u Max: %u\n", mean, sigma, median, minimum, maximum); */ + + /* rule 1: the image must not be constant */ + if (minimum == maximum) + { + return (int)CEN_INV_TARGET; + } + + /* rule 2: there must be a star */ + if (mean < median) + { + return (int)CEN_INV_TARGET; + } + + /* rule 3: the star must be sharp */ + if ((median + 2*sigma) > maximum) + { + return (int)CEN_INV_SMEAR; + } + + /* rule 4: there must be a signal */ + if ((maximum - minimum) < CenSignalLimit) + { + return (int)CEN_INV_TARGET; + } + + /* rule 5: the sigma must be large */ + if (sigma < CenSigmaLimit) + { + return (int)CEN_INV_SMEAR; + } + + return 0; +} + + +/** + * @brief calculates the start coordinates of the ROI + * + * given the size of the input window, the SEM window offsets, + * the target location and the dimensions of the sub-window, + * the start coordinates of the sub-window are calculated. + * + * @param coord[inout] structure describing the input dimensions. Here the resulting start location coordinates are also entered. + * @returns 0 if the coordinates are plausible + * + * @note We have to convert between SEM local coordinates and IFSW coordinates here. Looking at the + * real use case, we only pass the image section (window) without margin, otherwise the coordinates must be modified before. + * It also means, that we always assume the conversion between IFSW (=I, used for the TargetLocation) + * and SEM local system L(X,Y) = (I(X,Y) – (50,50))*0.01 regardless of the SEM readout circuit (NOM/RED). + * (Originally, this was L(X,Y) = (I(X,Y) – (2850,50))*0.01, but this was changed upon request by the platform.) + * This is intended, because the platform does not care which circuit we use, so we always use the NOM offset. + * In case of doubt, consult the IFSW-SOC ICD, section 5.3.2 + * + * @warning Do not use on full frame dimensions which include margins (1076x1033) + */ + +int getStartCoord (struct Coordinates *coord) +{ + float TargetLocX, TargetLocY; + int StartLocX_L, StartLocY_L; + + /* convert the target location to L system assuming nominal margins */ + TargetLocX = (coord->TargetLocX_I - LTOI_X)*0.01f; + TargetLocY = (coord->TargetLocY_I - LTOI_Y)*0.01f; + + StartLocX_L = roundf(TargetLocX - 0.5f * coord->SubWinSizeX_L); + StartLocY_L = roundf(TargetLocY - 0.5f * coord->SubWinSizeY_L); + + /* The start loc from above assumes an (up to) 1024x1024 image. + We have to modify it by the actual SEM window position */ + StartLocX_L -= coord->SemWinPosX_L; + StartLocY_L -= coord->SemWinPosY_L; + + /* now check if the sub-window area is actually within the window */ + if (StartLocX_L < 0) + return -1; + if (StartLocY_L < 0) + return -2; + if ((StartLocX_L + coord->SubWinSizeX_L) > coord->SemWinSizeX_L) + return -3; + if ((StartLocY_L + coord->SubWinSizeY_L) > coord->SemWinSizeY_L) + return -4; + + /* enter the result */ + coord->StartLocationX_L = (unsigned int) StartLocX_L; + coord->StartLocationY_L = (unsigned int) StartLocY_L; + + return 0; +} + + +/** + * @brief get median of 9 unsigned ints, messing up the order of the input array + * @param data array of input samples + * + * @returns median of the 9 samples + */ + +unsigned int Med9USpoil (unsigned int *data) +{ + SWAP_SORTU (data[1], data[2]); + SWAP_SORTU (data[4], data[5]); + SWAP_SORTU (data[7], data[8]); + SWAP_SORTU (data[0], data[1]); + SWAP_SORTU (data[3], data[4]); + SWAP_SORTU (data[6], data[7]); + SWAP_SORTU (data[1], data[2]); + SWAP_SORTU (data[4], data[5]); + SWAP_SORTU (data[7], data[8]); + SWAP_SORTU (data[0], data[3]); + SWAP_SORTU (data[5], data[8]); + SWAP_SORTU (data[4], data[7]); + SWAP_SORTU (data[3], data[6]); + SWAP_SORTU (data[1], data[4]); + SWAP_SORTU (data[2], data[5]); + SWAP_SORTU (data[4], data[7]); + SWAP_SORTU (data[4], data[2]); + SWAP_SORTU (data[6], data[4]); + SWAP_SORTU (data[4], data[2]); + + return(data[4]); +} + + +/** + * @brief 3x3 median filter with threshold + * + * This algorithm takes an image as input and applies 2D median filtering. + * For each pixel which is not on one of the four borders, it takes a copy of the 3x3 sub-array + * and calculates the median. If the absolute difference between pixel value and calculated median + * is larger than the threshold, then the sample is replaced by the median. + * + * @param data array of input samples + * @param xdim size of image in x + * @param ydim size in y + * @param threshold the threshold value to compare against + * @param filtered the filtered output image + * + * @returns median of the 9 samples + */ + +int MedFilter3x3 (unsigned int *data, unsigned int xdim, unsigned int ydim, unsigned int threshold, unsigned int *filtered) +{ + unsigned int x, y, off; + unsigned int medwin[9]; + unsigned int pixval, median, diff; + + /* we start at 1,1 and run to xdim-1, ydim-1 so that a 1 pixel border is not processed */ + if (xdim < 3) + return -1; + if (ydim < 3) + return -1; + + for (y=1; y < (ydim-1); y++) + { + for (x=1; x < (xdim-1); x++) + { + /* first row */ + off = (y-1)*xdim; + medwin[0] = data[off + x-1]; + medwin[1] = data[off + x]; + medwin[2] = data[off + x+1]; + + /* last row */ + off = (y+1)*xdim; + medwin[6] = data[off + x-1]; + medwin[7] = data[off + x]; + medwin[8] = data[off + x+1]; + + /* middle row */ + off = y*xdim; + medwin[3] = data[off + x-1]; + pixval = data[off + x]; + medwin[4] = pixval; + medwin[5] = data[off + x+1]; + + median = Med9USpoil(medwin); + + if (pixval > median) + { + diff = pixval - median; + } + else + { + diff = median - pixval; + } + + if (diff > threshold) + { + filtered[off + x] = median; /* reuse off from middle row */ + } + else + { + filtered[off +x] = pixval; + } + } + } + + /* now copy the borders */ + for (x=0; x < xdim; x++) + { + filtered[x] = data[x]; + } + for (x=(ydim-1)*xdim; x < ydim*xdim; x++) + { + filtered[x] = data[x]; + } + for (y=1; y < (ydim-1); y++) + { + filtered[y*xdim] = data[y*xdim]; + filtered[y*xdim + (xdim-1)] = data[y*xdim + (xdim-1)]; + } + + return 0; +} + + +/** + * @brief Calculates Center of Gravity for a given 1d array in sub-element accuracy + * + * @param img a buffer holding the image + * @param rows the number of rows in the image + * @param cols the number of columns in the image + * @param[out] x x position + * @param[out] y y position + * + */ + +void CenterOfGravity2D (unsigned int *img, unsigned int rows, unsigned int cols, float *x, float *y) +{ + unsigned int i, j; + unsigned int tmp; /* was: double */ + + double pos; + double sum = 0.0; + + /* + start by iterating columns, i.e. contiguous sections of memory, + so the cache will be primed at least for small images for + the random access of rows afterwards. + Large images should be transposed beforehand, the overhead is a lot + smaller that a series of cache misses for every single datum. + */ + + /* for the y axis */ + pos = 0.0; + for (i = 0; i < rows; i++) + { + tmp = 0; + + for (j = 0; j < cols; j++) + tmp += GET_PIXEL(img, cols, j, i); + + pos += tmp * (i + 1); + sum += tmp; + } + + if (sum != 0.0) + (*y) = (float)(pos / sum) - 1.0f; + + /* for the x axis */ + pos = 0.0; + for (j = 0; j < cols; j++) + { + tmp = 0; + + for (i = 0; i < rows; i++) + tmp += GET_PIXEL(img, cols, j, i); /* yes, cols is correct */ + + pos += tmp * (j + 1); + } + + if (sum != 0.0) + (*x) = (float)(pos / sum) - 1.0f; + + return; +} + + +/** + * @brief Calculates Weighted Center of Gravity for a 2d image + * + * In this algorithm, the inner product of img and weights goes into the + * @ref CenterOfGravity2D algorithm. That algorithm sums up the pixel values in an unsigned int, + * so the data and the dimensions that we pass must account for that. Consequently, the range of + * values in our data array needs to be reduced if they are too large. For this purpose, the + * maximum value of the products is taken, its number of bits determined and checked against a user-define number + * (CogBits, default = 16). If that exceeds the CogBits, all pixels are right shifted to fit into the range of values. + * Remember, we will find the center of gravity (position) from that data set, so multiplicative factors can be ignored. + * + * @param img a buffer holding the image + * @param weights a buffer holding the weights + * @param rows the number of rows in the image + * @param cols the number of columns in the image + * @param[out] x x position + * @param[out] y y position + * + * @note It is fine to work in place, i.e. img and weights can be identical. + */ + +void WeightedCenterOfGravity2D (unsigned int *img, unsigned int *weights, unsigned int rows, unsigned int cols, float *x, float *y) +{ + unsigned int i; + unsigned int max = 0; + unsigned int bu; + unsigned int rsh = 0; + unsigned char CoGBits; + + CrIaCopy(COGBITS_ID, &CoGBits); + + for (i = 0; i < rows * cols; i++) + { + /* multiply image with weights */ + weights[i] *= img[i]; + + /* and find max value */ + max = weights[i] > max ? img[i] : max; + } + + /* determine size of datatype and shift so that it is back within CogBits (e.g. 16) bits */ + bu = bits_used(max); + if (bu > CoGBits) + { + rsh = bu - CoGBits; + /* and shift back to CoGBits bits datatype (no rounding) */ + for (i = 0; i < rows * cols; i++) + weights[i] >>= rsh; + } + + CenterOfGravity2D (weights, rows, cols, x, y); + + return; +} + + +/** + * @brief Calculates Intensity Weighted Center of Gravity for a 2d image + * + * In the IWCoG algorithm, the image is basically squared, before it goes into the @ref CenterOfGravity2D. + * This is achieved by calling @ref WeightedCenterOfGravity2D with img as data and weights parameter. + * + * @param img a buffer holding the image + * @param rows the number of rows in the image + * @param cols the number of columns in the image + * @param[out] x x position + * @param[out] y y position + * + */ + +void IntensityWeightedCenterOfGravity2D (unsigned int *img, unsigned int rows, unsigned int cols, float *x, float *y) +{ + /* the IWC just works on the square of the image */ + WeightedCenterOfGravity2D (img, img, rows, cols, x, y); + + return; +} + + +/** + * @brief enter centroid results in the Centroid of the SIB + * + * The results of e.g. @ref CenterOfGravity2D are written back into the @ref SIB. A SIB has a layout according + * to the @ref CrIaSib structure. Within that structure is a @ref SibHeader, which itself carries a @ref SibCentroid. + * We are writing the calculated offsets and validity there. + * + * @note This function uses CENT_OFFSET_X and CENT_MULT_X (and their counterparts in Y) to calculate the final result: + * OffsetX = (int) roundf(100.*(CentMultX*foffsetX + CentOffsetX)). This allows us to flip the axis and add a shift. + * + * @param Sib the SIB to use, which is the one used to calculate the Centroid + * @param validity the validity to enter + * @param foffsetX the offset in X to enter + * @param foffsetY the offset in Y to enter + * + */ + +void PrepareSibCentroid (struct CrIaSib *Sib, unsigned char validity, float foffsetX, float foffsetY) +{ + struct SibCentroid *Centroid; + struct SibHeader *Header; + + unsigned int TargetLocationX, TargetLocationY; + + unsigned short DataCadence; + unsigned int PImageRep; + unsigned int ExpCoarse, ExpFine; + + float CentMultX, CentMultY; /* float, can be used to invert the axis -1 */ + float CentOffsetX, CentOffsetY; + + int offsetX, offsetY; + + /* + The results are stored in the Centroid structure of the SIB header. + Pasting the values into the datapool is done one level up (in the CrIaCentAlgoFunc). + Several values can already be copied there, because they are independent of the + centroid calculation, such as the timestamps and the target location. + */ + + Header = (struct SibHeader *) Sib->Header; + Centroid = (struct SibCentroid *) Sib->Centroid; + + Centroid->startIntegCoarse = Header->startTimeCoarse; + Centroid->startIntegFine = Header->startTimeFine; + + ExpFine = Header->startTimeFine + (Header->ExposureTime * 65536) / 1000; + ExpCoarse = ExpFine / 65536; + ExpFine = ExpFine - 65536 * ExpCoarse; + Centroid->endIntegCoarse = Header->startTimeCoarse + ExpCoarse; + Centroid->endIntegFine = ExpFine; + + /* for the Data Cadence [centisec] we use the SEM Repetition Period [millisec]. */ + CrIaCopy (PIMAGEREP_ID, &PImageRep); + /* saturate at 600s */ + if (PImageRep > 600000) + { + PImageRep = 600000; + } + + DataCadence = PImageRep / 10; /* [ms] -> [cs] */ + Centroid->dataCadence = DataCadence; /* DataCadence is ushort */ + + CrIaCopy(TARGETLOCATIONX_ID, &TargetLocationX); + CrIaCopy(TARGETLOCATIONY_ID, &TargetLocationY); + + Centroid->targetLocX = TargetLocationX; + Centroid->targetLocY = TargetLocationY; + + /* Patch and copy the OFFSET values back to the SIB */ + CrIaCopy(CENT_OFFSET_X_ID, &CentOffsetX); + CrIaCopy(CENT_OFFSET_Y_ID, &CentOffsetY); + CrIaCopy(CENT_MULT_X_ID, &CentMultX); + CrIaCopy(CENT_MULT_Y_ID, &CentMultY); + + offsetX = (int) roundf(100.*(CentMultX*foffsetX + CentOffsetX)); + offsetY = (int) roundf(100.*(CentMultY*foffsetY + CentOffsetY)); + + Centroid->offsetX = offsetX; + Centroid->offsetY = offsetY; + + Centroid->validityStatus = validity; + + return; +} + + +/** + * @brief Centroid calculation for CHEOPS + * + * The @ref Centroiding algorithm takes a @ref SIB and calculate the offsets of the star to the @ref TargetLocation + * according to the results from an intensity-weighted centre of gravity calculation. The results are stored in the + * @ref SibCentroid structure within the @ref SibHeader of the @ref SIB. Whether the result is valid is stored in the + * @ref SibCentroid structure. + * + * @param Sib the SIB to use + * + */ + +void Centroiding (struct CrIaSib *Sib) +{ + struct Coordinates Coord; + struct SibHeader *sibHeader; + + unsigned int TargetLocationX, TargetLocationY; + unsigned short SemWinPosX, SemWinPosY; + + int status = 0; + int xstart, ystart; + float x, y, expected_x, expected_y, foffsetX, foffsetY; + + unsigned int *roi, *filtered; + unsigned int minimum; + unsigned int i; + + unsigned short CentDimX, CentDimY; + unsigned char CentMedianfilter, CentChecks, validity; + unsigned int CentMedianThrd; + + CrIaCopy(CENT_DIM_X_ID, &CentDimX); + CrIaCopy(CENT_DIM_Y_ID, &CentDimY); + CrIaCopy(CENT_CHECKS_ID, &CentChecks); + + CrIaCopy(CENT_MEDIANFILTER_ID, &CentMedianfilter); + + CrIaCopy(TARGETLOCATIONX_ID, &TargetLocationX); + CrIaCopy(TARGETLOCATIONY_ID, &TargetLocationY); + + sibHeader = (struct SibHeader *) Sib->Header; + + /* we set the validity to success before calculation */ + validity = CEN_VAL_WINDOW; + if (sibHeader->AcqType == ACQ_TYPE_FULL) + { + validity = CEN_VAL_FULL; + } + +#if (__sparc__) + /* first we release the AUX heap */ + release(AUX); + + /* then we allocate new areas for the work buffers */ + roi = (unsigned int *) alloc(CentDimX * CentDimY * 4, AUX); + filtered = (unsigned int *) alloc(CentDimX * CentDimY * 4, AUX); +#else + roi = pc_roi; + filtered = pc_filtered; +#endif + + /* use target location and sem offsets to calculate the ROI + the SEM window size is taken from the SIB, the POS is taken from the DP */ + + CrIaCopy(CE_SEMWINDOWPOSX_ID, &SemWinPosX); + CrIaCopy(CE_SEMWINDOWPOSY_ID, &SemWinPosY); + + Coord.TargetLocX_I = TargetLocationX; + Coord.TargetLocY_I = TargetLocationY; + Coord.SemWinSizeX_L = Sib->Xdim; + Coord.SemWinSizeY_L = Sib->Ydim; + Coord.SemWinPosX_L = (unsigned int) SemWinPosX; + Coord.SemWinPosY_L = (unsigned int) SemWinPosY; + Coord.SubWinSizeX_L = CentDimX; + Coord.SubWinSizeY_L = CentDimY; + Coord.StartLocationX_L = 0; + Coord.StartLocationY_L = 0; + + status = getStartCoord (&Coord); + + if (status != 0) + { + /* + We come here if the start coordinates could not be calculated. + In this case, we have to set the validity to invalid. + The x and y start coordinates do not matter much in this case, + because the CropCopy and the CoG are robust against stupid coordinates. + However, (0,0) is the safest. + */ + validity = CEN_INV_INPUT; + } + + xstart = Coord.StartLocationX_L; + ystart = Coord.StartLocationY_L; + + /* Mantis 2181: in FF mode adjust the xstart and ystart for the margin */ + if (sibHeader->AcqType == ACQ_TYPE_FULL) + { + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + xstart += RSM_XDIM; /* RED: 24 */ + } + else + { + xstart += LSM_XDIM; /* NOM: 28 */ + } + } + + status = CropCopyFromSibAndUnpack (Sib->Expos, Sib->Xdim, Sib->Ydim, CentDimX, CentDimY, xstart, ystart, roi); + + if (status != 0) + { + /* + Wrong dimensions. We come here most likely because the + given coordinates do not work with the SIB. + */ + validity = CEN_INV_INPUT; + } + + /* simple checks on image */ + status = 0; + if (CentChecks != 0) + { + status = CheckRoiForStar (roi, CentDimX, CentDimY); + } + + if (status != 0) + { + /* + If CheckRoiForStar returns an error, it does this + using the Centroid error codes, so we can pass it on. + */ + validity = (unsigned char)(status & 0xff); + } + +#ifdef DEBUGFILES + { + /* save fits file for debug purposes */ + static int roictr; + struct ScienceBuf myfile; + + myfile.xelements = CentDimX; + myfile.yelements = CentDimY; + myfile.zelements = 1; + myfile.nelements = CentDimX * CentDimY; + + /* ROI */ + myfile.data = (void *) roi; + sprintf (debugfilename, "!Debug_ROI%03u.fits", roictr); /* ! means overwrite */ + saveFitsImage (debugfilename, &myfile); + roictr++; + } +#endif + + /* optional median filter */ + if (CentMedianfilter == 1) + { + CrIaCopy(CEN_MEDIAN_THRD_ID, &CentMedianThrd); + /* create filtered image */ + status = MedFilter3x3 (roi, CentDimX, CentDimY, CentMedianThrd, filtered); + if (status == 0) + { + for (i=0; i < ((unsigned int)CentDimX * (unsigned int)CentDimY); i++) + roi[i] = filtered[i]; + } + } + +#ifdef DEBUGFILES + { + /* save fits file for debug purposes */ + static int medctr; + struct ScienceBuf myfile; + + myfile.xelements = CentDimX; + myfile.yelements = CentDimY; + myfile.zelements = 1; + myfile.nelements = CentDimX * CentDimY; + + /* ROI */ + myfile.data = (void *) roi; + sprintf (debugfilename, "!Debug_MED%03u.fits", medctr); /* ! means overwrite */ + saveFitsImage (debugfilename, &myfile); + medctr++; + } +#endif + + /* + calculate centroid + */ + + /* set initial positions */ + expected_x = 0.5f * CentDimX; + expected_y = 0.5f * CentDimY; + x = expected_x; + y = expected_y; + + /* remove background by subtracting the minimum */ + minimum = 0xffffffff; + + for (i=0; i < ((unsigned int)CentDimY * CentDimX); i++) + { + if (roi[i] < minimum) + { + minimum = roi[i]; + } + } + /* then subtract from roi */ + for (i=0; i < ((unsigned int)CentDimY * CentDimX); i++) + { + roi[i] -= minimum; + } + + /* call centroiding algorithm */ + IntensityWeightedCenterOfGravity2D (roi, CentDimY, CentDimX, &x, &y); + + foffsetX = expected_x - x; + foffsetY = expected_y - y; + + PrepareSibCentroid (Sib, validity, foffsetX, foffsetY); + + return; +} diff --git a/CrIa/src/EngineeringAlgorithms.h b/CrIa/src/EngineeringAlgorithms.h new file mode 100644 index 0000000000000000000000000000000000000000..76902211600d3b7fdef0c20014d46f4c7e6b0cca --- /dev/null +++ b/CrIa/src/EngineeringAlgorithms.h @@ -0,0 +1,67 @@ +/** + * + */ + +#ifndef ENGINEERINGALGORITHMS_H +#define ENGINEERINGALGORITHMS_H + +/* Includes */ +/* #include <CrFwConstants.h> */ +#include <stdint.h> + +#include "SdpBuffers.h" + +struct Coordinates { + unsigned int SemWinSizeX_L; + unsigned int SemWinSizeY_L; + unsigned int SemWinPosX_L; + unsigned int SemWinPosY_L; + unsigned int TargetLocX_I; + unsigned int TargetLocY_I; + unsigned int SubWinSizeX_L; + unsigned int SubWinSizeY_L; + unsigned int StartLocationX_L; + unsigned int StartLocationY_L; +} ; + +#define LTOI_X 50 /* was: 2850, but changed to 50 upon request by CASA */ +#define LTOI_Y 50 + +#define CEN_VAL_WINDOW 0 /* no error, CCD window mode */ +#define CEN_VAL_FULL 1 /* no error, full frame mode */ +#define CEN_INV_INPUT 0xFF /* invalid input data */ +#define CEN_INV_TARGET 0xFE /* invalid - no target */ +#define CEN_INV_SMEAR 0xFD /* invalid - too large smearing */ +#define CEN_INV_ALGO 0xFC /* invalid - algorithm fails */ +#define CEN_INV_SYNC 0xFB /* invalid - CIS-OBT not in sync */ + +#define SET_PIXEL(img,cols,x,y,val) { img[x + cols * y] = val; } +#define GET_PIXEL(img,cols,x,y) ( img[x + cols * y] ) + + +#define SWAP_SORTU(a,b) { if ((a) > (b)) { unsigned int temp = (a); (a) = (b); (b) = temp; } } + + + +void MinMaxU32 (unsigned int *data, unsigned int len, unsigned int *min, unsigned int *max); + +int CheckRoiForStar (unsigned int *data, unsigned int xdim, unsigned int ydim); + +int getStartCoord (struct Coordinates *coord); + +unsigned int Med9USpoil (unsigned int *data); + +int MedFilter3x3 (unsigned int *data, unsigned int xdim, unsigned int ydim, unsigned int threshold, unsigned int *filtered); + +void CenterOfGravity2D (unsigned int *img, unsigned int rows, unsigned int cols, float *x, float *y); + +void WeightedCenterOfGravity2D (unsigned int *img, unsigned int *weights, unsigned int rows, unsigned int cols, float *x, float *y); + +void IntensityWeightedCenterOfGravity2D (unsigned int *img, unsigned int rows, unsigned int cols, float *x, float *y); + +void PrepareSibCentroid (struct CrIaSib *Sib, unsigned char validity, float foffsetX, float foffsetY); + +void Centroiding (struct CrIaSib *Sib); + + +#endif /* ENGINEERINGALGORITHMS_H */ diff --git a/CrIa/src/IfswConversions.c b/CrIa/src/IfswConversions.c new file mode 100644 index 0000000000000000000000000000000000000000..5ac60c26be38527dcec6a9ecf7e7053920389c70 --- /dev/null +++ b/CrIa/src/IfswConversions.c @@ -0,0 +1,313 @@ +/** + * @file IfswConversions.c + * @ingroup CrIaIasw + * @authors C. Reimers, Institute for Astrophysics, 2017 + * @date December, 2017 + * + * @brief Implementation of conversion functions (RAW/ENGINEERING values) used by the IASW. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "IfswMath.h" +#include "IfswConversions.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* for fpga_dpu_get_rt_addr */ +#if (__sparc__) +#include <iwf_fpga.h> +#include <ibsw_interface.h> +#else +#define EQM_BOARD_NOM 0x00005000 +#define EQM_BOARD_RED 0x00006000 +#endif /* __sparc__ */ + + +/* + * Divider K_PSU as given in document CHEOPS-IFW-INST-UM-070, issue 1.1, 01.09.2017, page 37 + */ +float getDividerK_PSU(unsigned int voltId) +{ + float K; + + switch (voltId) + { + case SEM_P7V0_ID: + K = 4.0949f; + break; + case SEM_P5V0_ID: + K = 3.6239f; + break; + case SEM_N5V0_ID: + K = 3.6239f; + break; + case SEM_P15V_ID: + K = 7.68f; + break; + case SEM_P30V_ID: + K = 16.1094f; + break; + default: + K = 0.0f; + break; + } + + return K; +} + +/* + * Divider K_DPU as given in document CHEOPS-IFW-INST-UM-070, issue 1.1, 01.09.2017, page 37 + */ +float getDividerK_DPU(unsigned int voltId) +{ + float K; + + switch (voltId) + { + case ADC_P5V_ID: /* fallthrough */ + case ADC_N5V_ID: + K = -4.0f; + break; + case ADC_P3V3_ID: /* fallthrough */ + case ADC_P2V5_ID: /* fallthrough */ + case ADC_P1V8_ID: /* fallthrough */ + case ADC_PGND_ID: + K = -2.0f; + break; + default: + K = 0.0f; + break; + } + + return K; +} + + +/* + * Thermistor currents I_therm as given in document CHEOPS-IFW-INST-UM-070, issue 1.1, 01.09.2017, page 39 + */ +float getIthermFor(unsigned int thermId) +{ + float Itherm; + unsigned short dpuVer; + unsigned int boardId; + + /* Get DPU version (NOMINAL or REDUNDANT) */ +#if (__sparc__) + dpuVer = fpga_dpu_get_rt_addr(); + boardId = CrIbGetDpuBoardId(); +#else + dpuVer = 9; /* NOMINAL */ + boardId = 9; /* FM nom */ +#endif /* __sparc__ */ + + if ((boardId == EQM_BOARD_NOM) || (boardId == EQM_BOARD_RED)) + { + Itherm = 100.4; + } + else /* all other models use the FM values */ + { + if (dpuVer == 9) /* FM NOMINAL */ + { + switch (thermId) + { + case ADC_TEMPOH1A_ID: + CrIaCopy(OTA_TM1A_NOM_ID, &Itherm); + break; + case ADC_TEMPOH2A_ID: + CrIaCopy(OTA_TM2A_NOM_ID, &Itherm); + break; + case ADC_TEMPOH3A_ID: + CrIaCopy(OTA_TM3A_NOM_ID, &Itherm); + break; + case ADC_TEMPOH4A_ID: + CrIaCopy(OTA_TM4A_NOM_ID, &Itherm); + break; + case ADC_TEMPOH1B_ID: + CrIaCopy(OTA_TM1B_NOM_ID, &Itherm); + break; + case ADC_TEMPOH2B_ID: + CrIaCopy(OTA_TM2B_NOM_ID, &Itherm); + break; + case ADC_TEMPOH3B_ID: + CrIaCopy(OTA_TM3B_NOM_ID, &Itherm); + break; + case ADC_TEMPOH4B_ID: + CrIaCopy(OTA_TM4B_NOM_ID, &Itherm); + break; + default: + Itherm = 99.00; + break; + } + } + else if (dpuVer == 10) /* FM REDUNDANT */ + { + switch (thermId) + { + case ADC_TEMPOH1A_ID: + CrIaCopy(OTA_TM1A_RED_ID, &Itherm); + break; + case ADC_TEMPOH2A_ID: + CrIaCopy(OTA_TM2A_RED_ID, &Itherm); + break; + case ADC_TEMPOH3A_ID: + CrIaCopy(OTA_TM3A_RED_ID, &Itherm); + break; + case ADC_TEMPOH4A_ID: + CrIaCopy(OTA_TM4A_RED_ID, &Itherm); + break; + case ADC_TEMPOH1B_ID: + CrIaCopy(OTA_TM1B_RED_ID, &Itherm); + break; + case ADC_TEMPOH2B_ID: + CrIaCopy(OTA_TM2B_RED_ID, &Itherm); + break; + case ADC_TEMPOH3B_ID: + CrIaCopy(OTA_TM3B_RED_ID, &Itherm); + break; + case ADC_TEMPOH4B_ID: + CrIaCopy(OTA_TM4B_RED_ID, &Itherm); + break; + default: + Itherm = 99.00; + break; + } + } + else + { + Itherm = 99.00; + } + + } + + return Itherm*1e-6; +} + + +/** + * Convert voltage from raw values (ADC) of DPU to engineering values (Volt) + */ +float convertToVoltEngVal_DPU(short Volt_ADC, unsigned int voltId) +{ + float X, K_DPU; + + X = (float)Volt_ADC; + + K_DPU = getDividerK_DPU(voltId); + + return (X * 2.995f * K_DPU) / 8191.0f; +} + + +/** + * Convert voltage from raw values (ADC) of PSU to engineering values (Volt) + */ +float convertToVoltEngVal_PSU(short Volt_ADC, unsigned int voltId) +{ + float X, K_PSU, K_DPU = -2.0f; + + X = (float)Volt_ADC; + + K_PSU = getDividerK_PSU(voltId); + + return (X * 2.995f * K_PSU * K_DPU) / 8191.0f; +} + +/** + * Convert DPU temperature from raw values (ADC) to engineering values (K or degree C) + * @note used for ADC_TEMP1 + */ +float convertToTempEngVal_DPU(short Temp_ADC) +{ + float X, R, T; + float DPU_N5V = -5.0f; + float I_const = 5.519e-5; + float B = 3418.0f; + float R_ref = 10000.0f; + float T_ref = 298.15f; + + X = (float)Temp_ADC; + + /* Get ADC_N5V voltage from Data Pool and convert it to engineering values */ +#ifdef PC_TARGET + { + short DPU_N5V_RAW; + + CrIaCopy(ADC_N5V_RAW_ID, &DPU_N5V_RAW); + DPU_N5V = convertToVoltEngVal_DPU(DPU_N5V_RAW, ADC_N5V_ID); + CrIaPaste(ADC_N5V_ID, &DPU_N5V); + } +#else + CrIaCopy(ADC_N5V_ID, &DPU_N5V); +#endif + + /* Calculate value for resistor R */ + R = ((((-1)*(2.0f * X * 2.995f) / 8191.0f) - DPU_N5V) / I_const) - 18200.0f; + + /* Check, if R is too small */ + if (R < 998.413465f) + return 373.15f; + + /*DEBUGP("R = %f, R/R_ref = %f, log(R/R_ref) = %f\n", R, R/R_ref, ln(R/R_ref));*/ + + /* Calculate temperature T in Kelvin */ + T = 1 / ((1/B) * logf(R/R_ref) + (1/T_ref)); + + return T; /* in Kelvin */ +} + +/** + * Convert OTA temperature from raw values (ADC) to engineering values (K or degree C) + * @note used for ADC_TEMPOH1A ... ADC_TEMPOH4B + */ +float convertToTempEngVal(short Temp_ADC, unsigned int thermId) +{ + float X, R, T; + float DPU_N5V = -5.0f; + float I_therm; + float B = 3775.0f; + float R_ref = 2252.0f; + float T_ref = 298.15f; + + X = (float)Temp_ADC; + + /* Get ADC_N5V voltage from Data Pool and convert it to engineering values */ +#ifdef PC_TARGET + { + short DPU_N5V_RAW; + + CrIaCopy(ADC_N5V_RAW_ID, &DPU_N5V_RAW); + DPU_N5V = convertToVoltEngVal_DPU(DPU_N5V_RAW, ADC_N5V_ID); + CrIaPaste(ADC_N5V_ID, &DPU_N5V); + } +#else + CrIaCopy(ADC_N5V_ID, &DPU_N5V); +#endif + + /* Get current I_therm from specific thermistors */ + I_therm = getIthermFor(thermId); + + /* Calculate value for resistor R */ + R = ((((-1)*(2.0f * X * 2.995f) / 8191.0f) - DPU_N5V) / I_therm) - 10000.0f; + + /* Check, if R is too small */ + if (R < 176.750132f) + return 373.15f; + + /*DEBUGP("R = %f, R/R_ref = %f, log(R/R_ref) = %f\n", R, R/R_ref, ln(R/R_ref));*/ + + /* Calculate temperature T in Kelvin */ + T = 1 / ((1/B) * logf(R/R_ref) + (1/T_ref)); + + return T; /* in Kelvin */ +} diff --git a/CrIa/src/IfswConversions.h b/CrIa/src/IfswConversions.h new file mode 100644 index 0000000000000000000000000000000000000000..791a6e1055ee94127abd712d740fe4a715a4e7ee --- /dev/null +++ b/CrIa/src/IfswConversions.h @@ -0,0 +1,20 @@ +/** + * @file IfswConversions.h + */ + +#ifndef IFSWCONVERSIONS_H +#define IFSWCONVERSIONS_H + +#define CONVERT_KTODEGC -273.15f + + +float convertToVoltEngVal_DPU(short Volt_ADC, unsigned int voltId); + +float convertToVoltEngVal_PSU(short Volt_ADC, unsigned int voltId); + +float convertToTempEngVal_DPU(short Temp_ADC); + +float convertToTempEngVal(short Temp_ADC, unsigned int thermId); + + +#endif /* IFSWCONVERSIONS_H */ diff --git a/CrIa/src/IfswDebug.c b/CrIa/src/IfswDebug.c new file mode 100644 index 0000000000000000000000000000000000000000..8cf8ca951d2463cfb830b10132ee67d5cb900858 --- /dev/null +++ b/CrIa/src/IfswDebug.c @@ -0,0 +1,312 @@ +/** + * @file IfswDebug.c + */ + +#include "IfswDebug.h" + + +#if (__sparc__) + +/** + * @file xen_printf.c + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date November, 2013 + * @brief a printf function suitable for use in xentium programs + * @brief There are many like it, but this one is mine! + * @note the lack of a cross-processor locking mechanism obviously implies that x_printf and leon printf writes might interfere + * + * @version 0.0 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#include <io.h> + +#define TSE 0x2 +#define THE 0x4 + +volatile char *uart1_data = (char *) 0x80000100; +volatile unsigned int *uart1_stat = (unsigned int*) 0x80000104; +static unsigned int writelock; + +static void x_putchar(int c) +{ + + /* wait for last byte to be written */ + while (! ((*uart1_stat) & THE)); + (*uart1_data) = (0xff & c); + /* wait until byte is sent */ + while (! ((*uart1_stat) & TSE)); +} + +static void x_sprintc(int c, char **str) +{ + if (str) { + (**str) = c; + (*str)++; + } else { + x_putchar(c); + } +} + +static unsigned int prints(char **str, const char *p_string, const unsigned int pad_flag, unsigned int pad_width) +{ + unsigned int pad_char = ' '; + + unsigned int print_counter = 0; + unsigned int string_length = 0; + + const char *p_tmp; + + + if (pad_width != 0) { + + p_tmp = p_string; + + while (*p_tmp != 0) { + string_length++; + p_tmp++; + } + + if (string_length >= pad_width) + pad_width = 0; + else + pad_width -= string_length; + + if (pad_flag & PAD_ZERO) + pad_char = '0'; + } + + if (!(pad_flag & PAD_RIGHT)) { + + while(pad_width > 0) { + x_sprintc(pad_char, str); + pad_width--; + print_counter++; + } + } + + while (*p_string != 0) { + x_sprintc(*p_string, str); + print_counter++; + p_string++; + } + + while (pad_width > 0) { + x_sprintc(pad_char, str); + print_counter++; + pad_width--; + } + + return print_counter; +} + + +#define FIELDSIZE 12 /* fits sign + 32 bit int as char + '\0' */ + +static int printi(char **str, int input, int base, int sign, + const unsigned int pad_flag, unsigned int pad_width, + int base_letter) +{ + int digit; + unsigned int print_counter = 0; + unsigned int unsigned_input = input; + + + char *p_buffer; + char char_buffer[FIELDSIZE]; + + + /* the integer is zero */ + if(!input) { + char_buffer[0] = '0'; + char_buffer[1] = '\0'; + return prints(str, char_buffer, pad_flag, pad_width); + } + + /* point to end of buffer and terminate string */ + p_buffer = char_buffer + FIELDSIZE-1; + *p_buffer = '\0'; + + + /* signed AND negative? */ + if (sign && (base == 10) && (input < 0)) { + unsigned_input = -input; + } + + /* shift throught digits and convert to ascii */ + while (unsigned_input) { + p_buffer--; + digit = unsigned_input % base; + (*p_buffer) = digit + (digit < 10 ? '0' : base_letter - 10); + unsigned_input /= base; + } + + if (sign && (input < 0)) { + if (pad_width && (pad_flag & PAD_ZERO)) { + x_sprintc('-', str); + print_counter++; + pad_width--; + } else { + p_buffer--; + (*p_buffer) = '-'; + } + } + + return print_counter + prints(str, p_buffer, pad_flag, pad_width); +} + +static int print(char **str, const char *format, va_list args ) +{ + unsigned int pad_width; + unsigned int pad_flag; + unsigned int print_counter = 0; + + char fmt; + char *p_tmp; + char tmp[2]; + + /* parse format string */ + while ((fmt=*(format++))) { + + /* normal character */ + if (fmt != '%') { + if(fmt == 0xa) + x_sprintc(0xd, str); + x_sprintc(fmt, str); + print_counter++; + } else { + /* format specifier found */ + + fmt = *(format++); + pad_width = pad_flag = 0; + + /* string terminated */ + if (fmt == '\0') + break; + + /* percent sign escaped */ + if (fmt == '%') { + x_sprintc(fmt, str); + print_counter++; + continue; + } + + if(fmt == '-') { + pad_flag = PAD_RIGHT; + fmt = *(format++); + } + + while (fmt == '0') { + pad_flag |= PAD_ZERO; + fmt = *(format++); + } + + while ((fmt >= '0') && (fmt <= '9')) { + pad_width *= 10; + pad_width += fmt - '0'; + fmt = *(format++); + } + + switch (fmt) { + + case 's' : + p_tmp = va_arg(args, char *); + print_counter += prints(str, p_tmp ? p_tmp :"(null)", pad_flag, pad_width); + break; + + case 'd' : + print_counter += printi(str, va_arg(args, int), 10, 1, pad_flag, pad_width, 'a'); + break; + + case 'x': + print_counter += printi(str, va_arg(args, int), 0x10, 0, pad_flag, pad_width, 'a'); + break; + + case 'X': + print_counter += printi(str, va_arg(args, int), 0x10, 0, pad_flag, pad_width, 'A'); + break; + + case 'u': + print_counter += printi(str, va_arg(args, int), 10, 0, pad_flag, pad_width, 'a'); + break; + + case 'c': + tmp[0] = (char) va_arg(args, int); + tmp[1] = '\0'; + print_counter += prints(str, tmp, pad_flag, pad_width); + break; + default: + /* ignore all invalid */ + break; + + } + } + } + + if (str != 0) + **str = '\0'; + + va_end(args); + + return print_counter; +} + + +/** + * @brief 'man printf' (mostly) + */ + +int x_printf(const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( 0, format, args ); +} + +#define PRINT_TIMEOUT 1000000 + +int l_printf(const char *format, ...) +{ + va_list args; + int retval = 0; + volatile unsigned int timeout = 0; + + for (timeout = 0; (ioread32be(&writelock) != 0) && (timeout < PRINT_TIMEOUT); timeout++); + + if (ioread32be(&writelock) == 0) + { + iowrite32be(1, &writelock); + va_start( args, format ); + retval = print( 0, format, args ); + iowrite32be(0, &writelock); + } + + return retval; +} + + +/** + * @brief 'man sprintf' (mostly) + */ + +int x_sprintf(char *str, const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( &str, format, args ); +} + +#endif /* sparc */ diff --git a/CrIa/src/IfswDebug.h b/CrIa/src/IfswDebug.h new file mode 100644 index 0000000000000000000000000000000000000000..99f02b2961773efae90e9a8f851eae3f32957ddf --- /dev/null +++ b/CrIa/src/IfswDebug.h @@ -0,0 +1,61 @@ +/** + * @file IfswDebug.h + */ + +#ifndef IFSWDEBUG_H +#define IFSWDEBUG_H + +#if (__sparc__) + +#include <stdarg.h> + +#define PAD_RIGHT 0x1 +#define PAD_ZERO 0x2 + + +int x_printf(const char *format, ...); +int l_printf(const char *format, ...); +int x_sprintf(char *str, const char *format, ...); + +#else +#include <stdio.h> +#define x_printf printf +#define l_printf printf +#endif /* __sparc__ */ + +#ifdef DEBUG +/* #define DEBUGP(...) l_printf(__VA_ARGS__) */ +#define DEBUGP l_printf +#else +/* void DEBUGP(__attribute__ ((unused)) char *a, ...); */ +#define DEBUGP {}if(0)l_printf +#endif /* DEBUG */ + +#ifdef PR_DEBUG +#define PRDEBUGP l_printf +#else +#define PRDEBUGP {}if(0)l_printf +#endif /* PR_DEBUG */ + +#ifdef MP_DEBUG +#define MPDEBUGP l_printf +#else +#define MPDEBUGP {}if(0)l_printf +#endif /* MP_DEBUG */ + +#ifdef ERR_DEBUG +#define ERRDEBUGP l_printf +#else +#define ERRDEBUGP {}if(0)l_printf +#endif /* ERR_DEBUG */ + +#ifdef SD_DEBUG +#define SDDEBUGP l_printf +#else +#define SDDEBUGP {}if(0)l_printf +#endif /* SD_DEBUG */ + + +#endif /* IFSWDEBUG_H */ + + diff --git a/CrIa/src/IfswMath.c b/CrIa/src/IfswMath.c new file mode 100644 index 0000000000000000000000000000000000000000..c54703a0b6dff1d011e0b0c9f0998a2f22f4c60f --- /dev/null +++ b/CrIa/src/IfswMath.c @@ -0,0 +1,317 @@ +#include "IfswMath.h" + + +#if (__sparc__) + +/** + * @brief calculate the square root of a single precision float using the processor-built-in instruction + * @param x the radicand + * @returns the principal square root + */ + +float fsqrts(float x) +{ + float y; + __asm__("fsqrts %1, %0 \n\t" + : "=f" (y) + : "f" (x)); + return y; +} + + +/** + * @brief calculate the square root of a double precision float using the processor-built-in instruction + * @param x the radicand + * @returns the principal square root + */ + +double fsqrtd(double x) +{ + double y; + __asm__("fsqrtd %1, %0 \n\t" + : "=f" (y) + : "f" (x)); + return y; +} + +/* + from newlib/libm/common/sf_round.c + + NOTE: this funny implementation does not make use of the sign bit, but works with signed data +*/ + +float roundf(float x) +{ + int w; + /* Most significant word, least significant word. */ + int exponent_less_127; + + GET_FLOAT_WORD(w, x); + + /* Extract exponent field. */ + exponent_less_127 = ((w & 0x7f800000) >> 23) - 127; + + if (exponent_less_127 < 23) + { + if (exponent_less_127 < 0) + { + w &= 0x80000000; + if (exponent_less_127 == -1) + /* Result is +1.0 or -1.0. */ + w |= (127 << 23); + } + else + { + unsigned int exponent_mask = 0x007fffff >> exponent_less_127; + if ((w & exponent_mask) == 0) + /* x has an integral value. */ + return x; + + w += 0x00400000 >> exponent_less_127; + w &= ~exponent_mask; + } + } + else + { + if (exponent_less_127 == 128) + /* x is NaN or infinite. */ + return x + x; + else + return x; + } + + SET_FLOAT_WORD(x, w); + return x; +} + + + + +/* from newlib sf_numtest.c */ +int numtestf (float x) +{ + int wx; /* was: __int32_t wx; */ + int exp; + + GET_FLOAT_WORD (wx, x); + + exp = (wx & 0x7f800000) >> 23; + + /* Check for a zero input. */ + if (x == 0.0) + { + return (0); + } + + /* Check for not a number or infinity. */ + if (exp == 0x7f8) + { + if(wx & 0x7fffff) + return (NAN); + else + return (INF); + } + + /* Otherwise it's a finite value. */ + else + return (NUM); +} + + +/* from newlib sf_fabs.c */ +float fabsf (float x) +{ + switch (numtestf (x)) + { + case NAN: + /* errno = EDOM; */ /* no ERRNO support */ + return (x); + case INF: + /* errno = ERANGE; */ /* no ERRNO support */ + return (x); + case 0: + return (0.0); + default: + return (x < 0.0 ? -x : x); + } +} + + +/* from newlib mathcnst.h */ +float z_rooteps_f = 1.7263349182589107e-4; +ufloat z_infinity_f = { 0x7f800000 }; +ufloat z_notanum_f = { 0xffd00000 }; + + +/* from newlib sf_asine.c */ +static const float p[] = { 0.933935835, -0.504400557 }; +static const float q[] = { 0.560363004e+1, -0.554846723e+1 }; +static const float a[] = { 0.0, 0.785398163 }; +static const float b[] = { 1.570796326, 0.785398163 }; + +float asinef (float x, int acosine) +{ + int flag, i; + int branch = 0; + float g, res, R, P, Q, y; + + /* Check for special values. */ + i = numtestf (x); + if (i == NAN || i == INF) + { + /* errno = EDOM; */ /* no ERRNO support */ + if (i == NAN) + return (x); + else + return (z_infinity_f.f); + } + + y = fabsf (x); + flag = acosine; + + g = y * y; /* added to calm compiler */ + res = y; /* added to calm compiler */ + + if (y > 0.5) + { + i = 1 - flag; + + /* Check for range error. */ + if (y > 1.0) + { + /* errno = ERANGE; */ /* no ERRNO support */ + return (z_notanum_f.f); + } + + g = (1 - y) / 2.0; + y = -2 * fsqrts (g); + branch = 1; + } + else + { + i = flag; + if (y < z_rooteps_f) + res = y; + else + g = y * y; + } + + if (y >= z_rooteps_f || branch == 1) + { + /* Calculate the Taylor series. */ + P = (p[1] * g + p[0]) * g; + Q = (g + q[1]) * g + q[0]; + R = P / Q; + + res = y + y * R; + } + + /* Calculate asine or acose. */ + if (flag == 0) + { + res = (a[i] + res) + a[i]; + if (x < 0.0) + res = -res; + } + else + { + if (x < 0.0) + res = (b[i] + res) + b[i]; + else + res = (a[i] - res) + a[i]; + } + + return (res); +} + + + +float acosf (float x) +{ + return asinef (x, 1); +} + + + +static const float la[] = { -0.5527074855 }; +static const float lb[] = { -0.6632718214e+1 }; +static const float lC1 = 0.693145752; +static const float lC2 = 1.428606820e-06; +static const float lC3 = 0.4342944819; + +float logarithmf (float x, int ten) +{ + int N; + float f, w, z; + + /* Check for domain error here. */ + if (x <= 0.0) + { + /* errno = ERANGE; */ /* no ERRNO support */ + return (z_notanum_f.f); + } + + /* Get the exponent and mantissa where x = f * 2^N. */ + f = frexpf (x, &N); + + z = f - 0.5; + + if (f > __SQRT_HALF) + z = (z - 0.5) / (f * 0.5 + 0.5); + else + { + N--; + z /= (z * 0.5 + 0.5); + } + w = z * z; + + /* Use Newton's method with 4 terms. */ + z += z * w * (la[0]) / ((w + 1.0) * w + lb[0]); + + if (N != 0) + z = (N * lC2 + z) + N * lC1; + + if (ten) + z *= lC3; + + return (z); +} + + +float logf (float x) +{ + return logarithmf (x, 0); +} + + +float frexpf (float d, int *exp) +{ + float f; + int wf, wd; + + GET_FLOAT_WORD (wd, d); + + /* Get the exponent. */ + *exp = ((wd & 0x7f800000) >> 23) - 126; + + /* Get the mantissa. */ + wf = wd & 0x7fffff; + wf |= 0x3f000000; + + SET_FLOAT_WORD (f, wf); + + /* Check for special values. */ + switch (numtestf (f)) + { + case NAN: + case INF: + /* errno = EDOM; */ /* no ERRNO support */ + *exp = 0; + return (f); + } + + return (f); +} + + +#endif diff --git a/CrIa/src/IfswMath.h b/CrIa/src/IfswMath.h new file mode 100644 index 0000000000000000000000000000000000000000..f62bec5d88270fdf44abe2fc4295800521a49e93 --- /dev/null +++ b/CrIa/src/IfswMath.h @@ -0,0 +1,91 @@ +/** + * + */ + +#ifndef IFSWMATH_H +#define IFSWMATH_H + + +#if !(__sparc__) +#include <math.h> +#endif + + + +#if (__sparc__) + +/* + from newlib/libc/sys/linux/cmath/math_private.h +*/ + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + unsigned int word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + + + +/* from newlib zmath.h */ +#define NUM 3 +#define NAN 2 +#define INF 1 +#define __SQRT_HALF 0.70710678118654752440 + +typedef const union +{ + long l; + float f; +} ufloat; + + +float fsqrts(float x); + +double fsqrtd(double x); + +float roundf(float x); + +int numtestf (float x); + +float fabsf (float x); + +float asinef (float x, int acosine); + +float acosf (float x); + +float logarithmf (float x, int ten); + +float logf (float x); + +float frexpf (float d, int *exp); + +#else +#include <math.h> +#define fsqrts(f) ((float)sqrt(f)) +#define fsqrtd(lf) sqrt(lf) +#define fln(f) logf(f) +#endif + + +#endif /* IFSWMATH_H */ diff --git a/CrIa/src/IfswUtilities.c b/CrIa/src/IfswUtilities.c new file mode 100644 index 0000000000000000000000000000000000000000..1b4cc7f8dfda80e284c838480b03be1102c96946 --- /dev/null +++ b/CrIa/src/IfswUtilities.c @@ -0,0 +1,1197 @@ +/** + * @file IfswUtilities.c + * @ingroup CrIaIasw + * @authors R. Ottensamer and C. Reimers, Institute for Astrophysics, 2015-2016 + * @date September, 2016 + * + * @brief Implementation of utility functions used by the IASW. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "IfswDebug.h" +#include "IfswMath.h" +#include "IfswUtilities.h" +#include "IfswConversions.h" + +#include "CrIaIasw.h" +#include "CrFwCmpData.h" + +#include <Pckt/CrFwPckt.h> +#include <OutFactory/CrFwOutFactory.h> +#include <OutCmp/CrFwOutCmp.h> +#include <OutLoader/CrFwOutLoader.h> +#include <CrIaPckt.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrSemConstants.h> +#include <FwProfile/FwSmConfig.h> + +#include <byteorder.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaSemCreate.h> + +/* for fpga_dpu_get_rt_addr */ +#if (__sparc__) +#include <iwf_fpga.h> +#endif /* __sparc__ */ + +/* for verifyAddress */ +#if (__sparc__) +#include <wrap_malloc.h> +#else +unsigned int dummyram[1024*8]; +#define SRAM1_ADDR ((unsigned int) dummyram) +#define SRAM1_SIZE 0x0 +#define SRAM2_ADDR (((unsigned int)dummyram)+SRAM1_SIZE) +#define SRAM2_SIZE 0x0 +#define AHBRAM_ADDR (((unsigned int)dummyram)+SRAM2_SIZE) +#define AHBRAM_SIZE 0x0 +#define FPGA_ADDR (((unsigned int)dummyram)+AHBRAM_SIZE) +#define FPGA_SIZE 0x0 +#define REG1_ADDR (((unsigned int)dummyram)+FPGA_SIZE) +#define REG1_SIZE 0x0 +#define REG2_ADDR (((unsigned int)dummyram)+REG1_SIZE) +#define REG2_SIZE 0x0 +#define SRAM1_FLASH_ADDR 0 +#endif /* __sparc__ */ + + + +#define SWAPABFLOAT(A,B) { if (A > B) { float swaptmp = A; A = B; B = swaptmp; } } + +/* NOTE: The caller must make sure that the passed array contains 4 floats */ +void sort4float (float *data) +{ + SWAPABFLOAT(data[0], data[1]); + SWAPABFLOAT(data[2], data[3]); + SWAPABFLOAT(data[0], data[2]); + SWAPABFLOAT(data[1], data[3]); + SWAPABFLOAT(data[1], data[2]); + return; +} + + +int LTblInit; /* set in CrIaInit to 0 */ +CrIaPcktCrc_t LTbl[256]; + +CrFwBool_t GetCalculatedCrcFrom(CrFwPckt_t pckt) +{ + CrIaPcktCrc_t CrcCheck; + CrFwPcktLength_t len, i; + + /* Calculate CRC from packet */ + CrcCheck = 0xFFFF; + if (!LTblInit) + { + InitLtbl(LTbl); + LTblInit = 1; + } + len = CrFwPcktGetLength(pckt) - sizeof(CrIaPcktCrc_t); + for (i=0; i<len; ++i) + { + CrcCheck = Crc(pckt[i], CrcCheck, LTbl); + } + CrcCheck = be16_to_cpu(CrcCheck); + + DEBUGP("CRC calculated from package: %d \n", CrcCheck); + + return CrcCheck; +} + +/* wrappers for Mantis 1870 */ +unsigned char heater_stat[4] = {0,0,0,0}; + +/* Mantis 2107: patch the assignment of heaters */ +unsigned char PatchHtr[4] = {HEATER_3,HEATER_4,HEATER_1,HEATER_2}; + +void CrIaHeaterOn (enum heater htr) +{ + heater_stat[htr] = 1; + + fpga_heater_on(PatchHtr[htr]); +} + +void CrIaHeaterOff (enum heater htr) +{ + heater_stat[htr] = 0; + + fpga_heater_off(PatchHtr[htr]); +} + +unsigned char CrIaHeaterStatus (enum heater htr) +{ + /* NOTE: this function reports the software state, not the true hardware state */ + return heater_stat[htr]; +} + + +unsigned char getHbSem() +{ + unsigned char hbSem = 1; + unsigned short smState; + unsigned short smOperState; + + smOperState = FwSmGetCurStateEmb(smDescSem); + smState = FwSmGetCurState(smDescSem); + + if (smState == CrIaSem_OPER) + { + if (smOperState != CrIaSem_STANDBY) + hbSem = 0; + } + + return hbSem; +} + + +void PutBit8 (unsigned char value, unsigned int bitOffset, unsigned char *dest) +{ + unsigned int bytepos, bitpos; + unsigned char destval, mask; + + bytepos = bitOffset >> 3; /* division by 8 */ + bitpos = bitOffset - 8*bytepos; + + /* shape a mask with the required bit set true */ + mask = 1 << (7-bitpos); + + /* get the destination byte and clear the bit */ + destval = dest[bytepos]; + destval &= ~mask; + + /* set bit if the value was true */ + if (value) + destval |= mask; + + /* write it back */ + dest[bytepos] = destval; + + return; +} + +/* NOTE: this is very slow. better use PutNBits32 */ +void PutNBits8 (unsigned int value, unsigned int bitOffset, unsigned int nbits, unsigned char *dest) +{ + unsigned int i; + unsigned char bitvalue; + + for (i=0; i<nbits; i++) + { + bitvalue = (unsigned char)((value >> (nbits - 1 - i)) & 1); + PutBit8 (bitvalue, bitOffset + i, dest); + } + + return; +} + + +unsigned int getHkDataSize (unsigned char sid) +{ + unsigned char rdlSid, rdlSlot; + unsigned int rdlListId; + unsigned short RdlDataItemList[250]; + unsigned int i, hkPacketSize; + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* sid not found in list */ + if (rdlSlot == RDL_SIZE) + { + DEBUGP("SID %d not found!\n", sid); + return 0; + } + + /* get the data pool handle of the list */ + switch (rdlSlot) + { + case 0: + rdlListId = RDLDATAITEMLIST_0_ID; + break; + case 1: + rdlListId = RDLDATAITEMLIST_1_ID; + break; + case 2: + rdlListId = RDLDATAITEMLIST_2_ID; + break; + case 3: + rdlListId = RDLDATAITEMLIST_3_ID; + break; + case 4: + rdlListId = RDLDATAITEMLIST_4_ID; + break; + case 5: + rdlListId = RDLDATAITEMLIST_5_ID; + break; + case 6: + rdlListId = RDLDATAITEMLIST_6_ID; + break; + case 7: + rdlListId = RDLDATAITEMLIST_7_ID; + break; + case 8: + rdlListId = RDLDATAITEMLIST_8_ID; + break; + case 9: + rdlListId = RDLDATAITEMLIST_9_ID; + break; + default : + /* cannot be reached, because we have only 10 RDLs */ + return 0; + } + + /* get list */ + CrIaCopy(rdlListId, RdlDataItemList); + + /* add up size of that list items */ + hkPacketSize = OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1 + 2; /* PUS header, SID and CRC */ + + for (i=0; i < RD_MAX_ITEMS; i++) + { + if (RdlDataItemList[i] == 0) + break; + + hkPacketSize += (GetDataPoolMult((unsigned int)RdlDataItemList[i]) * GetDataPoolSize((unsigned int)RdlDataItemList[i])); + } + + return hkPacketSize; +} + + +unsigned short getSemAnoEvtId(unsigned short eventId) +{ + switch (eventId) + { + case CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT: /* 42204 */ + return 1; + case CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE: /* 42205 */ + return 2; + case CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG: /* 42206 */ + return 3; + case CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG: /* 42207 */ + return 4; + case CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG: /* 42208 */ + return 5; + case CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG: /* 42209 */ + return 6; + case CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY: /* 42214 */ + return 7; + case CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH: /* 42215 */ + return 8; + case CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME: /* 42216 */ + return 9; + case CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD: /* 42217 */ + return 10; + case CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR: /* 43800 */ + return 11; + case CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE: /* 43801 */ + return 12; + case CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT: /* 43802 */ + return 13; + case CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE: /* 43813 */ + return 14; + case CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR: /* 43814 */ + return 15; + case CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT: /* 43815 */ + return 16; + case CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG: /* 43816 */ + return 17; + case CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG: /* 43817 */ + return 18; + case CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED: /* 43818 */ + return 19; + case CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL: /* 43819 */ + return 20; + case CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL: /* 43820 */ + return 21; + case CRSEM_SERV5_EVT_ERR_DAT_DMA: /* 43821 */ + return 22; + case CRSEM_SERV5_EVT_WAR_PATTER: /* 42218 */ + return 23; + case CRSEM_SERV5_EVT_WAR_PACKWR: /* 42219 */ + return 24; + case CRSEM_SERV5_EVT_ERR_BIAS_SET: /* 43822 */ + return 25; + case CRSEM_SERV5_EVT_ERR_SYNC: /* 43823 */ + return 26; + case CRSEM_SERV5_EVT_ERR_SCRIPT: /* 43824 */ + return 27; + case CRSEM_SERV5_EVT_ERR_PWR: /* 43825 */ + return 28; + case CRSEM_SERV5_EVT_ERR_SPW_TC: /* 43826 */ + return 29; + default: + DEBUGP("ERR: Event %d has not been in the list, using 0!\n", eventId); + break; + } + + return 0; /* all unknown events have index 0 */ +} + + +unsigned short checkDpuHkLimits() +{ + float lowerLimitFloat, upperLimitFloat; + float valueFloat; + short valueShort; + unsigned short limitCnt = 0; + unsigned short evt_data[2]; + + /* get ADC_P3V3 limit */ + CrIaCopy(ADC_P3V3_U_ID, &upperLimitFloat); + /* get ADC_P3V3 value */ + CrIaCopy(ADC_P3V3_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_P3V3_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_P5V limit */ + CrIaCopy(ADC_P5V_U_ID, &upperLimitFloat); + /* get ADC_P5V value */ + CrIaCopy(ADC_P5V_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_P5V_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_P1V8 limit */ + CrIaCopy(ADC_P1V8_U_ID, &upperLimitFloat); + /* get ADC_P1V8 value */ + CrIaCopy(ADC_P1V8_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_P1V8_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_P2V5 limit */ + CrIaCopy(ADC_P2V5_U_ID, &upperLimitFloat); + /* get ADC_P2V5 value */ + CrIaCopy(ADC_P2V5_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_P2V5_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_N5V limit */ + CrIaCopy(ADC_N5V_L_ID, &lowerLimitFloat); + /* get ADC_N5V value */ + CrIaCopy(ADC_N5V_ID, &valueFloat); + if (valueFloat < lowerLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_N5V_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_PGND limits */ + CrIaCopy(ADC_PGND_U_ID, &upperLimitFloat); + /* Mantis 2206: Missing Lower Limit Check for ADC_PGND */ + CrIaCopy(ADC_PGND_L_ID, &lowerLimitFloat); + /* get ADC_PGND value */ + CrIaCopy(ADC_PGND_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_PGND_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + if (valueFloat < lowerLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_PGND_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH1A limit */ + CrIaCopy(ADC_TEMPOH1A_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH1A value */ + CrIaCopy(ADC_TEMPOH1A_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH1A_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH1A_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMP1 limit */ + CrIaCopy(ADC_TEMP1_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMP1 value */ + CrIaCopy(ADC_TEMP1_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal_DPU(valueShort) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMP1_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH2A limit */ + CrIaCopy(ADC_TEMPOH2A_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH2A value */ + CrIaCopy(ADC_TEMPOH2A_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH2A_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH2A_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH1B limit */ + CrIaCopy(ADC_TEMPOH1B_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH1B value */ + CrIaCopy(ADC_TEMPOH1B_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH1B_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH1B_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH3A limit */ + CrIaCopy(ADC_TEMPOH3A_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH3A value */ + CrIaCopy(ADC_TEMPOH3A_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH3A_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH3A_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH2B limit */ + CrIaCopy(ADC_TEMPOH2B_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH2B value */ + CrIaCopy(ADC_TEMPOH2B_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH2B_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH2B_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH4A limit */ + CrIaCopy(ADC_TEMPOH4A_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH4A value */ + CrIaCopy(ADC_TEMPOH4A_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH4A_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH4A_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH3B limit */ + CrIaCopy(ADC_TEMPOH3B_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH3B value */ + CrIaCopy(ADC_TEMPOH3B_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH3B_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH3B_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get ADC_TEMPOH4B limit */ + CrIaCopy(ADC_TEMPOH4B_U_ID, &upperLimitFloat); /* engineering value */ + /* get ADC_TEMPOH4B value */ + CrIaCopy(ADC_TEMPOH4B_RAW_ID, &valueShort); /* raw value */ + if (convertToTempEngVal(valueShort, ADC_TEMPOH4B_ID) + CONVERT_KTODEGC > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = ADC_TEMPOH4B_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get SEM_P15V limit */ + CrIaCopy(SEM_P15V_U_ID, &upperLimitFloat); + /* get SEM_P15V value */ + CrIaCopy(SEM_P15V_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = SEM_P15V_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get SEM_P30V limit */ + CrIaCopy(SEM_P30V_U_ID, &upperLimitFloat); + /* get SEM_P30V value */ + CrIaCopy(SEM_P30V_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = SEM_P30V_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get SEM_P5V0 limit */ + CrIaCopy(SEM_P5V0_U_ID, &upperLimitFloat); + /* get SEM_P5V0 value */ + CrIaCopy(SEM_P5V0_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = SEM_P5V0_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get SEM_P7V0 limit */ + CrIaCopy(SEM_P7V0_U_ID, &upperLimitFloat); + /* get SEM_P7V0 value */ + CrIaCopy(SEM_P7V0_ID, &valueFloat); + if (valueFloat > upperLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = SEM_P7V0_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + /* get SEM_N5V0 limit */ + CrIaCopy(SEM_N5V0_L_ID, &lowerLimitFloat); + /* get SEM_N5V0 value */ + CrIaCopy(SEM_N5V0_ID, &valueFloat); + if (valueFloat < lowerLimitFloat) + { + limitCnt += 1; + /* send event report OOL */ + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = SEM_N5V0_ID; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + + return limitCnt; +} + + +unsigned short checkResources() +{ + float maxLoad; + float wcet_1, wcet_2, wcet_3; + float maxMem; + unsigned char NofAllocatedInCmd, MaxNOfInCmd, NofAllocatedInRep, MaxNOfInRep, NOfAllocatedOutCmp, MaxNOfOutCmp; + unsigned char Sem_NOfPendingInCmp, Sem_PCRLSize, GrdObc_NOfPendingInCmp, GrdObc_PCRLSize; + unsigned char OutMg1_NOfPendingOutCmp, OutMg1_POCLSize, OutMg2_NOfPendingOutCmp, OutMg2_POCLSize; + unsigned char OutMg3_NOfPendingOutCmp, OutMg3_POCLSize; + unsigned short InSem_NOfPendingPckts; + unsigned char InSem_PcktQueueSize; + unsigned char InObc_NOfPendingPckts, InObc_PcktQueueSize, InGrd_NOfPendingPckts, InGrd_PcktQueueSize; + unsigned char OutSem_NOfPendingPckts, OutSem_PcktQueueSize, OutObc_NOfPendingPckts, OutObc_PcktQueueSize; + unsigned char OutGrd_NOfPendingPckts, OutGrd_PcktQueueSize; + + /* check, if CPU usage on core 1 exceeds CPU1_USAGE_MAX of available CPU */ + CrIaCopy(CPU1_USAGE_MAX_ID, &maxLoad); + + CrIaCopy(WCET_1_ID, &wcet_1); + CrIaCopy(WCET_2_ID, &wcet_2); + CrIaCopy(WCET_3_ID, &wcet_3); + + if ((wcet_1 + wcet_2 + wcet_3) > maxLoad * 0.125f) + return 1; + + /* check, if dynamically allocated memory exceeds MEM_USAGE_MAX of available memory */ + + /* NOTE: with our malloc wrapper we cannot allocate more memory than the size of the heaps, so this check will never fail */ + + CrIaCopy(MEM_USAGE_MAX_ID, &maxMem); + + CrIaCopy(NOFALLOCATEDINCMD_ID, &NofAllocatedInCmd); + CrIaCopy(MAXNOFINCMD_ID, &MaxNOfInCmd); + CrIaCopy(NOFALLOCATEDINCMD_ID, &NofAllocatedInRep); + CrIaCopy(MAXNOFINCMD_ID, &MaxNOfInRep); + CrIaCopy(NOFALLOCATEDOUTCMP_ID, &NOfAllocatedOutCmp); + CrIaCopy(MAXNOFOUTCMP_ID, &MaxNOfOutCmp); + CrIaCopy(SEM_NOFPENDINGINCMP_ID, &Sem_NOfPendingInCmp); + CrIaCopy(SEM_PCRLSIZE_ID, &Sem_PCRLSize); + CrIaCopy(GRDOBC_NOFPENDINGINCMP_ID, &GrdObc_NOfPendingInCmp); + CrIaCopy(GRDOBC_PCRLSIZE_ID, &GrdObc_PCRLSize); + CrIaCopy(OUTMG1_NOFPENDINGOUTCMP_ID, &OutMg1_NOfPendingOutCmp); + CrIaCopy(OUTMG1_POCLSIZE_ID, &OutMg1_POCLSize); + CrIaCopy(OUTMG2_NOFPENDINGOUTCMP_ID, &OutMg2_NOfPendingOutCmp); + CrIaCopy(OUTMG2_POCLSIZE_ID, &OutMg2_POCLSize); + CrIaCopy(OUTMG3_NOFPENDINGOUTCMP_ID, &OutMg3_NOfPendingOutCmp); + CrIaCopy(OUTMG3_POCLSIZE_ID, &OutMg3_POCLSize); + CrIaCopy(INSEM_NOFPENDINGPCKTS_ID, &InSem_NOfPendingPckts); + CrIaCopy(INSEM_PCKTQUEUESIZE_ID, &InSem_PcktQueueSize); + CrIaCopy(INOBC_NOFPENDINGPCKTS_ID, &InObc_NOfPendingPckts); + CrIaCopy(INOBC_PCKTQUEUESIZE_ID, &InObc_PcktQueueSize); + CrIaCopy(INGRD_NOFPENDINGPCKTS_ID, &InGrd_NOfPendingPckts); + CrIaCopy(INGRD_PCKTQUEUESIZE_ID, &InGrd_PcktQueueSize); + CrIaCopy(OUTSEM_NOFPENDINGPCKTS_ID, &OutSem_NOfPendingPckts); + CrIaCopy(OUTSEM_PCKTQUEUESIZE_ID, &OutSem_PcktQueueSize); + CrIaCopy(OUTOBC_NOFPENDINGPCKTS_ID, &OutObc_NOfPendingPckts); + CrIaCopy(OUTOBC_PCKTQUEUESIZE_ID, &OutObc_PcktQueueSize); + CrIaCopy(OUTGRD_NOFPENDINGPCKTS_ID, &OutGrd_NOfPendingPckts); + CrIaCopy(OUTGRD_PCKTQUEUESIZE_ID, &OutGrd_PcktQueueSize); + + if (((float)NofAllocatedInCmd / (float)MaxNOfInCmd > maxMem) || /* Check number of command packets allocated by InFactory */ + ((float)NofAllocatedInRep / (float)MaxNOfInRep > maxMem) || /* Check number of report packets allocated by InFactory */ + ((float)NOfAllocatedOutCmp / (float)MaxNOfOutCmp > maxMem) || /* Check number of command and report packets allocated by OutFactory */ + ((float)Sem_NOfPendingInCmp / (float)Sem_PCRLSize > maxMem) || /* Check number of pending commands in InManagerSem */ + ((float)GrdObc_NOfPendingInCmp / (float)GrdObc_PCRLSize > maxMem) || /* Check number of pending commands in InManagerGrdObc */ + ((float)OutMg1_NOfPendingOutCmp / (float)OutMg1_POCLSize > maxMem) || /* Check number of pending out-going reports in OutManager1 */ + ((float)OutMg2_NOfPendingOutCmp / (float)OutMg2_POCLSize > maxMem) || /* Check number of pending out-going reports in OutManager2 */ + ((float)OutMg3_NOfPendingOutCmp / (float)OutMg3_POCLSize > maxMem) || /* Check number of pending out-going reports in OutManager3 */ + ((float)InSem_NOfPendingPckts / (float)InSem_PcktQueueSize > maxMem) || /* Check number of pending packets in InStreamSem */ + ((float)InObc_NOfPendingPckts / (float)InObc_PcktQueueSize > maxMem) || /* Check number of pending packets in InStreamObc */ + ((float)InGrd_NOfPendingPckts / (float)InGrd_PcktQueueSize > maxMem) || /* Check number of pending packets in InStreamSem */ + ((float)OutSem_NOfPendingPckts / (float)OutSem_PcktQueueSize > maxMem) || /* Check number of pending packets in OutStreamSem */ + ((float)OutObc_NOfPendingPckts / (float)OutObc_PcktQueueSize > maxMem) || /* Check number of pending packets in OutStreamObc */ + ((float)OutGrd_NOfPendingPckts / (float)OutGrd_PcktQueueSize > maxMem)) /* Check number of pending packets in OutStreamGrd */ + return 1; + + return 0; +} + + +unsigned long areaIdToAddress (unsigned short fbfRamAreaId, unsigned int fbfRamAddr) +{ + unsigned short sdbstate; + unsigned short group, member; + unsigned short nfull, nwin, sizefull, sizewin; + + if (fbfRamAreaId == AREAID_RAMADDR) + { + return fbfRamAddr; + } + + if (fbfRamAreaId == AREAID_SDU4) + { + return (unsigned long)SRAM1_FLASH_ADDR; + } + + /* the remaining possible IDs are in ranges 100.. , 200.. , 300.. */ + group = fbfRamAreaId / 100; + group *= 100; + member = fbfRamAreaId - group; + + CrIaCopy(SDBSTATE_ID, &sdbstate); + + if (group == AREAID_SIB) + { + if (sdbstate == CrIaSdb_CONFIG_FULL) + { + CrIaCopy(SIBNFULL_ID, &nfull); + CrIaCopy(SIBSIZEFULL_ID, &sizefull); + + if (member < nfull) + { + return (unsigned long)((unsigned int)sibAddressFull + (member * sizefull * 1024)); + } + else + { + return 0; + } + } + + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + CrIaCopy(SIBNWIN_ID, &nwin); + CrIaCopy(SIBSIZEWIN_ID, &sizewin); + + if (member < nwin) + { + return (unsigned long)((unsigned int)sibAddressWin + (member * sizewin * 1024)); + } + else + { + return 0; + } + } + } + + if (group == AREAID_CIB) + { + if (sdbstate == CrIaSdb_CONFIG_FULL) + { + CrIaCopy(CIBNFULL_ID, &nfull); + CrIaCopy(CIBSIZEFULL_ID, &sizefull); + + if (member < nfull) + { + return (unsigned long)((unsigned int)cibAddressFull + (member * sizefull * 1024)); + } + else + { + return 0; + } + } + + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + CrIaCopy(CIBNWIN_ID, &nwin); + CrIaCopy(CIBSIZEWIN_ID, &sizewin); + + if (member < nwin) + { + return (unsigned long)((unsigned int)cibAddressWin + (member * sizewin * 1024)); + } + else + { + return 0; + } + } + } + + if (group == AREAID_GIB) + { + CrIaCopy(GIBNFULL_ID, &nfull); + CrIaCopy(GIBSIZEFULL_ID, &sizefull); + CrIaCopy(GIBNWIN_ID, &nwin); + CrIaCopy(GIBSIZEWIN_ID, &sizewin); + + /* the ith GIB is a full frame */ + if (member < nfull) + { + return (unsigned long)((unsigned int)gibAddressFull + (member * sizefull * 1024)); + } + + /* the ith GIB is a window */ + if (member < nfull + nwin) + { + return (unsigned long)((unsigned int)gibAddressWin + ((member-nfull) * sizewin * 1024)); + } + else + { + return 0; + } + } + + return 0; +} + + +unsigned short verifyAddress (unsigned int addrVal) +{ + /* within SRAM_1 */ + if ((addrVal >= SRAM1_ADDR) && (addrVal < SRAM1_ADDR + SRAM1_SIZE)) + return ADDRID_SRAM1; + + /* within SRAM_2 */ + if ((addrVal >= SRAM2_ADDR) && (addrVal < SRAM2_ADDR + SRAM2_SIZE)) + return ADDRID_SRAM2; + + /* within SRAM_2, but alternate addressing */ + if (addrVal <= SRAM2_SIZE) + return ADDRID_SRAM2ALT; + + /* within AHB_RAM */ + if ((addrVal >= AHBRAM_ADDR) && (addrVal < AHBRAM_ADDR + AHBRAM_SIZE)) + return ADDRID_AHBRAM; + + /* within FPGA */ + if ((addrVal >= FPGA_ADDR) && (addrVal < FPGA_ADDR + FPGA_SIZE)) + return ADDRID_FPGA; + + /* within REGISTERS */ + if ((addrVal >= REG1_ADDR) && (addrVal < REG1_ADDR + REG1_SIZE)) + return ADDRID_REG1; + + if ((addrVal >= REG2_ADDR) && (addrVal < REG2_ADDR + REG2_SIZE)) + return ADDRID_REG2; + + /* invalid address */ + return ADDRID_INVALID; +} + + +unsigned short cvtAddrIdToRamId (unsigned short addr_id) +{ + switch (addr_id) + { + case ADDRID_SRAM1 : + case ADDRID_SRAM2 : + case ADDRID_SRAM2ALT : + return DPU_RAM; + + case ADDRID_AHBRAM : + return DPU_INTERNAL; + + case ADDRID_FPGA : + case ADDRID_REG1 : + case ADDRID_REG2 : + return DPU_REGISTER; + + case ADDRID_INVALID : + default : + break; + } + + return 0; +} + + +void SendTcAccRepSucc(CrFwPckt_t pckt) +{ + FwSmDesc_t rep; + CrFwDestSrc_t source; + CrFwBool_t isAcceptAck; + unsigned char sid, tcType, tcSubtype; + unsigned short tcPacketId, tcPacketSeqCtrl, tcLength, tcReceivedBytes, tcReceivedCrc, tcCalculatedCrc, tcFailureCode, nofTcAcc, seqCntLastAccTc; + + CRIA_UNUSED(tcFailureCode); + CRIA_UNUSED(tcCalculatedCrc); + CRIA_UNUSED(tcReceivedCrc); + CRIA_UNUSED(tcReceivedBytes); + CRIA_UNUSED(tcLength); + CRIA_UNUSED(tcSubtype); + CRIA_UNUSED(tcType); + CRIA_UNUSED(sid); + CRIA_UNUSED(sid); + CRIA_UNUSED(tcSubtype); + CRIA_UNUSED(tcType); + CRIA_UNUSED(tcSubtype); + CRIA_UNUSED(tcType); + CRIA_UNUSED(sid); + + source = CrFwPcktGetSrc(pckt); + DEBUGP("SendTcAccRepSucc: source = %d\n", source); + + CrIaCopy(NOFTCACC_ID, &nofTcAcc); + nofTcAcc += 1; + CrIaPaste(NOFTCACC_ID, &nofTcAcc); + + seqCntLastAccTc = CrFwPcktGetSeqCnt(pckt); + + if (source==CR_FW_CLIENT_GRD) + { + CrIaPaste(SEQCNTLASTACCTCFROMGRD_ID, &seqCntLastAccTc); + DEBUGP("SendTcAccRepSucc: set SeqCntLastAccTcFromGrd = %d\n", seqCntLastAccTc); + } + else if (source==CR_FW_CLIENT_OBC) + { + CrIaPaste(SEQCNTLASTACCTCFROMOBC_ID, &seqCntLastAccTc); + DEBUGP("SendTcAccRepSucc: set SeqCntLastAccTcFromObc = %d\n", seqCntLastAccTc); + } + + isAcceptAck = CrFwPcktIsAcceptAck(pckt); + + if (isAcceptAck==1) + { + /* send (1,1) TC acceptance report - success */ + /* Create out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV1, CRIA_SERV1_ACC_SUCC, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + tcPacketId = CrIaPcktGetPacketId(pckt); + CrIaServ1AccSuccParamSetTcPacketId(rep, tcPacketId); + tcPacketSeqCtrl = CrFwPcktGetSeqCtrl(pckt); + CrIaServ1AccSuccParamSetTcPacketSeqCtrl(rep, tcPacketSeqCtrl); + + CrFwOutCmpSetDest(rep, source); + + CrFwOutLoaderLoad(rep); + } + + return; +} + +void SendTcAccRepFail(CrFwPckt_t pckt, unsigned short tcFailureCode) +{ + FwSmDesc_t rep; + CrFwDestSrc_t source; + unsigned char tcType, tcSubtype; + unsigned short tcPacketId, tcPacketSeqCtrl, tcLength, tcReceivedBytes, tcReceivedCrc, tcCalculatedCrc, nofAccFailedTc, seqCntLastAccFailTc; + + if (pckt != NULL) + { + CrIaCopy(NOFACCFAILEDTC_ID, &nofAccFailedTc); + nofAccFailedTc += 1; + CrIaPaste(NOFACCFAILEDTC_ID, &nofAccFailedTc); + + seqCntLastAccFailTc = CrFwPcktGetSeqCnt(pckt); + CrIaPaste(SEQCNTLASTACCFAILTC_ID, &seqCntLastAccFailTc); + DEBUGP("SendTcAccRepFail: set SeqCntLastAccFailTc = %d\n", seqCntLastAccFailTc); + } + + /* send (1,2) TC acceptance report - failure */ + /* Create out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV1, CRIA_SERV1_ACC_FAIL, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + if (pckt != NULL) + { + /* Set out component parameters */ + tcPacketId = CrIaPcktGetPacketId(pckt); + CrIaServ1AccFailParamSetTcPacketId(rep, tcPacketId); + tcPacketSeqCtrl = CrFwPcktGetSeqCtrl(pckt); + CrIaServ1AccFailParamSetTcPacketSeqCtrl(rep, tcPacketSeqCtrl); + tcType = CrFwPcktGetServType(pckt); + CrIaServ1AccFailParamSetTcType(rep, tcType); + tcSubtype = CrFwPcktGetServSubType(pckt); + CrIaServ1AccFailParamSetTcSubtype(rep, tcSubtype); + tcLength = CrFwPcktGetLength(pckt); + CrIaServ1AccFailParamSetTcLength(rep, tcLength); + tcReceivedBytes = CrFwPcktGetParLength(pckt) + OFFSET_PAR_LENGTH_TC + CRC_LENGTH; + CrIaServ1AccFailParamSetTcReceivedBytes(rep, tcReceivedBytes); + tcReceivedCrc = CrIaPcktGetCrc(pckt); + CrIaServ1AccFailParamSetTcReceivedCrc(rep, tcReceivedCrc); + tcCalculatedCrc = GetCalculatedCrcFrom(pckt); + CrIaServ1AccFailParamSetTcCalculatedCrc(rep, tcCalculatedCrc); + + source = CrFwPcktGetSrc(pckt); + CrFwOutCmpSetDest(rep, source); + } + else + { + source = 0; + CrFwOutCmpSetDest(rep, source); + } + + CrIaServ1AccFailParamSetTcFailureCode(rep, tcFailureCode); + + CrFwOutLoaderLoad(rep); + + return; +} + +void SendTcStartRepSucc(CrFwPckt_t pckt) +{ + FwSmDesc_t rep; + CrFwDestSrc_t source; + CrFwBool_t isStartAck; + unsigned char tcType, tcSubtype; + unsigned short tcPacketId, tcPacketSeqCtrl; + + CRIA_UNUSED(tcSubtype); + CRIA_UNUSED(tcType); + + isStartAck = CrFwPcktIsStartAck(pckt); + + if (isStartAck==1) + { + /* send (1,3) TC start report - success */ + /* Create out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV1, CRIA_SERV1_START_SUCC, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + tcPacketId = CrIaPcktGetPacketId(pckt); + CrIaServ1StartSuccParamSetTcPacketId(rep, tcPacketId); + tcPacketSeqCtrl = CrFwPcktGetSeqCtrl(pckt); + CrIaServ1StartSuccParamSetTcPacketSeqCtrl(rep, tcPacketSeqCtrl); + + source = CrFwPcktGetSrc(pckt); + CrFwOutCmpSetDest(rep, source); + + CrFwOutLoaderLoad(rep); + } + + return; +} + +void SendTcStartRepFail(CrFwPckt_t pckt, unsigned short tcFailureCode, unsigned short wrongParamPosition, unsigned short wrongParamValue) +{ + FwSmDesc_t rep; + CrFwDestSrc_t source; + unsigned char tcType, tcSubtype; + unsigned short tcPacketId, tcPacketSeqCtrl, nofStartFailedTc, seqCntLastStartFailTc; + + CRIA_UNUSED(wrongParamPosition); + CRIA_UNUSED(wrongParamValue); + + CrIaCopy(NOFSTARTFAILEDTC_ID, &nofStartFailedTc); + nofStartFailedTc += 1; + CrIaPaste(NOFSTARTFAILEDTC_ID, &nofStartFailedTc); + + seqCntLastStartFailTc = CrFwPcktGetSeqCtrl(pckt); + CrIaPaste(SEQCNTLASTSTARTFAILTC_ID, &seqCntLastStartFailTc); + DEBUGP("SendTcStartRepFail: set SeqCntLastStartFailTc = %d\n", seqCntLastStartFailTc); + + /* send (1,4) TC start report - failure */ + /* Create out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV1, CRIA_SERV1_START_FAIL, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + tcPacketId = CrIaPcktGetPacketId(pckt); + CrIaServ1StartFailParamSetTcPacketId(rep, tcPacketId); + tcPacketSeqCtrl = CrFwPcktGetSeqCtrl(pckt); + CrIaServ1StartFailParamSetTcPacketSeqCtrl(rep, tcPacketSeqCtrl); + tcType = CrFwPcktGetServType(pckt); + CrIaServ1StartFailParamSetTcType(rep, tcType); + tcSubtype = CrFwPcktGetServSubType(pckt); + CrIaServ1StartFailParamSetTcSubtype(rep, tcSubtype); + CrIaServ1StartFailParamSetWrongParamPosition(rep, wrongParamPosition); + CrIaServ1StartFailParamSetWrongParamValue(rep, wrongParamValue); + CrIaServ1StartFailParamSetTcFailureCode(rep, tcFailureCode); + + source = CrFwPcktGetSrc(pckt); + CrFwOutCmpSetDest(rep, source); + + CrFwOutLoaderLoad(rep); + + return; +} + +void SendTcTermRepSucc(CrFwPckt_t pckt) +{ + FwSmDesc_t rep; + CrFwDestSrc_t source; + CrFwBool_t isTermAck; + unsigned char tcType, tcSubtype; + unsigned short tcPacketId, tcPacketSeqCtrl, nofTcTerm; + + CRIA_UNUSED(tcSubtype); + CRIA_UNUSED(tcType); + + CrIaCopy(NOFTCTERM_ID, &nofTcTerm); + nofTcTerm += 1; + CrIaPaste(NOFTCTERM_ID, &nofTcTerm); + + isTermAck = CrFwPcktIsTermAck(pckt); + + if (isTermAck==1) + { + /* send (1,7) TC termination report - success */ + /* Create out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV1, CRIA_SERV1_TERM_SUCC, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + tcPacketId = CrIaPcktGetPacketId(pckt); + CrIaServ1TermSuccParamSetTcPacketId(rep, tcPacketId); + tcPacketSeqCtrl = CrFwPcktGetSeqCtrl(pckt); + + CrIaServ1TermSuccParamSetTcPacketSeqCtrl(rep, tcPacketSeqCtrl); + + source = CrFwPcktGetSrc(pckt); + CrFwOutCmpSetDest(rep, source); + + CrFwOutLoaderLoad(rep); + } + + return; +} + +void SendTcTermRepFail(CrFwPckt_t pckt, unsigned short tcFailureCode, unsigned short wrongParamPosition, unsigned short wrongParamValue) +{ + FwSmDesc_t rep; + CrFwDestSrc_t source; + unsigned char tcType, tcSubtype; + unsigned short tcPacketId, tcPacketSeqCtrl, nofTermFailedTc, seqCntLastTermFailTc; + + CRIA_UNUSED(wrongParamPosition); + CRIA_UNUSED(wrongParamValue); + + CrIaCopy(NOFTERMFAILEDTC_ID, &nofTermFailedTc); + nofTermFailedTc += 1; + CrIaPaste(NOFTERMFAILEDTC_ID, &nofTermFailedTc); + + seqCntLastTermFailTc = CrFwPcktGetSeqCtrl(pckt); + CrIaPaste(SEQCNTLASTTERMFAILTC_ID, &seqCntLastTermFailTc); + DEBUGP("SendTcTermRepFail: set SeqCntLastTermFailTc = %d\n", seqCntLastTermFailTc); + + /* send (1,4) TC start report - failure */ + /* Create out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV1, CRIA_SERV1_TERM_FAIL, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + tcPacketId = CrIaPcktGetPacketId(pckt); + CrIaServ1TermFailParamSetTcPacketId(rep, tcPacketId); + tcPacketSeqCtrl = CrFwPcktGetSeqCtrl(pckt); + CrIaServ1TermFailParamSetTcPacketSeqCtrl(rep, tcPacketSeqCtrl); + tcType = CrFwPcktGetServType(pckt); + CrIaServ1TermFailParamSetTcType(rep, tcType); + tcSubtype = CrFwPcktGetServSubType(pckt); + CrIaServ1TermFailParamSetTcSubtype(rep, tcSubtype); + CrIaServ1TermFailParamSetWrongParamPosition(rep, wrongParamPosition); + CrIaServ1TermFailParamSetWrongParamValue(rep, wrongParamValue); + CrIaServ1TermFailParamSetTcFailureCode(rep, tcFailureCode); + + source = CrFwPcktGetSrc(pckt); + CrFwOutCmpSetDest(rep, source); + + CrFwOutLoaderLoad(rep); + + return; +} diff --git a/CrIa/src/IfswUtilities.h b/CrIa/src/IfswUtilities.h new file mode 100644 index 0000000000000000000000000000000000000000..8050918e57d21c9983f89a4085f26a53502f8d98 --- /dev/null +++ b/CrIa/src/IfswUtilities.h @@ -0,0 +1,103 @@ +/** + * @file IfswUtilities.h + */ + +#ifndef IFSWUTILITIES_H +#define IFSWUTILITIES_H + +/* Includes */ +#include <CrFwConstants.h> + +#if (__sparc__) +#include <iwf_fpga.h> /* heater enums */ +#else +#include "CrIaIasw.h" +#endif + +/* AREA IDs */ +#define AREAID_RAMADDR 0 +#define AREAID_SDU4 3 +#define AREAID_SIB 100 +#define AREAID_CIB 200 +#define AREAID_GIB 300 + +/* memory area IDs, have a finer grade than IDs from the ICD */ +#define ADDRID_SRAM1 1 +#define ADDRID_SRAM2 2 +#define ADDRID_SRAM2ALT 3 +#define ADDRID_AHBRAM 4 +#define ADDRID_FPGA 5 +#define ADDRID_REG1 6 +#define ADDRID_REG2 7 +#define ADDRID_INVALID 0 + +/* IDs from the ICD */ +#define DPU_RAM 0x0002 +#define DPU_REGISTER 0x0003 +#define DPU_INTERNAL 0x0004 +#define DPU_FLASH1 0x1100 +#define DPU_FLASH2 0x1200 +#define DPU_FLASH3 0x1300 +#define DPU_FLASH4 0x1400 + + +struct SdbLayout { + unsigned short mode; + unsigned short CibNFull; + unsigned short SibNFull; + unsigned short GibNFull; + unsigned short CibNWin; + unsigned short SibNWin; + unsigned short GibNWin; + unsigned short CibSizeFull; + unsigned short SibSizeFull; + unsigned short GibSizeFull; + unsigned short CibSizeWin; + unsigned short SibSizeWin; + unsigned short GibSizeWin; +} ; + + +extern unsigned char heater_stat[4]; + +void sort4float (float *data); + +unsigned char getHbSem(); + +void CrIaHeaterOn (enum heater htr); + +void CrIaHeaterOff (enum heater htr); + +unsigned char CrIaHeaterStatus (enum heater htr); + +void PutBit8 (unsigned char value, unsigned int bitOffset, unsigned char *dest); + +void PutNBits8 (unsigned int value, unsigned int bitOffset, unsigned int nbits, unsigned char *dest); + +unsigned int getHkDataSize(unsigned char sid); + +unsigned short getSemAnoEvtId(unsigned short eventId); + +unsigned short checkDpuHkLimits(); + +unsigned short checkResources(); + +unsigned long areaIdToAddress (unsigned short fbfRamAreaId, unsigned int fbfRamAddr); + +unsigned short verifyAddress (unsigned int addrVal); + +unsigned short cvtAddrIdToRamId (unsigned short addr_id); + +void SendTcAccRepSucc(CrFwPckt_t pckt); + +void SendTcAccRepFail(CrFwPckt_t pckt, unsigned short tcFailureCode); + +void SendTcStartRepSucc(CrFwPckt_t pckt); + +void SendTcStartRepFail(CrFwPckt_t pckt, unsigned short tcFailureCode, unsigned short wrongParamPosition, unsigned short wrongParamValue); + +void SendTcTermRepSucc(CrFwPckt_t pckt); + +void SendTcTermRepFail(CrFwPckt_t pckt, unsigned short tcFailureCode, unsigned short wrongParamPosition, unsigned short wrongParamValue); + +#endif /* IFSWUTILITIES_H */ diff --git a/CrIa/src/ScienceDataProcessing.c b/CrIa/src/ScienceDataProcessing.c new file mode 100644 index 0000000000000000000000000000000000000000..66868b09153bbaecf746080b13e7fa557e96a6e6 --- /dev/null +++ b/CrIa/src/ScienceDataProcessing.c @@ -0,0 +1,331 @@ +/** + * @file ScienceDataProcessing.c + * @ingroup Sdp + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup Sdp Science Data Processing + * + * @brief high level calling function to the science data processing + * + * This module contains the high level call, @ref ScienceProcessing to the @ref Compression. + * In order to get started with the concept of the data processing chain, read "Cheops On-Board Data Processing Steps", CHEOPS-UVIE-INST-TN-001. + * The concept of the @ref CompressionEntity is described well in the "IFSW-SOC ICD", CHEOPS-UVIE-ICD-003. + * The architectural overview of the @ref Sdp for CHEOPS is given by "On-Board Science Data Processing Architectural Design", + * CHEOPS-UVIE-DD-003. When it comes to algorithms, the best possible introduction is "Intelligent Detectors", http://othes.univie.ac.at/8223/. + * + * + */ + + +#include <stdint.h> + +#include <FwSmConfig.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/General/CrIaConstants.h> + +#include <CrIaIasw.h> /* for sibAddressFull and Win */ +#include <CrIaPrSm/CrIaSdbCreate.h> /* for CONFIG_FULL etc. */ +#if (__sparc__) +#include <wrap_malloc.h> +#endif + +#include "IfswDebug.h" + +#include "ScienceDataProcessing.h" + +#include "Sdp/SdpAlgorithmsImplementation.h" +#include "Sdp/SdpAlgorithmsImplementationLlc.h" +#include "Sdp/SdpBuffers.h" +#include "Sdp/SdpCeDefinitions.h" +#include "Sdp/SdpCollect.h" +#include "Sdp/SdpCompress.h" +#include "Sdp/SdpCompressionEntityStructure.h" + + + +/* science dummy processing for the second core */ +#if (__sparc__) +#include <ibsw_interface.h> +#include <timing.h> +#endif +extern struct ibsw_config ibsw_cfg; +#include <EngineeringAlgorithms.h> + + +/** + * @brief top-level function to create the compression output in the @ref GIB + * @param mycestruct pointer to the @ref ComprEntStructure + * + * This function calls @ref SdpCollect to create the binary Compression Entity from the @ref ComprEntStructure and then increments the @ref GIB in pointer in the data pool accordingly. + * + */ + +void Collect (struct ComprEntStructure *mycestruct) +{ + unsigned int gibSize = 0; + unsigned short gibIn, newGibIn, gibOut, gibSizeWin, gibNWin, gibSizeFull, gibNFull, sdbstate; + unsigned long int xibOffset; + unsigned short evt_data[2]; + + /* call the actual collect function */ + SdpCollect(mycestruct); + + /* check size of compression entity */ + CrIaCopy (GIBIN_ID, &gibIn); + CrIaCopy (GIBOUT_ID, &gibOut); + CrIaCopy (GIBSIZEWIN_ID, &gibSizeWin); + CrIaCopy (GIBNWIN_ID, &gibNWin); + CrIaCopy (GIBSIZEFULL_ID, &gibSizeFull); + CrIaCopy (GIBNFULL_ID, &gibNFull); + CrIaCopy (SDBSTATE_ID, &sdbstate); + + /* check size of compressed product */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + gibSize = gibSizeWin * 1024; + + if (sdbstate == CrIaSdb_CONFIG_FULL) + gibSize = gibSizeFull * 1024; + + if (mycestruct->Size > gibSize) + { +#ifdef ISOLATED + (void) evt_data; + SDPRINT("ERROR: the GIB size of %u is too small for the CE of size %u!\n", gibSize, mycestruct->Size); +#else + evt_data[0] = (unsigned short)((mycestruct->Size + 1023) / 1024); /* requested gibSize in kiB rounded up */ + evt_data[1] = 0; + SdpEvtRaise(3, CRIA_SERV5_EVT_CLCT_SIZE, evt_data, 4); +#endif + } + + /* increment GIBIN */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_RES_OFFSET_FROM_ADDR((unsigned long int)gibAddressWin); + newGibIn = updateXib((unsigned int)gibIn, (unsigned int)gibOut, xibOffset, (unsigned int)gibSizeWin, (unsigned int)gibNWin, GIBIN_WIN_XIB); + } + else + { + xibOffset = GET_RES_OFFSET_FROM_ADDR((unsigned long int)gibAddressFull); + newGibIn = updateXib((unsigned int)gibIn, (unsigned int)gibOut, xibOffset, (unsigned int)gibSizeFull, (unsigned int)gibNFull, GIBIN_FULL_XIB); + } + + /* NOTE: in the case that GIBIN couldn't be incremented, we stay on the last frame */ + + gibIn = newGibIn; + CrIaPaste (GIBIN_ID, &gibIn); + + return; +} + +/** + * @brief get combined information for SAA and SDS flags from a set of SIBs + * + * @param nframes number of frames to process as a CE. In other words, the stacking number + * @param Xdim width of the imaging area + * @param Ydim height of the imaging area + * + * @returns The combined flag information. + * + * This function looks at the SDB/SAA flags stored in the SIBs by the SciDataUpdFunc (see IFSW-SOC ICD). + * 0...OK, 1...SAA, 2...NOK (in this case, do not set SAA), 3...SDS + * The highest priority has the SDS state. It overrules a NOK. SAA has low priority, it is ignored if NOK is set. + * NOK is set by SdpCompress. + */ + +unsigned char GetSibFlags (unsigned int nframes, unsigned int Xdim, unsigned int Ydim) +{ + struct CrIaSib sib; + struct SibPhotometry *sibPhotometry; + int status; + unsigned int i; + unsigned short sibIn, sibOut, newSibOut, sibSizeWin, sibNWin, sibSizeFull, sibNFull, sdbstate; + unsigned long int xibOffset; + + unsigned int flags; + + /* get Sib parameters and state of SDB (WIN or FULL) */ + CrIaCopy (SIBIN_ID, &sibIn); + CrIaCopy (SIBOUT_ID, &sibOut); + CrIaCopy (SIBSIZEWIN_ID, &sibSizeWin); + CrIaCopy (SIBNWIN_ID, &sibNWin); + CrIaCopy (SIBSIZEFULL_ID, &sibSizeFull); + CrIaCopy (SIBNFULL_ID, &sibNFull); + CrIaCopy (SDBSTATE_ID, &sdbstate); + + flags = 0xffffffff; /* in the loop, the flags are combined with &, so we start with all on here */ + + for (i=0; i < nframes; i++) + { + /* setup SIB structure using current sibOut (the compression is the SIB consumer, thus it reads from "out") */ + status = 0; + if (sdbstate == CrIaSdb_CONFIG_WIN) + status = CrIaSetupSibWin (&sib, sibOut, Xdim, Ydim); + + if (sdbstate == CrIaSdb_CONFIG_FULL) + status = CrIaSetupSibFull (&sib, sibOut); + + if (status == 0) + { + /* error gets reported by setup function */ + break; + } + + /* All SIBs must have the same flag to be set for the CE. + The possible SIB flags are either 0 (no flag), 1 (SAA) or 3 (SDS) */ + sibPhotometry = (struct SibPhotometry *) sib.Photometry; + flags &= sibPhotometry->FlagsActive; + + if (i < nframes - 1) /* don't update for the last frame */ + { + /* move to the next sibOut in sequence */ + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeWin, (unsigned int)sibNWin, SIBOUT_WIN_XIB); + } + else + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressFull); + newSibOut = updateXibFwd((unsigned int)sibOut, (unsigned int)sibIn, xibOffset, (unsigned int)sibSizeFull, (unsigned int)sibNFull, SIBOUT_FULL_XIB); + } + + /* NOTE: in the case that SIBOUT cannot be incremented accordingly, we clone the last frame */ + + sibOut = newSibOut; + } + } + + return (unsigned char)(flags & 0xff); +} + + +/** + * @brief top-level call to the science data processing + * + * This function runs the compression. As input it needs the images in the SIBs and as output the @ref CompressionEntity binary object is saved in the @ref GIB. + * The flow of actions is: + * - call @ref InitComprEntStructureFromDataPool to copy the data pool parameters in the @ref ComprEntStructure. If they are modified during an active + * data processing, it has no influence on the current run. + * - call @ref SdpCompress, which is the actual data processing chain. It fills the @ref ComprEntStructure in the @ref CIB with content. + * - update the @ref SIB out pointer by skipping the buffers that have been processed. The function @ref updateXibNTimesFwd is used. + * - call the @ref Collect function to pack the @ref CompressionEntity binary and adjust the @ref GIB in + * - set the SDU2 down transfer size from the size of the @ref CompressionEntity + * - increment the CE counter, which is part of the CE header + * + * @note the CE counter is not reset automatically + * + */ + +void ScienceProcessing (void) +{ + struct ComprEntStructure mycestruct; + unsigned int cesize; + unsigned short cecounter=0; /* initialize counter with default value */ + + unsigned short sibIn, newSibOut, sibOut, sibSizeWin, sibNWin, sibSizeFull, sibNFull; + unsigned short sdbstate; + unsigned long int xibOffset; + unsigned char sibFlags; + + unsigned short uint16; + + uint16 = CC_PROLOGUE; + CrIaPaste(CCPRODUCT_ID, &uint16); + uint16 = CC_PROLOGUE; + CrIaPaste(CCSTEP_ID, &uint16); + + /* Init CE structure from DP */ + InitComprEntStructureFromDataPool (&mycestruct); + + /* COMPRESS: compress all the data and fill the CE products */ + uint16 = CC_COMPR_STARTED; + CrIaPaste(CCSTEP_ID, &uint16); + SdpCompress(&mycestruct); + + uint16 = CC_MIDPART; + CrIaPaste(CCSTEP_ID, &uint16); + + /* enter the Integrity information */ + sibFlags = GetSibFlags (mycestruct.StackingNumber, mycestruct.SemWindowSizeX, mycestruct.SemWindowSizeY); + + + if (sibFlags == DATA_SAA) + { + mycestruct.Integrity = DATA_SAA; /* Mantis 2189 */ + } + + /* SDS overrules all the other flags */ + if (sibFlags == DATA_SUSPEND) + { + mycestruct.Integrity = DATA_SUSPEND; + } + + /* + Increment sibOut by STCK_ORDER + */ + CrIaCopy (SIBIN_ID, &sibIn); + CrIaCopy (SIBOUT_ID, &sibOut); + CrIaCopy (SIBSIZEWIN_ID, &sibSizeWin); + CrIaCopy (SIBNWIN_ID, &sibNWin); + CrIaCopy (SIBSIZEFULL_ID, &sibSizeFull); + CrIaCopy (SIBNFULL_ID, &sibNFull); + + CrIaCopy (SDBSTATE_ID, &sdbstate); + PRDEBUGP("want to shift %d times\n", mycestruct.StackingNumber); + + newSibOut = sibOut; + + if (sdbstate == CrIaSdb_CONFIG_WIN) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressWin); + newSibOut = updateXibNTimesFwd(sibOut, sibIn, xibOffset, sibSizeWin, sibNWin, mycestruct.StackingNumber, SIBOUT_WIN_XIB); + } + if (sdbstate == CrIaSdb_CONFIG_FULL) + { + xibOffset = GET_SDB_OFFSET_FROM_ADDR((unsigned long int)sibAddressFull); + newSibOut = updateXibNTimesFwd(sibOut, sibIn, xibOffset, sibSizeFull, sibNFull, mycestruct.StackingNumber, SIBOUT_FULL_XIB); + } + + CrIaPaste (SIBOUT_ID, &newSibOut); + + /* COLLECT: create the bitstream from the CE products */ + PRDEBUGP("launch collect\n"); + uint16 = CC_COLLECT; + CrIaPaste(CCPRODUCT_ID, &uint16); + Collect(&mycestruct); + + /* set SDU 2 down transfer size */ + + PRDEBUGP("CE %d size is: %d\n", cecounter, mycestruct.Size); + + /* Mantis 1421 / 1626 leaves us the choice to either set SDU2DOWNTRANSFERSIZE to 0xffffffff or the actual size */ + cesize = DTSIZE_FROM_HEADER; + CrIaPaste(SDU2DOWNTRANSFERSIZE_ID, &cesize); + + /* increment the CE counter */ + CrIaCopy(CE_COUNTER_ID, &cecounter); + cecounter++; + CrIaPaste(CE_COUNTER_ID, &cecounter); + + PRDEBUGP("done!\n"); + + uint16 = CC_FINISHED; + CrIaPaste(CCSTEP_ID, &uint16); + + return; +} diff --git a/CrIa/src/ScienceDataProcessing.h b/CrIa/src/ScienceDataProcessing.h new file mode 100644 index 0000000000000000000000000000000000000000..3ba0ff84adc315324f1a650a3191b39d22d203f0 --- /dev/null +++ b/CrIa/src/ScienceDataProcessing.h @@ -0,0 +1,23 @@ +/** + * @file SdpAlgorithmsImplementation.h + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2016 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef SCIENCEDATAPROCESSING_H +#define SCIENCEDATAPROCESSING_H + +void ScienceProcessing (void); + +#endif /* SCIENCEDATAPROCESSING_H */ diff --git a/CrIa/src/Sdp/SdpAlgorithmsImplementation.c b/CrIa/src/Sdp/SdpAlgorithmsImplementation.c new file mode 120000 index 0000000000000000000000000000000000000000..1808f56103020ab7e40015e8f605ed2f4ac62676 --- /dev/null +++ b/CrIa/src/Sdp/SdpAlgorithmsImplementation.c @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpAlgorithmsImplementation.c \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpAlgorithmsImplementation.h b/CrIa/src/Sdp/SdpAlgorithmsImplementation.h new file mode 120000 index 0000000000000000000000000000000000000000..789cbdae4c8483f70e9c0422b313e25d7658f68f --- /dev/null +++ b/CrIa/src/Sdp/SdpAlgorithmsImplementation.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpAlgorithmsImplementation.h \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpAlgorithmsImplementationLlc.c b/CrIa/src/Sdp/SdpAlgorithmsImplementationLlc.c new file mode 120000 index 0000000000000000000000000000000000000000..b178ef145e9c49037753e36145ec45d7c1ddc70c --- /dev/null +++ b/CrIa/src/Sdp/SdpAlgorithmsImplementationLlc.c @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpAlgorithmsImplementationLlc.c \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpAlgorithmsImplementationLlc.h b/CrIa/src/Sdp/SdpAlgorithmsImplementationLlc.h new file mode 120000 index 0000000000000000000000000000000000000000..001fba122a7f53933002613fefd7fcc3d2971fe0 --- /dev/null +++ b/CrIa/src/Sdp/SdpAlgorithmsImplementationLlc.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpAlgorithmsImplementationLlc.h \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpBuffers.c b/CrIa/src/Sdp/SdpBuffers.c new file mode 120000 index 0000000000000000000000000000000000000000..01834a856299f0c80ceb498a9fa54716f96907fc --- /dev/null +++ b/CrIa/src/Sdp/SdpBuffers.c @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpBuffers.c \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpBuffers.h b/CrIa/src/Sdp/SdpBuffers.h new file mode 120000 index 0000000000000000000000000000000000000000..dbf2c98b7157278a39d6ba7043ee6526d8a941e1 --- /dev/null +++ b/CrIa/src/Sdp/SdpBuffers.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpBuffers.h \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpCeDefinitions.h b/CrIa/src/Sdp/SdpCeDefinitions.h new file mode 120000 index 0000000000000000000000000000000000000000..e33a90d53d737aec5a6395a6654933b897f68753 --- /dev/null +++ b/CrIa/src/Sdp/SdpCeDefinitions.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpCeDefinitions.h \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpCollect.c b/CrIa/src/Sdp/SdpCollect.c new file mode 120000 index 0000000000000000000000000000000000000000..91785c518c6c23838aea324775a8d772fd4c0973 --- /dev/null +++ b/CrIa/src/Sdp/SdpCollect.c @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpCollect.c \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpCollect.h b/CrIa/src/Sdp/SdpCollect.h new file mode 120000 index 0000000000000000000000000000000000000000..7b5998c97d76815b70fb61cd19b3bad672e3b45f --- /dev/null +++ b/CrIa/src/Sdp/SdpCollect.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpCollect.h \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpCompress.c b/CrIa/src/Sdp/SdpCompress.c new file mode 120000 index 0000000000000000000000000000000000000000..9526bf1d83f0727a0fd9f22feb1f712c132806d9 --- /dev/null +++ b/CrIa/src/Sdp/SdpCompress.c @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpCompress.c \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpCompress.h b/CrIa/src/Sdp/SdpCompress.h new file mode 120000 index 0000000000000000000000000000000000000000..a8de102843c4991da80b94d68d3d65833165f3e6 --- /dev/null +++ b/CrIa/src/Sdp/SdpCompress.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpCompress.h \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpCompressionEntityStructure.h b/CrIa/src/Sdp/SdpCompressionEntityStructure.h new file mode 120000 index 0000000000000000000000000000000000000000..4ce9b96a1e625dd17376f1ef8b8849f82859aadc --- /dev/null +++ b/CrIa/src/Sdp/SdpCompressionEntityStructure.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpCompressionEntityStructure.h \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpNlcPhot.c b/CrIa/src/Sdp/SdpNlcPhot.c new file mode 120000 index 0000000000000000000000000000000000000000..0ffd2e84e88c99dc045716fb6abc6e249e49d214 --- /dev/null +++ b/CrIa/src/Sdp/SdpNlcPhot.c @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpNlcPhot.c \ No newline at end of file diff --git a/CrIa/src/Sdp/SdpNlcPhot.h b/CrIa/src/Sdp/SdpNlcPhot.h new file mode 120000 index 0000000000000000000000000000000000000000..614436fe31a40c9a9736e8839de6bb0987ec5b98 --- /dev/null +++ b/CrIa/src/Sdp/SdpNlcPhot.h @@ -0,0 +1 @@ +../../../CompressionEntity/src/SdpNlcPhot.h \ No newline at end of file diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13AbrtDwlk.c b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13AbrtDwlk.c new file mode 100644 index 0000000000000000000000000000000000000000..32cbc8d78f086301b196e49a30b0f86801269ea7 --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13AbrtDwlk.c @@ -0,0 +1,154 @@ +/** + * @file CrIaServ13AbrtDwlk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Abort Downlink in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ13AbrtDwlk.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaParamSetter.h> +#include <CrIaPrSm/CrIaSduCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + + +CrFwBool_t CrIaServ13AbrtDwlkValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* SDUx must be in range 2..SDU_ID_MAX */ + + CrIaServ13AbrtDwlkParamGetSduId(&sduId, pckt); + + if ((sduId > 1) && (sduId <= SDU_ID_MAX)) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_SDUID); + return 0; +} + +void CrIaServ13AbrtDwlkStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + unsigned short sduxState = 0; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set action outcome to 'success' iff the SDUx State Machine is in state DOWN_TRANSFER */ + cmpData->outcome = 0; + + CrIaServ13AbrtDwlkParamGetSduId(&sduId, pckt); + + switch (sduId) + { + case 2: + sduxState = FwSmGetCurState(smDescSdu2); + break; + case 4: + sduxState = FwSmGetCurState(smDescSdu4); + break; + default: + break; + } + + if (sduxState == CrIaSdu_DOWN_TRANSFER) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + SendTcStartRepFail(pckt, ACK_WR_SDU_M, 0, (unsigned short)sduxState); + return; +} + +void CrIaServ13AbrtDwlkProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + unsigned short reasonCode = 1; /* NOTE: the only reason code is SDU_ABRT_GRD_REQ */ + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command Abort to SDUx State Machine; set Abort Reason Code to SDU_ABRT_GRD_REQ; set the action outcome to 'completed' */ + cmpData->outcome = 0; + + CrIaServ13AbrtDwlkParamGetSduId(&sduId, pckt); + + switch (sduId) + { + case 2: + FwSmMakeTrans(smDescSdu2, Abort); + break; + case 4: + FwSmMakeTrans(smDescSdu4, Abort); + break; + default: + break; + } + + /* Set Abort Reason Code to SDU_ABRT_GRD_REQ */ + CrIaServ13DwlkAbrtParamSetReasonCode(smDesc, reasonCode); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13AbrtDwlk.h b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13AbrtDwlk.h new file mode 100644 index 0000000000000000000000000000000000000000..5b99c04326052da8b6a7db0ae5ddbbd58420f6cf --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13AbrtDwlk.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ13AbrtDwlk.h + * + * Declaration of the Abort Downlink in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV13_ABRT_DWLK_H +#define CRIA_SERV13_ABRT_DWLK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Abort Downlink in-coming command packet. + * SDUx must be in range 2..SDU_ID_MAX + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ13AbrtDwlkValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Abort Downlink in-coming command packet. + * Set action outcome to 'success' iff the SDUx State Machine is in state DOWN_TRANSFER + * @param smDesc the state machine descriptor + */ +void CrIaServ13AbrtDwlkStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Abort Downlink in-coming command packet. + * Send command Abort to SDUx State Machine; set Abort Reason Code to SDU_ABRT_GRD_REQ; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ13AbrtDwlkProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV13_ABRT_DWLK_H */ + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13TrgLrgDataTsfr.c b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13TrgLrgDataTsfr.c new file mode 100644 index 0000000000000000000000000000000000000000..eca06561611145ed58f38b3a75cf2aecadf7409b --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13TrgLrgDataTsfr.c @@ -0,0 +1,149 @@ +/** + * @file CrIaServ13TrgLrgDataTsfr.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Trigger Large Data Transfer in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ13TrgLrgDataTsfr.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> +#include <CrIaPrSm/CrIaSduCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + + +CrFwBool_t CrIaServ13TrgLrgDataTsfrValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* SDUx must be in range 2..SDU_ID_MAX */ + + CrIaServ13TrgLrgDataTsfrParamGetSduId(&sduId, pckt); + + if ((sduId >= 2) && (sduId <= SDU_ID_MAX)) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_SDUID); + return 0; +} + +void CrIaServ13TrgLrgDataTsfrStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + unsigned short sduxState = 0; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set action outcome to 'success' iff the SDUx State Machine is in state INACTIVE */ + + CrIaServ13TrgLrgDataTsfrParamGetSduId(&sduId, pckt); + + switch (sduId) + { + case 2: + sduxState = FwSmGetCurState(smDescSdu2); + break; + case 4: + sduxState = FwSmGetCurState(smDescSdu4); + break; + default: + break; + } + + if (sduxState == CrIaSdu_INACTIVE) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_WR_SDU_M, 0, (unsigned short)sduxState); + + return; +} + +void CrIaServ13TrgLrgDataTsfrProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command StartDownTransfer to SDUx State Machine */ + + CrIaServ13TrgLrgDataTsfrParamGetSduId(&sduId, pckt); + + switch (sduId) + { + case 2: + FwSmMakeTrans(smDescSdu2, StartDownTransfer); + break; + case 4: + FwSmMakeTrans(smDescSdu4, StartDownTransfer); + break; + default: + break; + } + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13TrgLrgDataTsfr.h b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13TrgLrgDataTsfr.h new file mode 100644 index 0000000000000000000000000000000000000000..0ccb5a9390579bd2dc8d2d79b365a728298a23ab --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/InCmd/CrIaServ13TrgLrgDataTsfr.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ13TrgLrgDataTsfr.h + * + * Declaration of the Trigger Large Data Transfer in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV13_TRG_LRG_DATA_TSFR_H +#define CRIA_SERV13_TRG_LRG_DATA_TSFR_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Trigger Large Data Transfer in-coming command packet. + * SDUx must be in range 2..SDU_ID_MAX + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ13TrgLrgDataTsfrValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Trigger Large Data Transfer in-coming command packet. + * Set action outcome to 'success' iff the SDUx State Machine is in state INACTIVE + * @param smDesc the state machine descriptor + */ +void CrIaServ13TrgLrgDataTsfrStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Trigger Large Data Transfer in-coming command packet. + * Send command StartDownTransfer to SDUx State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ13TrgLrgDataTsfrProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV13_TRG_LRG_DATA_TSFR_H */ + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13DwlkAbrt.c b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13DwlkAbrt.c new file mode 100644 index 0000000000000000000000000000000000000000..7b507977845c595d6872669cf4f665bfd294ffc1 --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13DwlkAbrt.c @@ -0,0 +1,35 @@ +/** + * @file CrIaServ13DwlkAbrt.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Downlink Abort Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ13DwlkAbrt.h" + +#include <Services/General/CrIaParamSetter.h> + +#define SDU_ABRT_GRD_REQ 1 + + +void CrIaServ13DwlkAbrtUpdateAction(FwSmDesc_t smDesc) +{ + unsigned short reasonCode = SDU_ABRT_GRD_REQ; + + /* Load the value of Abort Reason Code from the entity which triggered the abort of the SDU transfer */ + CrIaServ13DwlkAbrtParamSetReasonCode(smDesc, reasonCode); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13DwlkAbrt.h b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13DwlkAbrt.h new file mode 100644 index 0000000000000000000000000000000000000000..0e4059bccb98febb324b0f0f28f5f7ac120dff35 --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13DwlkAbrt.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ13DwlkAbrt.h + * + * Declaration of the Downlink Abort Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV13_DWLK_ABRT_H +#define CRIA_SERV13_DWLK_ABRT_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Downlink Abort Report telemetry packet. + * Load the value of Abort Reason Code from the entity which triggered the abort of the SDU transfer + * @param smDesc the state machine descriptor + */ +void CrIaServ13DwlkAbrtUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV13_DWLK_ABRT_H */ + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13FstDwlk.c b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13FstDwlk.c new file mode 100644 index 0000000000000000000000000000000000000000..eca6b25f26b956f70d3e782a777cde1df4bd1d7a --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13FstDwlk.c @@ -0,0 +1,178 @@ +/** + * @file CrIaServ13FstDwlk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the First Downlink Part Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ13FstDwlk.h" + +#include <FwProfile/FwSmConfig.h> +#include <CrIaPrSm/CrIaSduCreate.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaParamSetter.h> + +#include <CrFwCmpData.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* for CrIbMilBusGetLinkCapacity */ +#if (__sparc__) +#include "ibsw_interface.h" +#include <wrap_malloc.h> +#else +#define SRAM1_FLASH_ADDR 0 +#endif + +/* for GetNBits32 */ +#include "Sdp/SdpAlgorithmsImplementation.h" + +#include "../../../IfswDebug.h" +#include "CrIaIasw.h" + + +CrFwBool_t CrIaServ13FstDwlkEnableCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 1; +} + +CrFwBool_t CrIaServ13FstDwlkReadyCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 1; +} + +CrFwBool_t CrIaServ13FstDwlkRepeatCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 0; +} + +void CrIaServ13FstDwlkUpdateAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwOutCmpData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + CrFwPcktLength_t PcktLength; + unsigned int dtSize; + unsigned short sduxBlockCnt, sduxBlockLength, GibOut; + /* const unsigned char * sduxBlockData;*/ + unsigned int sduxRemSize, SduXReadPos; + unsigned int sdu2DownTransferSize; + unsigned int sdu4DownTransferSize; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwOutCmpData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Collect dtSize bytes from SDUx */ + + /* SduId was already set */ + CrIaServ13FstDwlkParamGetSduId(&sduId, pckt); + + switch (sduId) + { + case 2: + /* set SduBlockCnt in packet (should be 1 here) */ + CrIaCopy(SDU2BLOCKCNT_ID, &sduxBlockCnt); + CrIaServ13FstDwlkParamSetSduBlockCount(smDesc, sduxBlockCnt); + + /* we have to retrieve the dtSize and the sduxRemSize + to calculate the size and position of the data. + However, sduxRemSize was modified in the DownTransferDo action, + so we have to restore its old value */ + + PcktLength = CrFwPcktGetLength(pckt); + dtSize = PcktLength - S13_OVERHEAD; + + CrIaCopy(SDU2REMSIZE_ID, &sduxRemSize); + + if (sduxRemSize == 0) + sduxRemSize = dtSize; + else + sduxRemSize += dtSize; + + /* now calculate the start position in the buffer */ + CrIaCopy(S2TOTRANSFERSIZE_ID, &sdu2DownTransferSize); + DEBUGP("FST: dtSize: %d old RemSize: %d downTranferSize %d\n", dtSize, sduxRemSize, sdu2DownTransferSize); + + /* calculate the already transmitted bytes */ + SduXReadPos = sdu2DownTransferSize - sduxRemSize; /* read pos is a byte offset to be added to gibOut*1024 */ + + sduxBlockLength = (unsigned short)dtSize; + CrIaServ13FstDwlkParamSetSduBlockLength(smDesc, sduxBlockLength); + + /* get up to 1 kiB block data from the 32-bit buffer into a local char array */ + CrIaCopy(GIBTOTRANSFER_ID, &GibOut); + + /* set SDU blockdata to gib */ + CrIaServ13FstDwlkParamSetSduBlockData(smDesc, (unsigned char *)GET_ADDR_FROM_RES_OFFSET(GibOut) + SduXReadPos, sduxBlockLength); + + break; + + case 4: + /* set SduBlockCnt in packet (should be 1 here) */ + CrIaCopy(SDU4BLOCKCNT_ID, &sduxBlockCnt); + CrIaServ13FstDwlkParamSetSduBlockCount(smDesc, sduxBlockCnt); + + /* we have to retrieve the dtSize and the sduxRemSize + to calculate the size and position of the data. + However, sduxRemSize was modified in the DownTransferDo action, + so we have to restore its old value */ + + PcktLength = CrFwPcktGetLength(pckt); + dtSize = PcktLength - S13_OVERHEAD; + + CrIaCopy(SDU4REMSIZE_ID, &sduxRemSize); + + if (sduxRemSize == 0) + sduxRemSize = dtSize; + else + sduxRemSize += dtSize; + + + /* now calculate the start position in the buffer */ + CrIaCopy(S4TOTRANSFERSIZE_ID, &sdu4DownTransferSize); + DEBUGP("FST: dtSize: %d old RemSize: %d downTranferSize %d\n", dtSize, sduxRemSize, sdu4DownTransferSize); + + /* calculate the already transmitted bytes */ + SduXReadPos = sdu4DownTransferSize - sduxRemSize; /* read pos is a byte offset */ + + sduxBlockLength = (unsigned short)dtSize; + CrIaServ13FstDwlkParamSetSduBlockLength(smDesc, sduxBlockLength); + + /* set SDU blockdata */ + CrIaServ13FstDwlkParamSetSduBlockData(smDesc, (unsigned char *)SRAM1_FLASH_ADDR + SduXReadPos, sduxBlockLength); + + break; + + default: + break; + } + + return; +} + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13FstDwlk.h b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13FstDwlk.h new file mode 100644 index 0000000000000000000000000000000000000000..f2e7f26a600244ec25d2d1cd8bda5c835397f3b9 --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13FstDwlk.h @@ -0,0 +1,48 @@ +/** + * @file CrIaServ13FstDwlk.h + * + * Declaration of the First Downlink Part Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV13_FST_DWLK_H +#define CRIA_SERV13_FST_DWLK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Enable check of the First Downlink Part Report telemetry packet. + * isEnabled = (SDUx State Machine is in DOWN_TRANSFER) + * @param smDesc the state machine descriptor + * @return the enable check result + */ +CrFwBool_t CrIaServ13FstDwlkEnableCheck(FwSmDesc_t smDesc); + +/** + * Ready check of the First Downlink Part Report telemetry packet. + * IsReady = (dtCapacity is greater than zero) + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrIaServ13FstDwlkReadyCheck(FwSmDesc_t smDesc); + +/** + * Repeat check of the First Downlink Part Report telemetry packet. + * IsRepeat = (sduxBlockCnt is equal to zero) + * @param smDesc the state machine descriptor + * @return the repeat check result + */ +CrFwBool_t CrIaServ13FstDwlkRepeatCheck(FwSmDesc_t smDesc); + +/** + * Update action of the First Downlink Part Report telemetry packet. + * Collect dtSize bytes from SDUx + * @param smDesc the state machine descriptor + */ +void CrIaServ13FstDwlkUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV13_FST_DWLK_H */ + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13IntmDwlk.c b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13IntmDwlk.c new file mode 100644 index 0000000000000000000000000000000000000000..2fbf5a39f8c330ddfb489d0dc63025bf0c2b862b --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13IntmDwlk.c @@ -0,0 +1,178 @@ +/** + * @file CrIaServ13IntmDwlk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Intermediate Downlink Part Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ13IntmDwlk.h" + +#include <FwProfile/FwSmConfig.h> +#include <CrIaPrSm/CrIaSduCreate.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaParamSetter.h> + +#include <CrFwCmpData.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* for CrIbMilBusGetLinkCapacity */ +#if (__sparc__) +#include "ibsw_interface.h" +#include <wrap_malloc.h> +#else +#define SRAM1_FLASH_ADDR 0 +#endif + +/* for GetNBits32 */ +#include "Sdp/SdpAlgorithmsImplementation.h" + +#include "../../../IfswDebug.h" +#include "CrIaIasw.h" + + +CrFwBool_t CrIaServ13IntmDwlkEnableCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 1; +} + +CrFwBool_t CrIaServ13IntmDwlkReadyCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 1; +} + +CrFwBool_t CrIaServ13IntmDwlkRepeatCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 0; +} + +void CrIaServ13IntmDwlkUpdateAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwOutCmpData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + CrFwPcktLength_t PcktLength; + unsigned int dtSize; + unsigned short sduxBlockCnt, sduxBlockLength, GibOut; + /* const unsigned char * sduxBlockData;*/ + unsigned int sduxRemSize, SduXReadPos; + unsigned int sdu2DownTransferSize; + unsigned int sdu4DownTransferSize; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwOutCmpData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Collect dtSize bytes from SDUx */ + + /* SduId was already set */ + CrIaServ13IntmDwlkParamGetSduId(&sduId, pckt); + + switch (sduId) + { + + case 2: + /* set SduBlockCnt in packet */ + CrIaCopy(SDU2BLOCKCNT_ID, &sduxBlockCnt); + CrIaServ13IntmDwlkParamSetSduBlockCount(smDesc, sduxBlockCnt); + + /* we have to retrieve the dtSize and the sduxRemSize + to calculate the size and position of the data. + However, sduxRemSize was modified in the DownTransferDo action, + so we have to restore its old value */ + + PcktLength = CrFwPcktGetLength(pckt); + dtSize = PcktLength - S13_OVERHEAD; + + CrIaCopy(SDU2REMSIZE_ID, &sduxRemSize); + + if (sduxRemSize == 0) + sduxRemSize = dtSize; + else + sduxRemSize += dtSize; + + /* now calculate the start position in the buffer */ + CrIaCopy(S2TOTRANSFERSIZE_ID, &sdu2DownTransferSize); + + /* calculate the already transmitted bytes */ + SduXReadPos = sdu2DownTransferSize - sduxRemSize; /* read pos is a byte offset to be added to gibOut*1024 */ + + sduxBlockLength = (unsigned short)dtSize; + CrIaServ13IntmDwlkParamSetSduBlockLength(smDesc, sduxBlockLength); + + /* get up to 1 kiB block data from the 32-bit buffer into a local char array */ + CrIaCopy(GIBTOTRANSFER_ID, &GibOut); + + /* set SDU blockdata to gib */ + CrIaServ13IntmDwlkParamSetSduBlockData(smDesc, (unsigned char *)GET_ADDR_FROM_RES_OFFSET(GibOut) + SduXReadPos, sduxBlockLength); + + break; + + case 4: + /* set SduBlockCnt in packet */ + CrIaCopy(SDU4BLOCKCNT_ID, &sduxBlockCnt); + CrIaServ13IntmDwlkParamSetSduBlockCount(smDesc, sduxBlockCnt); + + /* we have to retrieve the dtSize and the sduxRemSize + to calculate the size and position of the data. + However, sduxRemSize was modified in the DownTransferDo action, + so we have to restore its old value */ + + PcktLength = CrFwPcktGetLength(pckt); + dtSize = PcktLength - S13_OVERHEAD; + + CrIaCopy(SDU4REMSIZE_ID, &sduxRemSize); + + if (sduxRemSize == 0) + sduxRemSize = dtSize; + else + sduxRemSize += dtSize; + + + /* now calculate the start position in the buffer */ + CrIaCopy(S4TOTRANSFERSIZE_ID, &sdu4DownTransferSize); + + /* calculate the already transmitted bytes */ + SduXReadPos = sdu4DownTransferSize - sduxRemSize; /* read pos is a byte offset to be added to gibOut*1024 */ + + sduxBlockLength = (unsigned short)dtSize; + CrIaServ13IntmDwlkParamSetSduBlockLength(smDesc, sduxBlockLength); + + /* set SDU blockdata */ + CrIaServ13IntmDwlkParamSetSduBlockData(smDesc, (unsigned char *)SRAM1_FLASH_ADDR + SduXReadPos, sduxBlockLength); + + break; + + default: + break; + } + + return; +} + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13IntmDwlk.h b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13IntmDwlk.h new file mode 100644 index 0000000000000000000000000000000000000000..35695ee01ae0ca19c52275bdc403d4d2a760fcea --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13IntmDwlk.h @@ -0,0 +1,40 @@ +/** + * @file CrIaServ13IntmDwlk.h + * + * Declaration of the Intermediate Downlink Part Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV13_INTM_DWLK_H +#define CRIA_SERV13_INTM_DWLK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Enable check of the Intermediate Downlink Part Report telemetry packet. + * isEnabled = (SDUx State Machine is in DOWN_TRANSFER) AND (dtSize is equal to or larger than sduxRemSize) + * @param smDesc the state machine descriptor + * @return the enable check result + */ +CrFwBool_t CrIaServ13IntmDwlkEnableCheck(FwSmDesc_t smDesc); + +/** + * Ready check of the Intermediate Downlink Part Report telemetry packet. + * IsReady = (sduxBlockCnt is greater than zero) AND (dtCapacity is greater than zero) AND (dtSize is smaller than sduxRemSize) + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrIaServ13IntmDwlkReadyCheck(FwSmDesc_t smDesc); + +/** + * Update action of the Intermediate Downlink Part Report telemetry packet. + * Collect dtSize bytes from SDUx + * @param smDesc the state machine descriptor + */ +void CrIaServ13IntmDwlkUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV13_INTM_DWLK_H */ + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13LastDwlk.c b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13LastDwlk.c new file mode 100644 index 0000000000000000000000000000000000000000..bc62abc8100706931d7724617d9b76443b94589e --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13LastDwlk.c @@ -0,0 +1,180 @@ +/** + * @file CrIaServ13LastDwlk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Last Downlink Part Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ13LastDwlk.h" + +#include <FwProfile/FwSmConfig.h> +#include <CrIaPrSm/CrIaSduCreate.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaParamSetter.h> + +#include <CrFwCmpData.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* for CrIbMilBusGetLinkCapacity */ +#if (__sparc__) +#include "ibsw_interface.h" +#include <wrap_malloc.h> +#else +#define SRAM1_FLASH_ADDR 0 +#endif + +/* for GetNBits32 */ +#include "Sdp/SdpAlgorithmsImplementation.h" + +#include "../../../IfswDebug.h" +#include "CrIaIasw.h" + + +CrFwBool_t CrIaServ13LastDwlkEnableCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 1; +} + +CrFwBool_t CrIaServ13LastDwlkReadyCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 1; +} + +CrFwBool_t CrIaServ13LastDwlkRepeatCheck(FwSmDesc_t smDesc) +{ + /* NOTE: empty, because the intended functionality is already contained in the CrIaSduDownTransferDo action */ + + CRFW_UNUSED(smDesc); + return 0; +} + +void CrIaServ13LastDwlkUpdateAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwOutCmpData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char sduId = 0; + CrFwPcktLength_t PcktLength; + unsigned int dtSize; + unsigned short sduxBlockCnt, sduxBlockLength, GibOut; + /* const unsigned char * sduxBlockData;*/ + unsigned int sduxRemSize, SduXReadPos; + unsigned int sdu2DownTransferSize; + unsigned int sdu4DownTransferSize; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwOutCmpData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Collect dtSize or sduxRemSize (whichever is smaller) bytes from SDUx */ + + /* SduId was already set */ + CrIaServ13LastDwlkParamGetSduId(&sduId, pckt); + + switch (sduId) + { + + case 2: + /* set SduBlockCnt in packet */ + CrIaCopy(SDU2BLOCKCNT_ID, &sduxBlockCnt); + CrIaServ13LastDwlkParamSetSduBlockCount(smDesc, sduxBlockCnt); + + /* we have to retrieve the dtSize and the sduxRemSize + to calculate the size and position of the data. + However, sduxRemSize was modified in the DownTransferDo action, + so we have to restore its old value */ + + PcktLength = CrFwPcktGetLength(pckt); + dtSize = PcktLength - S13_OVERHEAD; + + CrIaCopy(SDU2REMSIZE_ID, &sduxRemSize); + + if (sduxRemSize == 0) + sduxRemSize = dtSize; + else + sduxRemSize += dtSize; + + /* now calculate the start position in the buffer */ + CrIaCopy(S2TOTRANSFERSIZE_ID, &sdu2DownTransferSize); + DEBUGP("LAST: dtSize: %d old RemSize: %d downTranferSize %d\n", dtSize, sduxRemSize, sdu2DownTransferSize); + + /* calculate the already transmitted bytes */ + SduXReadPos = sdu2DownTransferSize - sduxRemSize; /* read pos is a byte offset to be added to gibOut*1024 */ + + sduxBlockLength = (unsigned short)dtSize; + CrIaServ13LastDwlkParamSetSduBlockLength(smDesc, sduxBlockLength); + + /* get up to 1 kiB block data from the 32-bit buffer into a local char array */ + CrIaCopy(GIBTOTRANSFER_ID, &GibOut); + + /* set SDU blockdata to gib */ + CrIaServ13LastDwlkParamSetSduBlockData(smDesc, (unsigned char *)GET_ADDR_FROM_RES_OFFSET(GibOut) + SduXReadPos, sduxBlockLength); + + break; + + case 4: + /* set SduBlockCnt in packet */ + CrIaCopy(SDU4BLOCKCNT_ID, &sduxBlockCnt); + CrIaServ13LastDwlkParamSetSduBlockCount(smDesc, sduxBlockCnt); + + /* we have to retrieve the dtSize and the sduxRemSize + to calculate the size and position of the data. + However, sduxRemSize was modified in the DownTransferDo action, + so we have to restore its old value */ + + PcktLength = CrFwPcktGetLength(pckt); + dtSize = PcktLength - S13_OVERHEAD; + + CrIaCopy(SDU4REMSIZE_ID, &sduxRemSize); + + if (sduxRemSize == 0) + sduxRemSize = dtSize; + else + sduxRemSize += dtSize; + + + /* now calculate the start position in the buffer */ + CrIaCopy(S4TOTRANSFERSIZE_ID, &sdu4DownTransferSize); + DEBUGP("LAST: dtSize: %d old RemSize: %d downTranferSize %d\n", dtSize, sduxRemSize, sdu4DownTransferSize); + + /* calculate the already transmitted bytes */ + SduXReadPos = sdu4DownTransferSize - sduxRemSize; /* read pos is a byte offset */ + + sduxBlockLength = (unsigned short)dtSize; + CrIaServ13LastDwlkParamSetSduBlockLength(smDesc, sduxBlockLength); + + /* set SDU blockdata */ + CrIaServ13LastDwlkParamSetSduBlockData(smDesc, (unsigned char *)SRAM1_FLASH_ADDR + SduXReadPos, sduxBlockLength); + + break; + + default: + break; + } + + return; +} + diff --git a/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13LastDwlk.h b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13LastDwlk.h new file mode 100644 index 0000000000000000000000000000000000000000..5f6d0dec1db82d24a861521fb8970ee60f9bcf07 --- /dev/null +++ b/CrIa/src/Services/CrIaServ13LargeDataTransferService/OutRep/CrIaServ13LastDwlk.h @@ -0,0 +1,40 @@ +/** + * @file CrIaServ13LastDwlk.h + * + * Declaration of the Last Downlink Part Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV13_LAST_DWLK_H +#define CRIA_SERV13_LAST_DWLK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Enable check of the Last Downlink Part Report telemetry packet. + * isEnabled = (SDUx State Machine is in DOWN_TRANSFER) + * @param smDesc the state machine descriptor + * @return the enable check result + */ +CrFwBool_t CrIaServ13LastDwlkEnableCheck(FwSmDesc_t smDesc); + +/** + * Ready check of the Last Downlink Part Report telemetry packet. + * IsReady = (sduxBlockCnt is greater than zero) AND (dtCapacity is greater than zero) AND (dtSize is equal to or larger than sduxRemSize) + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrIaServ13LastDwlkReadyCheck(FwSmDesc_t smDesc); + +/** + * Update action of the Last Downlink Part Report telemetry packet. + * Collect dtSize or sduxRemSize (whichever is smaller) bytes from SDUx + * @param smDesc the state machine descriptor + */ +void CrIaServ13LastDwlkUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV13_LAST_DWLK_H */ + diff --git a/CrIa/src/Services/CrIaServ17TestService/InCmd/CrIaServ17PerfConnTest.c b/CrIa/src/Services/CrIaServ17TestService/InCmd/CrIaServ17PerfConnTest.c new file mode 100644 index 0000000000000000000000000000000000000000..dd590d3262a8026cfc82ea3486c9d9b2f08fcfdf --- /dev/null +++ b/CrIa/src/Services/CrIaServ17TestService/InCmd/CrIaServ17PerfConnTest.c @@ -0,0 +1,91 @@ +/** + * @file CrIaServ17PerfConnTest.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Perform Connection Test in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <stdlib.h> + +#include <Pckt/CrFwPckt.h> +#include <OutCmp/CrFwOutCmp.h> + +#include <OutLoader/CrFwOutLoader.h> +#include <OutFactory/CrFwOutFactory.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamSetter.h> + +#include <FwSmConfig.h> +#include <CrFwCmpData.h> + +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> + + +void CrIaServ17PerfConnTestStartAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 1; + + SendTcAccRepSucc(pckt); + SendTcStartRepSucc(pckt); + + return; +} + + + +void CrIaServ17PerfConnTestProgressAction(FwSmDesc_t smDesc) +{ + FwSmDesc_t rep; + CrFwPckt_t pckt; + CrFwCmpData_t *inData; + CrFwInCmdData_t *inSpecificData; + CrFwDestSrc_t source; + CrFwGroup_t group = 1; /* PCAT = 2 */ + + inData = (CrFwCmpData_t *) FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t *) inData->cmpSpecificData; + pckt = inSpecificData->pckt; + source = CrFwPcktGetSrc(pckt); + + rep = CrFwOutFactoryMakeOutCmp(CRIA_SERV17, CRIA_SERV17_LINK_CONN_REP, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + /* Set out component parameters */ + CrFwOutCmpSetGroup(rep, group); + CrFwOutCmpSetDest(rep, source); + + CrFwOutLoaderLoad(rep); + + inData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ17TestService/InCmd/CrIaServ17PerfConnTest.h b/CrIa/src/Services/CrIaServ17TestService/InCmd/CrIaServ17PerfConnTest.h new file mode 100644 index 0000000000000000000000000000000000000000..6fa7fd5afe026afda419d4850ec053b98efdf833 --- /dev/null +++ b/CrIa/src/Services/CrIaServ17TestService/InCmd/CrIaServ17PerfConnTest.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ17PerfConnTest.h + * + * Declaration of the Perform Connection Test in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV17_PERF_CONN_TEST_H +#define CRIA_SERV17_PERF_CONN_TEST_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Perform Connection Test in-coming command packet. + * Set the action outcome to 'success' + * @param smDesc the state machine descriptor + */ +void CrIaServ17PerfConnTestStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Perform Connection Test in-coming command packet. + * Load report (17,2); set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ17PerfConnTestProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV17_PERF_CONN_TEST_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisFdChk.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisFdChk.c new file mode 100644 index 0000000000000000000000000000000000000000..c53f44a71c21f0518f6d9cacbc9a97e5f97be5d9 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisFdChk.c @@ -0,0 +1,227 @@ +/** + * @file CrIaServ191DisFdChk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Disable FdCheck in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191DisFdChk.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +CrFwBool_t CrIaServ191DisFdChkValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The identifier of the FdCheck is in interval: (1..FID_MAX) */ + + CrIaServ191DisFdChkParamGetFdChkId(&FdChkId, pckt); + + if ((FdChkId > 0) && (FdChkId != FDC_EVT2) && (FdChkId <= FID_MAX)) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_FID); + return 0; +} + +void CrIaServ191DisFdChkStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char FdExtEnable = 0; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the FdExtEnable flag of the argument FdCheck is set to TRUE */ + + CrIaServ191DisFdChkParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaCopy(FDCHECKTTMEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaCopy(FDCHECKSDSCEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaCopy(FDCHECKCOMERREXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaCopy(FDCHECKTIMEOUTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaCopy(FDCHECKSAFEMODEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaCopy(FDCHECKALIVEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaCopy(FDCHECKSEMANOEVTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaCopy(FDCHECKSEMLIMITEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaCopy(FDCHECKDPUHKEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaCopy(FDCHECKCENTCONSEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaCopy(FDCHECKRESEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaCopy(FDCHECKSEMCONSEXTEN_ID, &FdExtEnable); + } + + if (FdExtEnable == 1) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_FID_DIS, 0, (unsigned short)FdExtEnable); + + return; +} + +void CrIaServ191DisFdChkProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char FdExtEnable = 0; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the FdExtEnable flag of the argument FdCheck to FALSE */ + + CrIaServ191DisFdChkParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaPaste(FDCHECKTTMEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaPaste(FDCHECKSDSCEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaPaste(FDCHECKCOMERREXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaPaste(FDCHECKTIMEOUTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaPaste(FDCHECKSAFEMODEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaPaste(FDCHECKALIVEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaPaste(FDCHECKSEMANOEVTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaPaste(FDCHECKSEMLIMITEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaPaste(FDCHECKDPUHKEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaPaste(FDCHECKCENTCONSEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaPaste(FDCHECKRESEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaPaste(FDCHECKSEMCONSEXTEN_ID, &FdExtEnable); + } + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisFdChk.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisFdChk.h new file mode 100644 index 0000000000000000000000000000000000000000..472d0fee82cd797456a76eea202dab9c47895a4a --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisFdChk.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ191DisFdChk.h + * + * Declaration of the Disable FdCheck in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_DIS_FD_CHK_H +#define CRIA_SERV191_DIS_FD_CHK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Disable FdCheck in-coming command packet. + * The identifier of the FdCheck is in interval: (1..FID_MAX) + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ191DisFdChkValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Disable FdCheck in-coming command packet. + * Set the action outcome to 'success' iff the FdExtEnable flag of the argument FdCheck is set to TRUE + * @param smDesc the state machine descriptor + */ +void CrIaServ191DisFdChkStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Disable FdCheck in-coming command packet. + * Set the FdExtEnable flag of the argument FdCheck to FALSE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191DisFdChkProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_DIS_FD_CHK_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisRecovProc.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisRecovProc.c new file mode 100644 index 0000000000000000000000000000000000000000..b9d2961497bf9cbb7096b11cb03827bfbe50a9d2 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisRecovProc.c @@ -0,0 +1,227 @@ +/** + * @file CrIaServ191DisRecovProc.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Disable Recovery Procedure in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191DisRecovProc.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +CrFwBool_t CrIaServ191DisRecovProcValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The identifier of the FdCheck is in interval: (1..FID_MAX) */ + + CrIaServ191DisRecovProcParamGetFdChkId(&FdChkId, pckt); + + if ((FdChkId > 0) && (FdChkId != FDC_EVT2) && (FdChkId <= FID_MAX)) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_RID); + return 0; +} + +void CrIaServ191DisRecovProcStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char RpExtEnable = 0; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the RpExtEnable flag of the argument FdCheck is set to TRUE */ + + CrIaServ191DisRecovProcParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaCopy(RPTTMEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaCopy(RPSDSCEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaCopy(RPCOMERREXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaCopy(RPTIMEOUTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaCopy(RPSAFEMODEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaCopy(RPALIVEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaCopy(RPSEMANOEVTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaCopy(RPSEMLIMITEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaCopy(RPDPUHKEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaCopy(RPCENTCONSEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaCopy(RPRESEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaCopy(RPSEMCONSEXTEN_ID, &RpExtEnable); + } + + if (RpExtEnable == 1) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_RID_DIS, 0, (unsigned short)RpExtEnable); + + return; +} + +void CrIaServ191DisRecovProcProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char RpExtEnable = 0; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the RpExtEnable flag of the argument FdCheck to FALSE */ + + CrIaServ191DisRecovProcParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaPaste(RPTTMEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaPaste(RPSDSCEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaPaste(RPCOMERREXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaPaste(RPTIMEOUTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaPaste(RPSAFEMODEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaPaste(RPALIVEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaPaste(RPSEMANOEVTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaPaste(RPSEMLIMITEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaPaste(RPDPUHKEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaPaste(RPCENTCONSEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaPaste(RPRESEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaPaste(RPSEMCONSEXTEN_ID, &RpExtEnable); + } + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisRecovProc.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisRecovProc.h new file mode 100644 index 0000000000000000000000000000000000000000..fdb50f4fb056fa20fcbf1111da71f2d3609d703a --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191DisRecovProc.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ191DisRecovProc.h + * + * Declaration of the Disable Recovery Procedure in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_DIS_RECOV_PROC_H +#define CRIA_SERV191_DIS_RECOV_PROC_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Disable Recovery Procedure in-coming command packet. + * The identifier of the FdCheck is in interval: (1..FID_MAX) + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ191DisRecovProcValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Disable Recovery Procedure in-coming command packet. + * Set the action outcome to 'success' iff the RpExtEnable flag of the argument FdCheck is set to TRUE + * @param smDesc the state machine descriptor + */ +void CrIaServ191DisRecovProcStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Disable Recovery Procedure in-coming command packet. + * Set the RpExtEnable flag of the argument FdCheck to FALSE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191DisRecovProcProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_DIS_RECOV_PROC_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbFdChk.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbFdChk.c new file mode 100644 index 0000000000000000000000000000000000000000..99e68906abd042f16b45a1f19e880c6911051033 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbFdChk.c @@ -0,0 +1,227 @@ +/** + * @file CrIaServ191EnbFdChk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Enable FdCheck in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191EnbFdChk.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +CrFwBool_t CrIaServ191EnbFdChkValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The identifier of the FdCheck is in interval: (1..FID_MAX) */ + + CrIaServ191EnbFdChkParamGetFdChkId(&FdChkId, pckt); + + if ((FdChkId > 0) && (FdChkId != FDC_EVT2) && (FdChkId <= FID_MAX)) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_FID); + return 0; +} + +void CrIaServ191EnbFdChkStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char FdExtEnable = 1; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the FdExtEnable flag of the argument FdCheck is set to FALSE */ + + CrIaServ191EnbFdChkParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaCopy(FDCHECKTTMEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaCopy(FDCHECKSDSCEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaCopy(FDCHECKCOMERREXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaCopy(FDCHECKTIMEOUTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaCopy(FDCHECKSAFEMODEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaCopy(FDCHECKALIVEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaCopy(FDCHECKSEMANOEVTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaCopy(FDCHECKSEMLIMITEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaCopy(FDCHECKDPUHKEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaCopy(FDCHECKCENTCONSEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaCopy(FDCHECKRESEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaCopy(FDCHECKSEMCONSEXTEN_ID, &FdExtEnable); + } + + if (FdExtEnable == 0) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_FID_ENB, 0, (unsigned short)FdExtEnable); + + return; +} + +void CrIaServ191EnbFdChkProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char FdExtEnable = 1; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the FdExtEnable flag of the argument FdCheck to TRUE */ + + CrIaServ191DisFdChkParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaPaste(FDCHECKTTMEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaPaste(FDCHECKSDSCEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaPaste(FDCHECKCOMERREXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaPaste(FDCHECKTIMEOUTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaPaste(FDCHECKSAFEMODEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaPaste(FDCHECKALIVEEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaPaste(FDCHECKSEMANOEVTEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaPaste(FDCHECKSEMLIMITEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaPaste(FDCHECKDPUHKEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaPaste(FDCHECKCENTCONSEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaPaste(FDCHECKRESEXTEN_ID, &FdExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaPaste(FDCHECKSEMCONSEXTEN_ID, &FdExtEnable); + } + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbFdChk.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbFdChk.h new file mode 100644 index 0000000000000000000000000000000000000000..769496c126b927b43d61cc0a8d134a59d9fb4686 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbFdChk.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ191EnbFdChk.h + * + * Declaration of the Enable FdCheck in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_ENB_FD_CHK_H +#define CRIA_SERV191_ENB_FD_CHK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Enable FdCheck in-coming command packet. + * The identifier of the FdCheck is in interval: (1..FID_MAX) + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ191EnbFdChkValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Enable FdCheck in-coming command packet. + * Set the action outcome to 'success' iff the FdExtEnable flag of the argument FdCheck is set to FALSE + * @param smDesc the state machine descriptor + */ +void CrIaServ191EnbFdChkStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Enable FdCheck in-coming command packet. + * Set the FdExtEnable flag of the argument FdCheck to TRUE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191EnbFdChkProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_ENB_FD_CHK_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbRecovProc.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbRecovProc.c new file mode 100644 index 0000000000000000000000000000000000000000..55fce768a3c2c35a5c64ece91b72f541fefe0612 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbRecovProc.c @@ -0,0 +1,227 @@ +/** + * @file CrIaServ191EnbRecovProc.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Enable Recovery Procedure in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191EnbRecovProc.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +CrFwBool_t CrIaServ191EnbRecovProcValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The identifier of the FdCheck is in interval: (1..FID_MAX) */ + + CrIaServ191DisRecovProcParamGetFdChkId(&FdChkId, pckt); + + if ((FdChkId > 0) && (FdChkId != FDC_EVT2) && (FdChkId <= FID_MAX)) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_RID); + return 0; +} + +void CrIaServ191EnbRecovProcStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char RpExtEnable = 1; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the RpExtEnable flag of the argument FdCheck is set to FALSE */ + + CrIaServ191EnbRecovProcParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaCopy(RPTTMEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaCopy(RPSDSCEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaCopy(RPCOMERREXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaCopy(RPTIMEOUTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaCopy(RPSAFEMODEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaCopy(RPALIVEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaCopy(RPSEMANOEVTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaCopy(RPSEMLIMITEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaCopy(RPDPUHKEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaCopy(RPCENTCONSEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaCopy(RPRESEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaCopy(RPSEMCONSEXTEN_ID, &RpExtEnable); + } + + if (RpExtEnable == 0) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_RID_ENB, 0, (unsigned short)RpExtEnable); + + return; +} + +void CrIaServ191EnbRecovProcProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short FdChkId; + unsigned char RpExtEnable = 1; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the RpExtEnable flag of the argument FdCheck to TRUE */ + + CrIaServ191EnbRecovProcParamGetFdChkId(&FdChkId, pckt); + + if (FdChkId == FDC_TS_TEMP) + { + CrIaPaste(RPTTMEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_ILL_CNT) + { + CrIaPaste(RPSDSCEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_COMM) + { + CrIaPaste(RPCOMERREXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_TO) + { + CrIaPaste(RPTIMEOUTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_SM) + { + CrIaPaste(RPSAFEMODEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_ALIVE) + { + CrIaPaste(RPALIVEEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_EVT1) + { + CrIaPaste(RPSEMANOEVTEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_OOL) + { + CrIaPaste(RPSEMLIMITEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_PSDU_OOL) + { + CrIaPaste(RPDPUHKEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_CENT_CONS) + { + CrIaPaste(RPCENTCONSEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_RES) + { + CrIaPaste(RPRESEXTEN_ID, &RpExtEnable); + } + if (FdChkId == FDC_SEM_CONS) + { + CrIaPaste(RPSEMCONSEXTEN_ID, &RpExtEnable); + } + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbRecovProc.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbRecovProc.h new file mode 100644 index 0000000000000000000000000000000000000000..c35d9773e8039e6d98c5a65abef470f0ecf156d4 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191EnbRecovProc.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ191EnbRecovProc.h + * + * Declaration of the Enable Recovery Procedure in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_ENB_RECOV_PROC_H +#define CRIA_SERV191_ENB_RECOV_PROC_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Enable Recovery Procedure in-coming command packet. + * The identifier of the FdCheck is in interval: (1..FID_MAX) + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ191EnbRecovProcValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Enable Recovery Procedure in-coming command packet. + * Set the action outcome to 'success' iff the RpExtEnable flag of the argument FdCheck is set to FALSE + * @param smDesc the state machine descriptor + */ +void CrIaServ191EnbRecovProcStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Enable Recovery Procedure in-coming command packet. + * Set the RpExtEnable flag of the argument FdCheck to TRUE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191EnbRecovProcProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_ENB_RECOV_PROC_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisFdChk.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisFdChk.c new file mode 100644 index 0000000000000000000000000000000000000000..b9a6ccffc9e166dae2328c7c508ade2fd9fa114f --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisFdChk.c @@ -0,0 +1,90 @@ +/** + * @file CrIaServ191GlobDisFdChk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Globally Disable FdChecks in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191GlobDisFdChk.h" + +#include <CrFwCmpData.h> +#include <FwProfile/FwSmConfig.h> + +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ191GlobDisFdChkStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + unsigned char FdGlbEnable; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the FdGlbEnable flag is set to TRUE */ + + CrIaCopy(FDGLBENABLE_ID, &FdGlbEnable); + + if (FdGlbEnable == 1) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_FID_DIS, 0, (unsigned short)FdGlbEnable); + + return; +} + +void CrIaServ191GlobDisFdChkProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char FdGlbEnable = 0; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the FdGlbEnable flag to FALSE */ + + CrIaPaste(FDGLBENABLE_ID, &FdGlbEnable); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisFdChk.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisFdChk.h new file mode 100644 index 0000000000000000000000000000000000000000..65de50647a31acbe417cce7dd5c4e16b2f1d3145 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisFdChk.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ191GlobDisFdChk.h + * + * Declaration of the Globally Disable FdChecks in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_GLOB_DIS_FD_CHK_H +#define CRIA_SERV191_GLOB_DIS_FD_CHK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Globally Disable FdChecks in-coming command packet. + * Set the action outcome to 'success' iff the FdGlbEnable flag is set to TRUE + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobDisFdChkStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Globally Disable FdChecks in-coming command packet. + * Set the FdGlbEnable flag to FALSE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobDisFdChkProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_GLOB_DIS_FD_CHK_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisRecovProc.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisRecovProc.c new file mode 100644 index 0000000000000000000000000000000000000000..4745a55d5cdb78d661d2e5994950e8532c3a94a1 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisRecovProc.c @@ -0,0 +1,90 @@ +/** + * @file CrIaServ191GlobDisRecovProc.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Globally Disable Recovery Procedures in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191GlobDisRecovProc.h" + +#include <CrFwCmpData.h> +#include <FwProfile/FwSmConfig.h> + +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ191GlobDisRecovProcStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + unsigned char RpGlbEnable; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the RpGlbEnable flag is set to TRUE */ + + CrIaCopy(RPGLBENABLE_ID, &RpGlbEnable); + + if (RpGlbEnable == 1) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_RID_DIS, 0, (unsigned short)RpGlbEnable); + + return; +} + +void CrIaServ191GlobDisRecovProcProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char RpGlbEnable = 0; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the RpGlbEnable flag to FALSE */ + + CrIaPaste(RPGLBENABLE_ID, &RpGlbEnable); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisRecovProc.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisRecovProc.h new file mode 100644 index 0000000000000000000000000000000000000000..49af703634be34116350b7f053c63e45a87e304c --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobDisRecovProc.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ191GlobDisRecovProc.h + * + * Declaration of the Globally Disable Recovery Procedures in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_GLOB_DIS_RECOV_PROC_H +#define CRIA_SERV191_GLOB_DIS_RECOV_PROC_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Globally Disable Recovery Procedures in-coming command packet. + * Set the action outcome to 'success' iff the RpGlbEnable flag is set to TRUE + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobDisRecovProcStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Globally Disable Recovery Procedures in-coming command packet. + * Set the RpGlbEnable flag to FALSE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobDisRecovProcProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_GLOB_DIS_RECOV_PROC_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbFdChk.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbFdChk.c new file mode 100644 index 0000000000000000000000000000000000000000..7fef861078f0d96028359837ea9a0cb0ea42e6c0 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbFdChk.c @@ -0,0 +1,90 @@ +/** + * @file CrIaServ191GlobEnbFdChk.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Globally Enable FdChecks in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191GlobEnbFdChk.h" + +#include <CrFwCmpData.h> +#include <FwProfile/FwSmConfig.h> + +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ191GlobEnbFdChkStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + unsigned char FdGlbEnable; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the FdGlbEnable flag is set to FALSE */ + + CrIaCopy(FDGLBENABLE_ID, &FdGlbEnable); + + if (FdGlbEnable == 0) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_FID_ENB, 0, (unsigned short)FdGlbEnable); + + return; +} + +void CrIaServ191GlobEnbFdChkProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char FdGlbEnable = 1; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the FdGlbEnable flag to TRUE */ + + CrIaPaste(FDGLBENABLE_ID, &FdGlbEnable); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbFdChk.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbFdChk.h new file mode 100644 index 0000000000000000000000000000000000000000..934a585b01dca9c8a1badaa1e46bc35fd8a1981a --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbFdChk.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ191GlobEnbFdChk.h + * + * Declaration of the Globally Enable FdChecks in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_GLOB_ENB_FD_CHK_H +#define CRIA_SERV191_GLOB_ENB_FD_CHK_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Globally Enable FdChecks in-coming command packet. + * Set the action outcome to 'success' iff the FdGlbEnable flag is set to FALSE + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobEnbFdChkStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Globally Enable FdChecks in-coming command packet. + * Set the FdGlbEnable flag to TRUE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobEnbFdChkProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_GLOB_ENB_FD_CHK_H */ + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbRecovProc.c b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbRecovProc.c new file mode 100644 index 0000000000000000000000000000000000000000..954002c9c5c6e6841a5fe8d945539ed1e9a7bcc1 --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbRecovProc.c @@ -0,0 +1,90 @@ +/** + * @file CrIaServ191GlobEnbRecovProc.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Globally Enable Recovery Procedures in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ191GlobEnbRecovProc.h" + +#include <CrFwCmpData.h> +#include <FwProfile/FwSmConfig.h> + +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ191GlobEnbRecovProcStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + unsigned char RpGlbEnable; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the RpGlbEnable flag is set to FALSE */ + + CrIaCopy(RPGLBENABLE_ID, &RpGlbEnable); + + if (RpGlbEnable == 0) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_RID_ENB, 0, (unsigned short)RpGlbEnable); + + return; +} + +void CrIaServ191GlobEnbRecovProcProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned char RpGlbEnable = 1; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the RpGlbEnable flag to TRUE */ + + CrIaPaste(RPGLBENABLE_ID, &RpGlbEnable); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbRecovProc.h b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbRecovProc.h new file mode 100644 index 0000000000000000000000000000000000000000..e657071570b5fd5898696e4dd1a5137ba47a36bd --- /dev/null +++ b/CrIa/src/Services/CrIaServ191FDIRService/InCmd/CrIaServ191GlobEnbRecovProc.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ191GlobEnbRecovProc.h + * + * Declaration of the Globally Enable Recovery Procedures in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV191_GLOB_ENB_RECOV_PROC_H +#define CRIA_SERV191_GLOB_ENB_RECOV_PROC_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Globally Enable Recovery Procedures in-coming command packet. + * Set the action outcome to 'success' iff the RpGlbEnable flag is set to FALSE + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobEnbRecovProcStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Globally Enable Recovery Procedures in-coming command packet. + * Set the RpGlbEnable flag to TRUE; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ191GlobEnbRecovProcProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV191_GLOB_ENB_RECOV_PROC_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192AbortDiag.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192AbortDiag.c new file mode 100644 index 0000000000000000000000000000000000000000..4b780abe97a695a4ac5f4f85cfc1a406bdadd59a --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192AbortDiag.c @@ -0,0 +1,121 @@ +/** + * @file CrIaServ192AbortDiag.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Abort DIAGNOSTICS in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192AbortDiag.h" + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConstants.h> +#include <FwProfile/FwSmDCreate.h> +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwSmCore.h> + +/** Cordet FW function definitions */ +#include <CrFramework/OutFactory/CrFwOutFactory.h> +#include <CrFramework/OutLoader/CrFwOutLoader.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> + + +void CrIaServ192AbortDiagStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEMOPER; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE or PRE_SCIENCE and the SEM Operational State Machine is in DIAGNOSTICS */ + + SEMOPER = FwSmGetCurStateEmb(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + + if ((IASW == CrIaIasw_SEM_OFFLINE) || (IASW == CrIaIasw_PRE_SCIENCE)) + { + + switch (SEMOPER) + { + case CrIaSem_DIAGNOSTICS: + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + +void CrIaServ192AbortDiagProgressAction(FwSmDesc_t smDesc) +{ + FwSmDesc_t cmd; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command CMD_DIAGNOSTIC_Disable to the SEM; set the action outcome to 'completed' */ + + + /* Create the CMD_Diagnostics_Disable command for SEM: TC(222,4) */ + cmd = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp (CRSEM_SERV222, CRSEM_SERV222_CMD_DIAG_DISABLE, 0, 0); + if (cmd == NULL) + { + /* handled by Resource FdCheck */ + return; + } + + CrFwOutCmpSetDest(cmd, CR_FW_CLIENT_SEM); + CrFwOutLoaderLoad(cmd); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192AbortDiag.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192AbortDiag.h new file mode 100644 index 0000000000000000000000000000000000000000..e7872f8f16fef9b8e23d286bda16835b8dc0ed12 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192AbortDiag.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192AbortDiag.h + * + * Declaration of the Abort DIAGNOSTICS in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_ABORT_DIAG_H +#define CRIA_SERV192_ABORT_DIAG_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Abort DIAGNOSTICS in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE or PRE_SCIENCE and the SEM Operational State Machine is in DIAGNOSTICS + * @param smDesc the state machine descriptor + */ +void CrIaServ192AbortDiagStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Abort DIAGNOSTICS in-coming command packet. + * Send command CMD_DIAGNOSTIC_Disable to the SEM; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192AbortDiagProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_ABORT_DIAG_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdFull.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdFull.c new file mode 100644 index 0000000000000000000000000000000000000000..f0add471319d5ba783f72f4e26be485df383e45f --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdFull.c @@ -0,0 +1,99 @@ +/** + * @file CrIaServ192GoCcdFull.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Go to CCD FULL in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192GoCcdFull.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ192GoCcdFullStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEMOPER; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM Operational State Machine is in STABILIZE */ + + SEMOPER = FwSmGetCurStateEmb(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + + if (IASW == CrIaIasw_SEM_OFFLINE) + { + + switch (SEMOPER) + { + case CrIaSem_STABILIZE: + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + +void CrIaServ192GoCcdFullProgressAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command GoToCcdFull to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, GoToCcdFull); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdFull.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdFull.h new file mode 100644 index 0000000000000000000000000000000000000000..956ce96b712442ac77cb4502f164b056717886de --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdFull.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192GoCcdFull.h + * + * Declaration of the Go to CCD FULL in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_GO_CCD_FULL_H +#define CRIA_SERV192_GO_CCD_FULL_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Go to CCD FULL in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM Operational State Machine is in STABILIZE + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoCcdFullStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Go to CCD FULL in-coming command packet. + * Send command GoToCcdFull to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoCcdFullProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_GO_CCD_FULL_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdWin.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdWin.c new file mode 100644 index 0000000000000000000000000000000000000000..f6a7520678bcffcaa16ee133ace7e5376c2abab2 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdWin.c @@ -0,0 +1,99 @@ +/** + * @file CrIaServ192GoCcdWin.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Go to CCD WINDOW in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192GoCcdWin.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ192GoCcdWinStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEMOPER; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM Operational State Machine is in STABILIZE */ + + SEMOPER = FwSmGetCurStateEmb(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + + if (IASW == CrIaIasw_SEM_OFFLINE) + { + + switch (SEMOPER) + { + case CrIaSem_STABILIZE: + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + +void CrIaServ192GoCcdWinProgressAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command GoToScience to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, GoToCcdWindow); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdWin.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdWin.h new file mode 100644 index 0000000000000000000000000000000000000000..f166ed332c77d6714555c16a110e9f851f09573f --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoCcdWin.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192GoCcdWin.h + * + * Declaration of the Go to CCD WINDOW in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_GO_CCD_WIN_H +#define CRIA_SERV192_GO_CCD_WIN_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Go to CCD WINDOW in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM Operational State Machine is in STABILIZE + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoCcdWinStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Go to CCD WINDOW in-coming command packet. + * Send command GoToScience to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoCcdWinProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_GO_CCD_WIN_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoDiag.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoDiag.c new file mode 100644 index 0000000000000000000000000000000000000000..21e48eddea88cb8262ba1eb98cc46863928170d2 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoDiag.c @@ -0,0 +1,99 @@ +/** + * @file CrIaServ192GoDiag.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Go to DIAGNOSTICS in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192GoDiag.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ192GoDiagStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEMOPER; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE or PRE_SCIENCE and the SEM Operational State Machine is in STABILIZE */ + + SEMOPER = FwSmGetCurStateEmb(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + + if ((IASW == CrIaIasw_SEM_OFFLINE) || (IASW == CrIaIasw_PRE_SCIENCE)) + { + + switch (SEMOPER) + { + case CrIaSem_STABILIZE: + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + +void CrIaServ192GoDiagProgressAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command GoToDiagnostics to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, GoToDiagnostics); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoDiag.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoDiag.h new file mode 100644 index 0000000000000000000000000000000000000000..f0a6da8f30ea7359e30f53e67f08e9862ead350e --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoDiag.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192GoDiag.h + * + * Declaration of the Go to DIAGNOSTICS in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_GO_DIAG_H +#define CRIA_SERV192_GO_DIAG_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Go to DIAGNOSTICS in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE or PRE_SCIENCE and the SEM Operational State Machine is in STABILIZE + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoDiagStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Go to DIAGNOSTICS in-coming command packet. + * Send command GoToDiagnostics to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoDiagProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_GO_DIAG_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoSafe.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoSafe.c new file mode 100644 index 0000000000000000000000000000000000000000..6988adda578bf85d87a21c24082ec344124e7a7e --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoSafe.c @@ -0,0 +1,99 @@ +/** + * @file CrIaServ192GoSafe.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Go to SAFE in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192GoSafe.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ192GoSafeStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEM; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM State Machine is in OPER */ + + SEM = FwSmGetCurState(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + + if (IASW == CrIaIasw_SEM_OFFLINE) + { + + switch (SEM) + { + case CrIaSem_OPER: + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + +void CrIaServ192GoSafeProgressAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command GoToSafe to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, GoToSafe); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoSafe.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoSafe.h new file mode 100644 index 0000000000000000000000000000000000000000..5dc9ce78f17c6b7df43bedf5b46ff894b5f10eb3 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoSafe.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192GoSafe.h + * + * Declaration of the Go to SAFE in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_GO_SAFE_H +#define CRIA_SERV192_GO_SAFE_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + +/** + * Start action of the Go to SAFE in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM State Machine is in OPER + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoSafeStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Go to SAFE in-coming command packet. + * Send command GoToSafe to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoSafeProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_GO_SAFE_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStab.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStab.c new file mode 100644 index 0000000000000000000000000000000000000000..61af9ddb8771511ef95f3640ae3da1578116c3b6 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStab.c @@ -0,0 +1,104 @@ +/** + * @file CrIaServ192GoStab.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Go to STABILIZE in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192GoStab.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ192GoStabStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEMOPER; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM Operational State Machine is in one of the following states: STANDBY, CCD_WINDOW, CCD_FULL, or DIAGNOSTICS */ + + SEMOPER = FwSmGetCurStateEmb(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + + if (IASW == CrIaIasw_SEM_OFFLINE) + { + + switch (SEMOPER) + { + case CrIaSem_STANDBY: + case CrIaSem_CCD_WINDOW: + case CrIaSem_CCD_FULL: + case CrIaSem_DIAGNOSTICS: + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + + + +void CrIaServ192GoStabProgressAction(FwSmDesc_t __attribute__((unused)) smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command GoToStabilize to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, GoToStabilize); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStab.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStab.h new file mode 100644 index 0000000000000000000000000000000000000000..e25b7d36bc2cae39dbfe8327e15f701bd37293be --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStab.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192GoStab.h + * + * Declaration of the Go to STABILIZE in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_GO_STAB_H +#define CRIA_SERV192_GO_STAB_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Go to STABILIZE in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM Operational State Machine is in one of the following states: STANDBY, CCD_WINDOW, CCD_FULL, or DIAGNOSTICS + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoStabStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Go to STABILIZE in-coming command packet. + * Send command GoToStabilize to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoStabProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_GO_STAB_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStby.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStby.c new file mode 100644 index 0000000000000000000000000000000000000000..d67c01ad1c839a4f4ad7fb190c980f0f48c3110d --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStby.c @@ -0,0 +1,98 @@ +/** + * @file CrIaServ192GoStby.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Go to STANDBY in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192GoStby.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> + + +void CrIaServ192GoStbyStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEM, SEMOPER; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff: (the IASW State Machine is in SEM OFFLINE) && (the SEM State Machine is in OPER or SAFE) */ + /* && (the SEM Operational State Machine is not in STANDBY) */ + + SEM = FwSmGetCurState(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + SEMOPER = FwSmGetCurStateEmb(smDescSem); + + if (((SEM == CrIaSem_SAFE) || (SEM == CrIaSem_OPER)) && (IASW == CrIaIasw_SEM_OFFLINE) && (SEMOPER != CrIaSem_STANDBY)) + { + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + + + +void CrIaServ192GoStbyProgressAction(FwSmDesc_t __attribute__((unused)) smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Send command GoToStandby to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, GoToStandby); + + cmpData->outcome=1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStby.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStby.h new file mode 100644 index 0000000000000000000000000000000000000000..dbdf7e3c9061af95b1bc8f7216ad30d59feff97f --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192GoStby.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192GoStby.h + * + * Declaration of the Go to STANDBY in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_GO_STBY_H +#define CRIA_SERV192_GO_STBY_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Go to STANDBY in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE and the SEM State Machine is in SAFE or OPER + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoStbyStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Go to STANDBY in-coming command packet. + * Send command GoToStandby to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192GoStbyProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_GO_STBY_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOffSem.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOffSem.c new file mode 100644 index 0000000000000000000000000000000000000000..b6a808b92a7ac01d4d27010504e7e58f90bc88e2 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOffSem.c @@ -0,0 +1,92 @@ +/** + * @file CrIaServ192SwchOffSem.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Switch Off SEM in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192SwchOffSem.h" + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ192SwchOffSemStartAction(FwSmDesc_t smDesc) +{ + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE */ + + IASW = FwSmGetCurState(smDescIasw); + + if (IASW == CrIaIasw_SEM_OFFLINE) + { + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + + SendTcStartRepFail(pckt, ACK_WR_IASW_M, 0, (unsigned short)IASW); + + return; +} + + + +void CrIaServ192SwchOffSemProgressAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command SwitchOff to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, SwitchOff); + + cmpData->outcome = 1; + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOffSem.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOffSem.h new file mode 100644 index 0000000000000000000000000000000000000000..eed83da34a4a9d232edf71e75fac6da4f970921b --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOffSem.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192SwchOffSem.h + * + * Declaration of the Switch Off SEM in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_SWCH_OFF_SEM_H +#define CRIA_SERV192_SWCH_OFF_SEM_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Switch Off SEM in-coming command packet. + * Set the action outcome to 'success' iff the IASW State Machine is in SEM_OFFLINE + * @param smDesc the state machine descriptor + */ +void CrIaServ192SwchOffSemStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Switch Off SEM in-coming command packet. + * Send command SwitchOff to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192SwchOffSemProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_SWCH_OFF_SEM_H */ + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOnSem.c b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOnSem.c new file mode 100644 index 0000000000000000000000000000000000000000..63509628a3390ed232daa3e113cf9f0e4d962029 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOnSem.c @@ -0,0 +1,98 @@ +/** + * @file CrIaServ192SwchOnSem.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Switch On SEM in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ192SwchOnSem.h" + +#include <FwProfile/FwSmCore.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <Services/General/CrSemConstants.h> +#include <Services/General/CrIaConstants.h> + +extern FwSmDesc_t smDescSem; + + +void CrIaServ192SwchOnSemStartAction(FwSmDesc_t smDesc) +{ + unsigned short SEM; + unsigned short IASW; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the SEM Unit State Machine is in OFF and the IASW State Machine is in SEM_OFFLINE */ + + SEM = FwSmGetCurState(smDescSem); + IASW = FwSmGetCurState(smDescIasw); + + if ((SEM == CrIaSem_OFF) && (IASW == CrIaIasw_SEM_OFFLINE)) + { + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + + SendTcStartRepFail(pckt, ACK_WR_SEM_M, 0, (unsigned short)IASW); + + return; +} + + +void CrIaServ192SwchOnSemProgressAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command SwitchOn to the SEM Unit State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescSem, SwitchOn); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOnSem.h b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOnSem.h new file mode 100644 index 0000000000000000000000000000000000000000..6a166f6f693be480a4148fb0121de1291c19ccf6 --- /dev/null +++ b/CrIa/src/Services/CrIaServ192SEMManagementService/InCmd/CrIaServ192SwchOnSem.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ192SwchOnSem.h + * + * Declaration of the Switch On SEM in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV192_SWCH_ON_SEM_H +#define CRIA_SERV192_SWCH_ON_SEM_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Switch On SEM in-coming command packet. + * Set the action outcome to 'success' iff the SEM Unit State Machine is in OFF and the IASW State Machine is in SEM_OFFLINE + * @param smDesc the state machine descriptor + */ +void CrIaServ192SwchOnSemStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Switch On SEM in-coming command packet. + * Send command SwitchOn to the SEM Unit State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ192SwchOnSemProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV192_SWCH_ON_SEM_H */ + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193PrepareSci.c b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193PrepareSci.c new file mode 100644 index 0000000000000000000000000000000000000000..fa3e67991fe9001c0ecb6908102d60c9633a3f63 --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193PrepareSci.c @@ -0,0 +1,92 @@ +/** + * @file CrIaServ193PrepareSci.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Prepare Science in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ193PrepareSci.h" + +#include "../../../IfswDebug.h" + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ193PrepareSciStartAction(FwSmDesc_t smDesc) +{ + unsigned short smState; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff IASW State Machine is in STANDBY */ + + smState = FwSmGetCurState(smDescIasw); + + if (smState != CrIaIasw_STANDBY) + { + SendTcStartRepFail(pckt, ACK_WR_IASW_M, 0, (unsigned short)smState); + + cmpData->outcome = 0; + + return; + } + + SendTcStartRepSucc(pckt); + + cmpData->outcome = 1; + + return; +} + +void CrIaServ193PrepareSciProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Send command PrepareScience to the IASW State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescIasw, PrepareScience); + + SendTcTermRepSucc(pckt); + + cmpData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193PrepareSci.h b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193PrepareSci.h new file mode 100644 index 0000000000000000000000000000000000000000..01dbf01dfe85b024085b64ef96e941537286a3cc --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193PrepareSci.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ193PrepareSci.h + * + * Declaration of the Prepare Science in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV193_PREPARE_SCI_H +#define CRIA_SERV193_PREPARE_SCI_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Prepare Science in-coming command packet. + * Set the action outcome to 'success' iff IASW State Machine is in STANDBY + * @param smDesc the state machine descriptor + */ +void CrIaServ193PrepareSciStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Prepare Science in-coming command packet. + * Send command PrepareScience to the IASW State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ193PrepareSciProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV193_PREPARE_SCI_H */ + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartOfflineOper.c b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartOfflineOper.c new file mode 100644 index 0000000000000000000000000000000000000000..51dc14851f75238603f47f5c09a1931290910560 --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartOfflineOper.c @@ -0,0 +1,96 @@ +/** + * @file CrIaServ193StartOfflineOper.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Start Offline Operation in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ193StartOfflineOper.h" + +#include "../../../IfswDebug.h" + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <CrConfigIa/CrFwUserConstants.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ193StartOfflineOperStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + unsigned short smState; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff IASW State Machine is in STANDBY */ + + smState = FwSmGetCurState(smDescIasw); + + if (smState == CrIaIasw_STANDBY) + { + + SendTcStartRepSucc(pckt); + + cmpData-> outcome = CRIA_SUCCESS; + + } + else + { + + SendTcStartRepFail(pckt, ACK_WR_IASW_M, 0, (unsigned short)smState); + + cmpData-> outcome = CRIA_FAILURE; + } + + return; +} + +void CrIaServ193StartOfflineOperProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Send command StartOffline to the IASW State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescIasw, StartOffline); + + SendTcTermRepSucc(pckt); + + cmpData-> outcome = CRIA_SUCCESS; + + return; +} + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartOfflineOper.h b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartOfflineOper.h new file mode 100644 index 0000000000000000000000000000000000000000..87d22de5517d2dddaffaa979d74f3e38ee3995cc --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartOfflineOper.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ193StartOfflineOper.h + * + * Declaration of the Start Offline Operation in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV193_START_OFFLINE_OPER_H +#define CRIA_SERV193_START_OFFLINE_OPER_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Start Offline Operation in-coming command packet. + * Set the action outcome to 'success' iff IASW State Machine is in STANDBY + * @param smDesc the state machine descriptor + */ +void CrIaServ193StartOfflineOperStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Start Offline Operation in-coming command packet. + * Send command StartOffline to the IASW State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ193StartOfflineOperProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV193_START_OFFLINE_OPER_H */ + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartSci.c b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartSci.c new file mode 100644 index 0000000000000000000000000000000000000000..2d41a1bf148a716c80c97da1749444e37deae76f --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartSci.c @@ -0,0 +1,108 @@ +/** + * @file CrIaServ193StartSci.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Start Science in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ193StartSci.h" + +#include "../../../IfswDebug.h" + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ193StartSciStartAction(FwSmDesc_t smDesc) +{ + unsigned short smState; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff IASW State Machine is in PRE_SCIENCE */ + + smState = FwSmGetCurState(smDescIasw); + + if (smState==CrIaIasw_PRE_SCIENCE) + { + + SendTcStartRepSucc(pckt); + + cmpData-> outcome = CRIA_SUCCESS; + + } + else + { + + SendTcStartRepFail(pckt, ACK_WR_IASW_M, 0, (unsigned short)smState); + + cmpData-> outcome = CRIA_FAILURE; + } + + return; +} + +void CrIaServ193StartSciProgressAction(FwSmDesc_t smDesc) +{ + unsigned short smState; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Send command StartScience to the IASW State Machine; set the action outcome to 'completed' if the IASW State Machine goes to SCIENCE and to 'failed' otherwise */ + + /* Send Start Science Command to IASW State Machine */ + FwSmMakeTrans(smDescIasw, StartScience); + + smState = FwSmGetCurState(smDescIasw); + + if (smState==CrIaIasw_SCIENCE) + { + SendTcTermRepSucc(pckt); + + cmpData-> outcome = CRIA_SUCCESS; + } + else + { + SendTcTermRepFail(pckt, ACK_MODE_CHNG_FAILED, 0, (unsigned short)smState); + + cmpData-> outcome = CRIA_FAILURE; + } + + return; +} + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartSci.h b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartSci.h new file mode 100644 index 0000000000000000000000000000000000000000..43a9303cf36536145d3bd5b08a8ee114df48d58d --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StartSci.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ193StartSci.h + * + * Declaration of the Start Science in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV193_START_SCI_H +#define CRIA_SERV193_START_SCI_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Start Science in-coming command packet. + * Set the action outcome to 'success' iff IASW State Machine is in PRE_SCIENCE + * @param smDesc the state machine descriptor + */ +void CrIaServ193StartSciStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Start Science in-coming command packet. + * Send command StartScience to the IASW State Machine; set the action outcome to 'completed' if the IASW State Machine goes to SCIENCE and to 'failed' otherwise + * @param smDesc the state machine descriptor + */ +void CrIaServ193StartSciProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV193_START_SCI_H */ + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopScience.c b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopScience.c new file mode 100644 index 0000000000000000000000000000000000000000..fe5e99123668f684f6902d1162a0085f3065e30c --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopScience.c @@ -0,0 +1,92 @@ +/** + * @file CrIaServ193StopScience.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Stop Science in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ193StopScience.h" + +#include "../../../IfswDebug.h" + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ193StopScienceStartAction(FwSmDesc_t smDesc) +{ + unsigned short smState; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff IASW State Machine is in SCIENCE */ + + smState = FwSmGetCurState(smDescIasw); + + if (smState == CrIaIasw_SCIENCE) + { + SendTcStartRepSucc(pckt); + + cmpData-> outcome = 1; + } + else + { + SendTcStartRepFail(pckt, ACK_WR_IASW_M, 0, (unsigned short)smState); + + cmpData-> outcome = 0; + } + + return; +} + +void CrIaServ193StopScienceProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Send command StopScience to the IASW State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescIasw, StopScience); + + SendTcTermRepSucc(pckt); + + cmpData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopScience.h b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopScience.h new file mode 100644 index 0000000000000000000000000000000000000000..94b6a1c9e0db11fa23438d7ac5a9fe75f6551bce --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopScience.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ193StopScience.h + * + * Declaration of the Stop Science in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV193_STOP_SCIENCE_H +#define CRIA_SERV193_STOP_SCIENCE_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Stop Science in-coming command packet. + * Set the action outcome to 'success' iff IASW State Machine is in SCIENCE + * @param smDesc the state machine descriptor + */ +void CrIaServ193StopScienceStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Stop Science in-coming command packet. + * Send command StopScience to the IASW State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ193StopScienceProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV193_STOP_SCIENCE_H */ + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopSem.c b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopSem.c new file mode 100644 index 0000000000000000000000000000000000000000..5569d03d937d7a61ed5fc0c37f8f1bb52d6b7251 --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopSem.c @@ -0,0 +1,92 @@ +/** + * @file CrIaServ193StopSem.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Stop SEM in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ193StopSem.h" + +#include "../../../IfswDebug.h" + +#include <CrIaIasw.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaPrSm/CrIaIaswCreate.h> + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +void CrIaServ193StopSemStartAction(FwSmDesc_t smDesc) +{ + unsigned short smState; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff IASW State Machine is not in STANDBY */ + + smState = FwSmGetCurState(smDescIasw); + + if (smState != CrIaIasw_STANDBY) + { + SendTcStartRepSucc(pckt); + + cmpData-> outcome = 1; + } + else + { + SendTcStartRepFail(pckt, ACK_WR_IASW_M, 0, (unsigned short)smState); + + cmpData-> outcome = 0; + } + + return; +} + +void CrIaServ193StopSemProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Send command StopSEM to the IASW State Machine; set the action outcome to 'completed' */ + + FwSmMakeTrans(smDescIasw, StopSem); + + SendTcTermRepSucc(pckt); + + cmpData-> outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopSem.h b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopSem.h new file mode 100644 index 0000000000000000000000000000000000000000..f28cbf76a0f1d1df1382b3370e33de83d6be8c93 --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193StopSem.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ193StopSem.h + * + * Declaration of the Stop SEM in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV193_STOP_SEM_H +#define CRIA_SERV193_STOP_SEM_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Stop SEM in-coming command packet. + * Set the action outcome to 'success' iff IASW State Machine is not in STANDBY + * @param smDesc the state machine descriptor + */ +void CrIaServ193StopSemStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Stop SEM in-coming command packet. + * Send command StopSEM to the IASW State Machine; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ193StopSemProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV193_STOP_SEM_H */ + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193SwitchOffIasw.c b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193SwitchOffIasw.c new file mode 100644 index 0000000000000000000000000000000000000000..5f4897714fbaf8ceb8a556ff1d9be401fb7e3994 --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193SwitchOffIasw.c @@ -0,0 +1,87 @@ +/** + * @file CrIaServ193SwitchOffIasw.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Controlled Switch-Off IASW in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ193SwitchOffIasw.h" + +#include <CrFwCmpData.h> +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwPrCore.h> + +#include <CrIaIasw.h> +#include <Services/General/CrIaConstants.h> +#include <IfswUtilities.h> + + +void CrIaServ193SwitchOffIaswStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Start the Controlled Switch-Off Procedure and set the action outcome to 'success' */ + + FwPrStart(prDescCtrldSwitchOffIasw); + + SendTcStartRepSucc(pckt); + + cmpData-> outcome = 1; + + return; +} + +void CrIaServ193SwitchOffIaswProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + unsigned short status; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Execute the Controlled Switch-Off Procedure and set the action outcome to 'continued' if the procedure is still running + and to 'completed' if it has terminated. */ + + FwPrExecute(prDescCtrldSwitchOffIasw); + + status = FwPrIsStarted(prDescCtrldSwitchOffIasw); + + if (status == PR_STARTED) + { + cmpData-> outcome = 2; + } + else + { + SendTcTermRepSucc(pckt); + + cmpData-> outcome = 1; + } + + return; +} + diff --git a/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193SwitchOffIasw.h b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193SwitchOffIasw.h new file mode 100644 index 0000000000000000000000000000000000000000..863fdd394e5852e936a8f1aa1df177743d517b06 --- /dev/null +++ b/CrIa/src/Services/CrIaServ193IASWModeControlService/InCmd/CrIaServ193SwitchOffIasw.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ193SwitchOffIasw.h + * + * Declaration of the Controlled Switch-Off IASW in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV193_SWITCH_OFF_IASW_H +#define CRIA_SERV193_SWITCH_OFF_IASW_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Controlled Switch-Off IASW in-coming command packet. + * Start the Controlled Switch-Off Procedure and set the action outcome to 'success' + * @param smDesc the state machine descriptor + */ +void CrIaServ193SwitchOffIaswStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Controlled Switch-Off IASW in-coming command packet. + * Execute the Controlled Switch-Off Procedure and set the action outcome to 'continued' if the procedure is still running and to 'completed' if it has terminated. + * @param smDesc the state machine descriptor + */ +void CrIaServ193SwitchOffIaswProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV193_SWITCH_OFF_IASW_H */ + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194ResAlgo.c b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194ResAlgo.c new file mode 100644 index 0000000000000000000000000000000000000000..4bc73155edfc2720739c04887ca2473d20cfd132 --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194ResAlgo.c @@ -0,0 +1,130 @@ +/** + * @file CrIaServ194ResAlgo.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Resume Algorithm in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ194ResAlgo.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> +#include <CrIaPrSm/CrIaAlgoCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +CrFwBool_t CrIaServ194ResAlgoValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The algorithm identifier must be in the range 1..MAX_ID_ALGO */ + + CrIaServ194ResAlgoParamGetAlgoId(&algoId, pckt); + + if ((algoId == 0) || (algoId == 2) || (algoId == 7) || (algoId == 10) || (algoId > MAX_ID_ALGO)) + { + SendTcAccRepFail(pckt, ACK_ILL_AID); + return 0; + } + + SendTcAccRepSucc(pckt); + return 1; +} + +void CrIaServ194ResAlgoStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + unsigned short algoState = 65535; /* NOTE: set state undefined */ + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the target algorithm is in state SUSPENDED */ + + CrIaServ194ResAlgoParamGetAlgoId(&algoId, pckt); + algoState = FwSmGetCurState(algoSm[algoId-1]); + + if (algoState == CrIaAlgo_SUSPENDED) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_WR_ALGO_M, 0, (unsigned short)algoState); + + return; +} + +void CrIaServ194ResAlgoProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command Suspend to the Algorithm State Machine of the target algorithm; */ + + CrIaServ194ResAlgoParamGetAlgoId(&algoId, pckt); + + FwSmMakeTrans(algoSm[algoId-1], Resume); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194ResAlgo.h b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194ResAlgo.h new file mode 100644 index 0000000000000000000000000000000000000000..d757627cc53a0a7a8bcac21e0364b31a85667892 --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194ResAlgo.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ194ResAlgo.h + * + * Declaration of the Resume Algorithm in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV194_RES_ALGO_H +#define CRIA_SERV194_RES_ALGO_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Resume Algorithm in-coming command packet. + * The algorithm identifier must be in the range 1..MAX_ID_ALGO + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ194ResAlgoValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Resume Algorithm in-coming command packet. + * Set the action outcome to 'success' iff the target algorithm is in state ACTIVE + * @param smDesc the state machine descriptor + */ +void CrIaServ194ResAlgoStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Resume Algorithm in-coming command packet. + * Send command Suspend to the Algorithm State Machine of the target algorithm; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ194ResAlgoProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV194_RES_ALGO_H */ + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StartAlgo.c b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StartAlgo.c new file mode 100644 index 0000000000000000000000000000000000000000..0df19558746d241b39521aea95f35639a0f1a0ec --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StartAlgo.c @@ -0,0 +1,163 @@ +/** + * @file CrIaServ194StartAlgo.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Start Algorithm in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ194StartAlgo.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> +#include <CrIaPrSm/CrIaAlgoCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + +#include <IfswDebug.h> +#include <byteorder.h> + + +CrFwBool_t CrIaServ194StartAlgoValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + unsigned char len; + unsigned int algoParam; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The algorithm identifier must be in the range 1..MAX_ID_ALGO */ + /* The algorithm parameters must satisfy their constraints */ + + CrIaServ194StartAlgoParamGetAlgoId(&algoId, pckt); + + if ((algoId == 0) || (algoId == 2) || (algoId == 7) || (algoId == 10) || (algoId > MAX_ID_ALGO)) + { + SendTcAccRepFail(pckt, ACK_ILL_AID); + return 0; + } + + /* SAA_EVAL_ALGO: check algorithm parameters */ + + if (algoId == SAA_EVAL_ALGO) + { + len = 4; + + CrIaServ194StartAlgoParamGetAlgoParams((unsigned char *) &algoParam, len, pckt); + + if (algoParam == 0) + { + SendTcAccRepFail(pckt, ACK_ILL_PAR); + return 0; + } + + } + + SendTcAccRepSucc(pckt); + return 1; +} + +void CrIaServ194StartAlgoStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + unsigned short algoState = 65535; /* NOTE: set state undefined */ + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the target algorithm is in state INACTIVE */ + + CrIaServ194StartAlgoParamGetAlgoId(&algoId, pckt); + algoState = FwSmGetCurState(algoSm[algoId-1]); + + if (algoState == CrIaAlgo_INACTIVE) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_WR_ALGO_M, 0, (unsigned short)algoState); + + return; +} + +void CrIaServ194StartAlgoProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + unsigned int initSaaCounter; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Copy the algorithm parameters to the data pool; + send command Start to the Algorithm State Machine of the target algorithm; */ + + CrIaServ194StartAlgoParamGetAlgoId(&algoId, pckt); + + if (algoId == SAA_EVAL_ALGO) + { + /* Get parameter InitSaaCounter and set it in data pool */ + CrIaServ194SaaEvalAlgoParamGetInitSaaCounter(&initSaaCounter, pckt); + CrIaPaste(PINITSAACOUNTER_ID, &initSaaCounter); + } + + FwSmMakeTrans(algoSm[algoId-1], Start); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StartAlgo.h b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StartAlgo.h new file mode 100644 index 0000000000000000000000000000000000000000..bff438289566de2767c9e891152b70ce59a19f54 --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StartAlgo.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ194StartAlgo.h + * + * Declaration of the Start Algorithm in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV194_START_ALGO_H +#define CRIA_SERV194_START_ALGO_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Start Algorithm in-coming command packet. + * The algorithm identifier must be in the range 1..MAX_ID_ALGO and the algorithm parameters must satisfy their constraints + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ194StartAlgoValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Start Algorithm in-coming command packet. + * Set the action outcome to 'success' iff the target algorithm is in state INACTIVE + * @param smDesc the state machine descriptor + */ +void CrIaServ194StartAlgoStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Start Algorithm in-coming command packet. + * Copy the algorithm parameters to the data pool; send command Start to the Algorithm State Machine of the target algorithm; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ194StartAlgoProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV194_START_ALGO_H */ + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StopAlgo.c b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StopAlgo.c new file mode 100644 index 0000000000000000000000000000000000000000..7f461ba7f9d39846caa5060fe17eeb4755f8981c --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StopAlgo.c @@ -0,0 +1,130 @@ +/** + * @file CrIaServ194StopAlgo.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Stop Algorithm in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ194StopAlgo.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> +#include <CrIaPrSm/CrIaAlgoCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +CrFwBool_t CrIaServ194StopAlgoValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The algorithm identifier must be in the range 1..MAX_ID_ALGO */ + + CrIaServ194StopAlgoParamGetAlgoId(&algoId, pckt); + + if ((algoId == 0) || (algoId == 2) || (algoId == 7) || (algoId == 10) || (algoId > MAX_ID_ALGO)) + { + SendTcAccRepFail(pckt, ACK_ILL_AID); + return 0; + } + + SendTcAccRepSucc(pckt); + return 1; +} + +void CrIaServ194StopAlgoStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + unsigned short algoState = 65535; /* NOTE: set state undefined */ + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the target algorithm is in state other than INACTIVE */ + + CrIaServ194StopAlgoParamGetAlgoId(&algoId, pckt); + algoState = FwSmGetCurState(algoSm[algoId-1]); + + if (algoState != CrIaAlgo_INACTIVE) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_WR_ALGO_M, 0, (unsigned short)algoState); + + return; +} + +void CrIaServ194StopAlgoProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command Stop to the Algorithm State Machine of the target algorithm; */ + + CrIaServ194StopAlgoParamGetAlgoId(&algoId, pckt); + + FwSmMakeTrans(algoSm[algoId-1], Stop); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StopAlgo.h b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StopAlgo.h new file mode 100644 index 0000000000000000000000000000000000000000..591928d987c0ff816273708271aa3c41948c738a --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194StopAlgo.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ194StopAlgo.h + * + * Declaration of the Stop Algorithm in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV194_STOP_ALGO_H +#define CRIA_SERV194_STOP_ALGO_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Stop Algorithm in-coming command packet. + * The algorithm identifier must be in the range 1..MAX_ID_ALGO + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ194StopAlgoValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Stop Algorithm in-coming command packet. + * Set the action outcome to 'success' iff the target algorithm is in a state other than INACTIVE + * @param smDesc the state machine descriptor + */ +void CrIaServ194StopAlgoStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Stop Algorithm in-coming command packet. + * Send command Stop to the Algorithm State Machine of the target algorithm; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ194StopAlgoProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV194_STOP_ALGO_H */ + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194SusAlgo.c b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194SusAlgo.c new file mode 100644 index 0000000000000000000000000000000000000000..8a84c28106b029389abc8ac7a23ad3a3d3749f9c --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194SusAlgo.c @@ -0,0 +1,130 @@ +/** + * @file CrIaServ194SusAlgo.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Suspend Algorithm in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ194SusAlgo.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <Services/General/CrIaParamGetter.h> +#include <CrIaPrSm/CrIaAlgoCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> + + +CrFwBool_t CrIaServ194SusAlgoValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The algorithm identifier must be in the range 1..MAX_ID_ALGO */ + + CrIaServ194SusAlgoParamGetAlgoId(&algoId, pckt); + + if ((algoId == 0) || (algoId == 2) || (algoId == 7) || (algoId == 10) || (algoId > MAX_ID_ALGO)) + { + SendTcAccRepFail(pckt, ACK_ILL_AID); + return 0; + } + + SendTcAccRepSucc(pckt); + return 1; +} + +void CrIaServ194SusAlgoStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + unsigned short algoState = 65535; /* NOTE: set state undefined */ + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' iff the target algorithm is in state ACTIVE */ + + CrIaServ194SusAlgoParamGetAlgoId(&algoId, pckt); + algoState = FwSmGetCurState(algoSm[algoId-1]); + + if (algoState == CrIaAlgo_ACTIVE) + { + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; + } + + cmpData->outcome = 0; + SendTcStartRepFail(pckt, ACK_WR_ALGO_M, 0, (unsigned short)algoState); + + return; +} + +void CrIaServ194SusAlgoProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + unsigned short algoId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Send command Suspend to the Algorithm State Machine of the target algorithm; */ + + CrIaServ194SusAlgoParamGetAlgoId(&algoId, pckt); + + FwSmMakeTrans(algoSm[algoId-1], Suspend); + + /* Set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194SusAlgo.h b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194SusAlgo.h new file mode 100644 index 0000000000000000000000000000000000000000..68e0448910e3073eb02a876157f99e9804587ee4 --- /dev/null +++ b/CrIa/src/Services/CrIaServ194AlgorithmControlService/InCmd/CrIaServ194SusAlgo.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ194SusAlgo.h + * + * Declaration of the Suspend Algorithm in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV194_SUS_ALGO_H +#define CRIA_SERV194_SUS_ALGO_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Suspend Algorithm in-coming command packet. + * The algorithm identifier must be in the range 1..MAX_ID_ALGO + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ194SusAlgoValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Suspend Algorithm in-coming command packet. + * Set the action outcome to 'success' iff the target algorithm is in state ACTIVE + * @param smDesc the state machine descriptor + */ +void CrIaServ194SusAlgoStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Suspend Algorithm in-coming command packet. + * Send command Suspend to the Algorithm State Machine of the target algorithm; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ194SusAlgoProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV194_SUS_ALGO_H */ + diff --git a/CrIa/src/Services/CrIaServ195HeartbeatService/OutRep/CrIaServ195HbRep.c b/CrIa/src/Services/CrIaServ195HeartbeatService/OutRep/CrIaServ195HbRep.c new file mode 100644 index 0000000000000000000000000000000000000000..07aadcca7577536452c303e596b40e7d7e7d8dbd --- /dev/null +++ b/CrIa/src/Services/CrIaServ195HeartbeatService/OutRep/CrIaServ195HbRep.c @@ -0,0 +1,83 @@ +/** + * @file CrIaServ195HbRep.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Heartbeat Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ195HbRep.h" + +#include <Services/General/CrIaParamSetter.h> +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <CrIaIasw.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +CrFwBool_t toggleFlag = 0; + + +CrFwBool_t CrIaServ195HbRepReadyCheck(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned char isEnabled; + + /* If (HEARTBEAT_ENABLED is TRUE) then isReady is true once every 8 cycles; else isReady is FALSE */ + + CrIaCopy(HEARTBEAT_ENABLED_ID, &isEnabled); + + if (!isEnabled) + return 0; + + if (FwSmGetExecCnt(smDesc) % 8 == 0) + return 1; + + return 0; +} + + +void CrIaServ195HbRepUpdateAction(FwSmDesc_t smDesc) +{ + unsigned char hbSem; + unsigned short hbData; + + /* Toggle parameter alternates between HEARTBEAT_D1 and HEARTBEAT_D2 */ + if(toggleFlag) + { + CrIaCopy(HEARTBEAT_D2_ID, &hbData); + toggleFlag = 0; + } + else + { + CrIaCopy(HEARTBEAT_D1_ID, &hbData); + toggleFlag = 1; + } + + /* SEM Heater Control Status is OFF if the + * SEM State Machine is in OPER and the SEM Operation State + * Machine is in a state other than STANDBY + */ + + hbSem = getHbSem(); + /* Set HbSem Flag in data pool */ + CrIaPaste(HBSEM_ID, &hbSem); + + CrIaServ195HbRepParamSetHbData(smDesc, hbData); + + CrIaServ195HbRepParamSetHbSEM(smDesc, hbSem); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ195HeartbeatService/OutRep/CrIaServ195HbRep.h b/CrIa/src/Services/CrIaServ195HeartbeatService/OutRep/CrIaServ195HbRep.h new file mode 100644 index 0000000000000000000000000000000000000000..6eeeadbf4e2f1b7c0038175f906a039b6ca34f4e --- /dev/null +++ b/CrIa/src/Services/CrIaServ195HeartbeatService/OutRep/CrIaServ195HbRep.h @@ -0,0 +1,32 @@ +/** + * @file CrIaServ195HbRep.h + * + * Declaration of the Heartbeat Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV195_HB_REP_H +#define CRIA_SERV195_HB_REP_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Ready check of the Heartbeat Report telemetry packet. + * If (HEARTBEAT_ENABLED is TRUE) then isReady is true once every 8 cycles; else isReady is FALSE + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrIaServ195HbRepReadyCheck(FwSmDesc_t smDesc); + +/** + * Update action of the Heartbeat Report telemetry packet. + * Toggle parameter alternates between HEARTBEAT_D1 and HEARTBEAT_D2; SEM Heater Control Status is OFF iff the SEM State Machine is in OPER and the SEM Operation State Machine is in a state other than STANDBY + * @param smDesc the state machine descriptor + */ +void CrIaServ195HbRepUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV195_HB_REP_H */ + diff --git a/CrIa/src/Services/CrIaServ196AOCSService/InCmd/CrIaServ196StarMapCmd.c b/CrIa/src/Services/CrIaServ196AOCSService/InCmd/CrIaServ196StarMapCmd.c new file mode 100644 index 0000000000000000000000000000000000000000..947ac52746c4a6854e6385222851545465da4b02 --- /dev/null +++ b/CrIa/src/Services/CrIaServ196AOCSService/InCmd/CrIaServ196StarMapCmd.c @@ -0,0 +1,289 @@ +/** + * @file CrIaServ196StarMapCmd.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Star Map Command in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ196StarMapCmd.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> + +#include <IfswDebug.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamGetter.h> + +#include <Sdp/SdpAlgorithmsImplementation.h> /* for getnbits32 */ + +#define SAFETARGETDIST 110000 /* max in imaging area is 105150/102350 */ + + +CrFwBool_t CrIaServ196StarMapCmdValidityCheck(FwPrDesc_t prDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + unsigned char skyPattern[1024]; + unsigned int TargetLocX, TargetLocY; + unsigned short acqAlgoId; + + DEBUGP("CrIaServ196StarMapCmdValidityCheck: TBD\n"); + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* check range of acquisition algo ID */ + CrIaServ196StarMapCmdParamGetAcqAlgoId(&acqAlgoId, pckt); + + if ((acqAlgoId < ACQALGOID_NOMINAL) || (acqAlgoId > ACQALGOID_DUMMY)) + { + SendTcAccRepFail(pckt, ACK_ILL_SMAP); + return 0; + } + + /* the following lines check if Target Location is within a safe distance */ + CrIaServ196StarMapCmdParamGetSkyPattern(skyPattern, pckt); + + /* tglocx 24 */ + GetNBits32 (&TargetLocX, 0, 24, (unsigned int *)skyPattern); + + /* tglocy 24 */ + GetNBits32 (&TargetLocY, 24, 24, (unsigned int *)skyPattern); + + if (TargetLocX > SAFETARGETDIST) + { + SendTcAccRepFail(pckt, ACK_ILL_SMAP); + return 0; + } + if (TargetLocY > SAFETARGETDIST) + { + SendTcAccRepFail(pckt, ACK_ILL_SMAP); + return 0; + } + + SendTcAccRepSucc(pckt); + + return 1; +} + +void CrIaServ196StarMapCmdStartAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' */ + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; +} + +void CrIaServ196StarMapCmdProgressAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + unsigned int ObservationId, TaSpare32; + unsigned short TaAlgoId; + unsigned char skyPattern[1024]; + + unsigned int k; + + unsigned int uint32, bitoff; + unsigned short uint16, NrOfStars; + unsigned char uint8; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Copy the star pattern, the observation identifier and the target star to the data pool; set the action outcome to 'completed' */ + DEBUGP("CrIaServ196StarMapCmdProgressAction: Copy the star pattern, the observation identifier and the target star to the data pool; set the action outcome to 'completed'.\n"); + + CrIaServ196StarMapCmdParamGetObservationId(&ObservationId, pckt); + CrIaPaste(OBSERVATIONID_ID, &ObservationId); + + CrIaServ196StarMapCmdParamGetAcqAlgoId(&TaAlgoId, pckt); + CrIaPaste(TAACQALGOID_ID, &TaAlgoId); + + CrIaServ196StarMapCmdParamGetSPARE(&TaSpare32, pckt); + CrIaPaste(TASPARE32_ID, &TaSpare32); /* was TARGETSTAR, but is no longer needed */ + + /* + read the inner parameters from the sky pattern + */ + CrIaServ196StarMapCmdParamGetSkyPattern(skyPattern, pckt); + + /* tglocx 24 */ + bitoff = 0; + GetNBits32 (&uint32, bitoff, 24, (unsigned int *)skyPattern); + bitoff += 24; + CrIaPaste(TARGETLOCATIONX_ID, &uint32); + + /* tglocy 24 */ + GetNBits32 (&uint32, bitoff, 24, (unsigned int *)skyPattern); + bitoff += 24; + CrIaPaste(TARGETLOCATIONY_ID, &uint32); + + /* algoid 8 */ + GetNBits32 (&uint32, bitoff, 8, (unsigned int *)skyPattern); + bitoff += 8; + uint16 = (unsigned short)uint32; /* NOTE: algoid is uchar in the packet, but enum in the DP, hence the cast */ + CrIaPaste(TAALGOID_ID, &uint16); + + /* timing1 ushort */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TATIMINGPAR1_ID, &uint16); + + /* timing2 ushort */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TATIMINGPAR2_ID, &uint16); + + /* dist ushort */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TADISTANCETHRD_ID, &uint16); + + /* iter uchar in SM, but ushort in DP */ + GetNBits32 (&uint32, bitoff, 8, (unsigned int *)skyPattern); + bitoff += 8; + uint16 = (unsigned char)uint32; + CrIaPaste(TAITERATIONS_ID, &uint16); + + /* rebinfact ushort */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TAREBINNINGFACT_ID, &uint16); + + /* detthrd ushort */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TADETECTIONTHRD_ID, &uint16); + + /* se_reduced_extr ushort */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TASEREDUCEDEXTR_ID, &uint16); + + /* se reduced radius 16 */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TASEREDUCEDRADIUS_ID, &uint16); + + /* se tolerance 16 */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TASETOLERANCE_ID, &uint16); + + /* mva tolerance 16 */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TAMVATOLERANCE_ID, &uint16); + + /* ama tolerance 16 */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TAAMATOLERANCE_ID, &uint16); + + /* pointing uncertainty */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + CrIaPaste(TAPOINTUNCERT_ID, &uint16); + + /* + copy data pattern parameters + */ + + /* targetsig 32 */ + GetNBits32 (&uint32, bitoff, 32, (unsigned int *)skyPattern); + bitoff += 32; + CrIaPaste(TATARGETSIG_ID, &uint32); + + /* nrofstars 16 */ + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + NrOfStars = (unsigned short)uint32; + CrIaPaste(TANROFSTARS_ID, &NrOfStars); + + /* + copy stars pattern + */ + + /* stars... each one has a 16 bit x and y */ + for (k=0; (k < 2*NrOfStars) && (k < 2*MAXNROFSTARS); k++) + { + GetNBits32 (&uint32, bitoff, 16, (unsigned int *)skyPattern); + bitoff += 16; + uint16 = (unsigned short)uint32; + + uint8 = uint16 >> 8; + CrIaPasteArrayItem (STARMAP_ID, &uint8, 2*k); + uint8 = uint16 & 0xff; + CrIaPasteArrayItem (STARMAP_ID, &uint8, 2*k+1); + } + + /* Mantis 2135: reset visit counters */ + uint16 = 0; + CrIaPaste(CE_COUNTER_ID, &uint16); + + uint32 = 0; + CrIaPaste(SDSCOUNTER_ID, &uint32); + + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ196AOCSService/InCmd/CrIaServ196StarMapCmd.h b/CrIa/src/Services/CrIaServ196AOCSService/InCmd/CrIaServ196StarMapCmd.h new file mode 100644 index 0000000000000000000000000000000000000000..3f4cec7cedca1e7963a65e4294581237047bfb73 --- /dev/null +++ b/CrIa/src/Services/CrIaServ196AOCSService/InCmd/CrIaServ196StarMapCmd.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ196StarMapCmd.h + * + * Declaration of the Star Map Command in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV196_STAR_MAP_CMD_H +#define CRIA_SERV196_STAR_MAP_CMD_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Star Map Command in-coming command packet. + * TBD + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ196StarMapCmdValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Star Map Command in-coming command packet. + * Set the action outcome to 'success' iff the TBD checks on the command parameters are passed. + * @param smDesc the state machine descriptor + */ +void CrIaServ196StarMapCmdStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Star Map Command in-coming command packet. + * Copy the star pattern, the observation identifier and the target star to the data pool; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ196StarMapCmdProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV196_STAR_MAP_CMD_H */ + diff --git a/CrIa/src/Services/CrIaServ196AOCSService/OutRep/CrIaServ196AocsRep.c b/CrIa/src/Services/CrIaServ196AOCSService/OutRep/CrIaServ196AocsRep.c new file mode 100644 index 0000000000000000000000000000000000000000..f08181a270d65204e7e0c17e4fbb481eb855a36e --- /dev/null +++ b/CrIa/src/Services/CrIaServ196AOCSService/OutRep/CrIaServ196AocsRep.c @@ -0,0 +1,179 @@ +/** + * @file CrIaServ196AocsRep.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the AOCS Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ196AocsRep.h" +#include <FwSmConfig.h> +#include <FwPrCore.h> + +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrIaParamSetter.h> + +#include <CrConfigIa/CrFwCmpData.h> +#include <CrConfigIa/CrFwUserConstants.h> + +#include <CrFwTime.h> + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <IfswUtilities.h> +#include <CrIaPrSm/CrIaIaswCreate.h> +#include <CrIaPrSm/CrIaAlgoCreate.h> +#include <Ta/TargetAcquisition.h> +#include <EngineeringAlgorithms.h> + +#include <IfswDebug.h> + +#if !(__sparc__) +#include <byteorder.h> +#endif + + +CrFwBool_t CrIaServ196AocsRepEnableCheck(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned short iaswState; + + iaswState = FwSmGetCurState(smDescIasw); + + if (iaswState != CrIaIasw_SCIENCE) + return 0; + + return 1; +} + + +CrFwBool_t CrIaServ196AocsRepReadyCheck(FwSmDesc_t __attribute__((unused)) smDesc) +{ + unsigned int imageCycleCnt; + unsigned short algoCent0State, algoCent1State, algoAcqState; + static unsigned char Ta_lastsig; + + /* isReady is true in the cycles in which the Centroiding or Acquisition Algorithm has computed a new centroid. */ + + /* check if Centroiding Algorithm or Acquisition Algorithm is ACTIVE */ + algoCent0State = FwSmGetCurState(smDescAlgoCent0); + algoCent1State = FwSmGetCurState(smDescAlgoCent1); + algoAcqState = FwSmGetCurState(smDescAlgoAcq1); + + + if (algoAcqState != CrIaAlgo_ACTIVE) + { + if ((algoCent0State != CrIaAlgo_ACTIVE) && (algoCent1State != CrIaAlgo_ACTIVE)) + { + /* return if both are inactive */ + return 0; + } + else /* only centroid algorithm is active */ + { + /* true in cycles in which the centroiding algo has computed a new centroid */ + /* Mantis 2180 */ + if (S196Flag == 0) + return 0; + } + } + else /* target acquisition algorithm is active */ + { + /* Mantis 2226: reset the toggle at the beginning */ + CrIaCopy(IMAGECYCLECNT_ID, &imageCycleCnt); + if (imageCycleCnt == 0xffffffff) + { + Ta_lastsig = signal_Ta; + return 0; + } + + if (signal_Ta == Ta_lastsig) + { + /* no toggle in signal_Ta means no new centroid */ + return 0; + } + else + { + Ta_lastsig = signal_Ta; + } + } + + return 1; +} + + +void CrIaServ196AocsRepUpdateAction(FwSmDesc_t smDesc) +{ + int offsetX, offsetY; + unsigned short startIntegFine, endIntegFine, dataCadence; + unsigned int targetLocX, targetLocY, startIntegCoarse, endIntegCoarse; + unsigned char validityStatus, centValProcOutput; + + /* load the report parameters from the data pool and feed into the packet */ + + /* NOTE: the centroid validity is already entered in the Centroiding and TargetAcquisition functions */ + + /* Run the Centroid Validity Procedure */ + FwPrRun(prDescCentVal); + + /* OffsetX, 24 bits */ + CrIaCopy (OFFSETX_ID, &offsetX); + CrIaServ196AocsRepParamSetOffsetX (smDesc, offsetX); + + /* OffsetY, 24 bits */ + CrIaCopy (OFFSETY_ID, &offsetY); + CrIaServ196AocsRepParamSetOffsetY (smDesc, offsetY); + + /* TargetLocationX, 24 bits */ + CrIaCopy(TARGETLOCATIONX_ID, &targetLocX); + CrIaServ196AocsRepParamSetTargetLocationX (smDesc, targetLocX); + + /* TargetLocationY, 24 bits */ + CrIaCopy(TARGETLOCATIONY_ID, &targetLocY); + CrIaServ196AocsRepParamSetTargetLocationY (smDesc, targetLocY); + + /* IntegStartTimeCrs, 32 bits */ + CrIaCopy(INTEGSTARTTIMECRS_ID, &startIntegCoarse); + CrIaServ196AocsRepParamSetIntegStartTimeCrs (smDesc, startIntegCoarse); + + /* IntegStartTimeFine, 16 bits */ + CrIaCopy(INTEGSTARTTIMEFINE_ID, &startIntegFine); + CrIaServ196AocsRepParamSetIntegStartTimeFine (smDesc, startIntegFine); + + /* IntegEndTimeCrs, 32 bits */ + CrIaCopy(INTEGENDTIMECRS_ID, &endIntegCoarse); + CrIaServ196AocsRepParamSetIntegEndTimeCrs (smDesc, endIntegCoarse); + + /* IntegEndTimeFine, 16 bits */ + CrIaCopy(INTEGENDTIMEFINE_ID, &endIntegFine); + CrIaServ196AocsRepParamSetIntegEndTimeFine (smDesc, endIntegFine); + + /* DataCadence, 16 bits */ + /* NOTE: datacadence is = SEM repetition time */ + CrIaCopy(DATACADENCE_ID, &dataCadence); + CrIaServ196AocsRepParamSetCentroidDataCadence (smDesc, dataCadence); + + /* ValidityStatus, 8 bits */ + CrIaCopy(CENTVALPROCOUTPUT_ID, ¢ValProcOutput); + if (centValProcOutput == 0xEE) + { + CrIaServ196AocsRepParamSetValidityStatus (smDesc, CEN_INV_INPUT); + } + else + { + CrIaCopy(VALIDITYSTATUS_ID, &validityStatus); + CrIaServ196AocsRepParamSetValidityStatus (smDesc, validityStatus); + } + + return; +} + diff --git a/CrIa/src/Services/CrIaServ196AOCSService/OutRep/CrIaServ196AocsRep.h b/CrIa/src/Services/CrIaServ196AOCSService/OutRep/CrIaServ196AocsRep.h new file mode 100644 index 0000000000000000000000000000000000000000..45d563241a68dc4580949ca71dbdfb9387ef60fe --- /dev/null +++ b/CrIa/src/Services/CrIaServ196AOCSService/OutRep/CrIaServ196AocsRep.h @@ -0,0 +1,40 @@ +/** + * @file CrIaServ196AocsRep.h + * + * Declaration of the AOCS Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV196_AOCS_REP_H +#define CRIA_SERV196_AOCS_REP_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Enable check of the AOCS Report telemetry packet. + * IsEnabled = (IASW State Machine is in SCIENCE) + * @param smDesc the state machine descriptor + * @return the enable check result + */ +CrFwBool_t CrIaServ196AocsRepEnableCheck(FwSmDesc_t smDesc); + +/** + * Ready check of the AOCS Report telemetry packet. + * isReady is true in the cycles in which the Centroiding or Acquisition Algorithm has computed a new centroid. + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrIaServ196AocsRepReadyCheck(FwSmDesc_t smDesc); + +/** + * Update action of the AOCS Report telemetry packet. + * Run Centroid Validity Procedure and then load report parameters from data pool + * @param smDesc the state machine descriptor + */ +void CrIaServ196AocsRepUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV196_AOCS_REP_H */ + diff --git a/CrIa/src/Services/CrIaServ197BootReportService/InCmd/CrIaServ197RepBoot.c b/CrIa/src/Services/CrIaServ197BootReportService/InCmd/CrIaServ197RepBoot.c new file mode 100644 index 0000000000000000000000000000000000000000..623d1ca721f8e31b78ccc959c73d37cfa34e8518 --- /dev/null +++ b/CrIa/src/Services/CrIaServ197BootReportService/InCmd/CrIaServ197RepBoot.c @@ -0,0 +1,351 @@ +/** + * @file CrIaServ197RepBoot.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Generate Boot Report in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ197RepBoot.h" + +#include "CrFwCmpData.h" +#include "CrFramework/OutFactory/CrFwOutFactory.h" +#include "CrFramework/OutLoader/CrFwOutLoader.h" +#include "CrFramework/OutCmp/CrFwOutCmp.h" + +#include "FwProfile/FwSmConfig.h" +#include "FwProfile/FwPrConfig.h" + +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaConstants.h> +#include <CrIaInCmp.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <IfswUtilities.h> /* for memory IDs */ +#include <stdlib.h> /* for NULL */ +#include <string.h> /* for memcpy */ + +#if(__sparc__) +#include "ibsw_interface.h" +#include "iwf_fpga.h" +#include "exchange_area.h" +#else +#define ERROR_LOG_MAX_ENTRIES 64 +#define SIZEOF_ERR_LOG_ENTRY 20 +#endif + + +CrFwBool_t CrIaServ197RepBootValidityCheck(FwPrDesc_t prDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + unsigned short dpuMemoryId; + unsigned int startAddress; + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + CrIaServ197RepBootParamGetDpuMemoryId (&dpuMemoryId, pckt); + CrIaServ197RepBootParamGetStartAddress (&startAddress, pckt); + + /* check command parameters */ + if (dpuMemoryId == DPU_RAM) + { + SendTcAccRepSucc(pckt); + return 1; + } + + if (dpuMemoryId == DPU_FLASH1) + { + /* every 32 bit address is fine */ + (void) startAddress; + SendTcAccRepSucc(pckt); + return 1; + } + + if (dpuMemoryId == DPU_FLASH2) + { + /* every 32 bit address is fine */ + (void) startAddress; + SendTcAccRepSucc(pckt); + return 1; + } + + if (dpuMemoryId == DPU_FLASH3) + { + /* every 32 bit address is fine */ + (void) startAddress; + SendTcAccRepSucc(pckt); + return 1; + } + + if (dpuMemoryId == DPU_FLASH4) + { + /* every 32 bit address is fine */ + (void) startAddress; + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_MEM_ID); + return 0; +} + +void CrIaServ197RepBootStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; +} + +void CrIaServ197RepBootProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwPckt_t pckt; + + FwSmDesc_t rep; + CrFwGroup_t group = 1; /* group 1 PCAT = 2 */ + + unsigned char resetType=0, dpuMode=0, dpuSwActive=0, dpuWatchdogStatus=0; + unsigned char dpuUnit=2, dpuResetType=0, timeSyncStatus=0, bootReportSent=0; + unsigned char spare1=0, semError=0, semOn=0, dpuScLinkStatus=0; + unsigned char dpuMilbusCoreEx=0, dpuMilbusSyncDw=0, dpuMilbusSyncTo=0, dpuSemLinkStatus=0; + unsigned char dpuSemLinkState=0, trapCore1=0, trapCore2=0; + + unsigned short spare2=0; + unsigned short dpuMemoryId=0; + + unsigned int psrRegCore1=0, wimRegCore1=0, pcRegCore1=0, npcRegCore1=0; + unsigned int fsrRegCore1=0, psrRegCore2=0, wimRegCore2=0, pcRegCore2=0; + unsigned int npcRegCore2=0, fsrRegCore2=0, ahbStatusReg=0, ahbFailingAddrReg=0; + unsigned int startAddress=0; + + const unsigned char *resetTime = NULL; + const unsigned char *pcHistoryCore1 = NULL; + const unsigned char *pcHistoryCore2 = NULL; + const unsigned char *errLogInfo = NULL; + + unsigned char charBuf[ERROR_LOG_MAX_ENTRIES * SIZEOF_ERR_LOG_ENTRY]; + + struct exchange_area *exchange; + + unsigned int unit; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + (void) pckt; + (void) exchange; + (void) unit; + (void) charBuf; + + /* Create an out component */ + rep = (FwSmDesc_t) CrFwOutFactoryMakeOutCmp(CRIA_SERV197, CRIA_SERV197_BOOT_REP, 0, 0); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + return; + } + +#if (__sparc__) + + exchange = (struct exchange_area *) EXCHANGE_AREA_BASE_ADDR; + + resetType = exchange->reset_type; + + dpuMode = (exchange->hk_dbs_status_byte1 >> 4) & 15; + dpuSwActive = (exchange->hk_dbs_status_byte1 >> 2) & 3; + dpuWatchdogStatus = (exchange->hk_dbs_status_byte1 >> 1) & 1; + dpuUnit = exchange->hk_dbs_status_byte1 & 1; + + dpuResetType = (exchange->hk_dbs_status_byte2 >> 5) & 7; + timeSyncStatus = (exchange->hk_dbs_status_byte2 >> 4) & 1; + bootReportSent = (exchange->hk_dbs_status_byte2 >> 3) & 1; + spare1 = (exchange->hk_dbs_status_byte2 >> 2) & 1; + semError = (exchange->hk_dbs_status_byte2 >> 1) & 1; + semOn = exchange->hk_dbs_status_byte2 & 1; + + dpuScLinkStatus = (exchange->hk_dbs_status_byte3 >> 7) & 1; + dpuMilbusCoreEx = (exchange->hk_dbs_status_byte3 >> 6) & 1; + dpuMilbusSyncDw = (exchange->hk_dbs_status_byte3 >> 5) & 1; + dpuMilbusSyncTo = (exchange->hk_dbs_status_byte3 >> 4) & 1; + dpuSemLinkStatus = (exchange->hk_dbs_status_byte3 >> 3) & 1; + dpuSemLinkState = exchange->hk_dbs_status_byte3 & 7; + + trapCore1 = (exchange->trapnum_core0); + trapCore2 = (exchange->trapnum_core1); + + psrRegCore1 = exchange->regs_cpu0.psr; + wimRegCore1 = exchange->regs_cpu0.wim; + pcRegCore1 = exchange->regs_cpu0.pc; + npcRegCore1 = exchange->regs_cpu0.npc; + fsrRegCore1 = exchange->regs_cpu0.fsr; + + psrRegCore2 = exchange->regs_cpu1.psr; + wimRegCore2 = exchange->regs_cpu1.wim; + pcRegCore2 = exchange->regs_cpu1.pc; + npcRegCore2 = exchange->regs_cpu1.npc; + fsrRegCore2 = exchange->regs_cpu1.fsr; + + ahbStatusReg = exchange->ahb_status_reg; + ahbFailingAddrReg = exchange->ahb_failing_addr_reg; + + spare2 = 0; +#endif + + CrIaServ197BootRepParamSetResetType(rep, resetType); + CrIaServ197BootRepParamSetDpuMode(rep, dpuMode); + CrIaServ197BootRepParamSetDpuSwActive(rep, dpuSwActive); + CrIaServ197BootRepParamSetDpuWatchdogStatus(rep, dpuWatchdogStatus); + CrIaServ197BootRepParamSetDpuUnit(rep, dpuUnit); + CrIaServ197BootRepParamSetDpuResetType(rep, dpuResetType); + CrIaServ197BootRepParamSetTimeSyncStatus(rep, timeSyncStatus); + CrIaServ197BootRepParamSetBootReportSent(rep, bootReportSent); + CrIaServ197BootRepParamSetSpare1(rep, spare1); + CrIaServ197BootRepParamSetSemError(rep, semError); + CrIaServ197BootRepParamSetSemOn(rep, semOn); + CrIaServ197BootRepParamSetDpuScLinkStatus(rep, dpuScLinkStatus); + CrIaServ197BootRepParamSetDpuMilbusCoreEx(rep, dpuMilbusCoreEx); + CrIaServ197BootRepParamSetDpuMilbusSyncDw(rep, dpuMilbusSyncDw); + CrIaServ197BootRepParamSetDpuMilbusSyncTo(rep, dpuMilbusSyncTo); + CrIaServ197BootRepParamSetDpuSemLinkStatus(rep, dpuSemLinkStatus); + CrIaServ197BootRepParamSetDpuSemLinkState(rep, dpuSemLinkState); +#if (__sparc__) + charBuf[0] = (exchange->reset_time.coarse_time >> 24) & 0xff; + charBuf[1] = (exchange->reset_time.coarse_time >> 16) & 0xff; + charBuf[2] = (exchange->reset_time.coarse_time >> 8) & 0xff; + charBuf[3] = (exchange->reset_time.coarse_time) & 0xff; + charBuf[4] = (exchange->reset_time.fine_time >> 8) & 0xff; + charBuf[5] = (exchange->reset_time.fine_time) & 0xff; +#endif + resetTime = charBuf; + CrIaServ197BootRepParamSetResetTime(rep, resetTime); + + CrIaServ197BootRepParamSetTrapCore1(rep, trapCore1); + CrIaServ197BootRepParamSetTrapCore2(rep, trapCore2); + + CrIaServ197BootRepParamSetPsrRegCore1(rep, psrRegCore1); + CrIaServ197BootRepParamSetWimRegCore1(rep, wimRegCore1); + CrIaServ197BootRepParamSetPcRegCore1(rep, pcRegCore1); + CrIaServ197BootRepParamSetNpcRegCore1(rep, npcRegCore1); + CrIaServ197BootRepParamSetFsrRegCore1(rep, fsrRegCore1); + + CrIaServ197BootRepParamSetPsrRegCore2(rep, psrRegCore2); + CrIaServ197BootRepParamSetWimRegCore2(rep, wimRegCore2); + CrIaServ197BootRepParamSetPcRegCore2(rep, pcRegCore2); + CrIaServ197BootRepParamSetNpcRegCore2(rep, npcRegCore2); + CrIaServ197BootRepParamSetFsrRegCore2(rep, fsrRegCore2); + + CrIaServ197BootRepParamSetAhbStatusReg(rep, ahbStatusReg); + CrIaServ197BootRepParamSetAhbFailingAddrReg(rep, ahbFailingAddrReg); + +#if (__sparc__) + pcHistoryCore1 = (unsigned char *) exchange->stacktrace_cpu0; + CrIaServ197BootRepParamSetPcHistoryCore1(rep, pcHistoryCore1); + + pcHistoryCore2 = (unsigned char *) exchange->stacktrace_cpu1; + CrIaServ197BootRepParamSetPcHistoryCore2(rep, pcHistoryCore2); +#else + (void) pcHistoryCore1; + (void) pcHistoryCore2; +#endif + + CrIaServ197BootRepParamSetSpare2(rep, spare2); + + CrIaServ197RepBootParamGetDpuMemoryId (&dpuMemoryId, pckt); + CrIaServ197RepBootParamGetStartAddress (&startAddress, pckt); + + CrIaServ197BootRepParamSetDpuMemoryId(rep, dpuMemoryId); + CrIaServ197BootRepParamSetStartAddress(rep, startAddress); + + + /* + get the 64 most recent RAM error log entries, most recent one first + the setter copies the first 44 entries to the report + */ + +#if (__sparc__) + + /* Mantis 1995: clear charBuf before */ + bzero(charBuf, ERROR_LOG_MAX_ENTRIES * SIZEOF_ERR_LOG_ENTRY); + bzero((char *) SRAM1_DBS_FLASH_BUFFER, ERROR_LOG_MAX_ENTRIES * SIZEOF_ERR_LOG_ENTRY); + + if (dpuMemoryId == DPU_RAM) + { + CrIbDumpRamErrorLog (charBuf); + } + else /* can only be DPU_FLASH1..4 due to validity check */ + { + /* Retrieve error log from flash */ + /* Mantis 1995: the units are indexed 0..3 */ + unit = 0; /* DPU_FLASH1 */ + if (dpuMemoryId == DPU_FLASH2) + { + unit = 1; + } + if (dpuMemoryId == DPU_FLASH3) + { + unit = 2; + } + if (dpuMemoryId == DPU_FLASH4) + { + unit = 3; + } + + /* the requested flash unit/address is dumped to the 1 MiB DBS FLASH buffer */ + CrIbDumpFlashErrorLog(unit, startAddress, (char *) SRAM1_DBS_FLASH_BUFFER); + + memcpy(charBuf, (const void *) SRAM1_DBS_FLASH_BUFFER, sizeof(charBuf)); + } + +#endif + + errLogInfo = charBuf; + CrIaServ197BootRepParamSetErrLogInfo(rep, errLogInfo); + + /* Set out component parameters */ + CrFwOutCmpSetGroup(rep, group); + + CrFwOutCmpSetDest(rep, CR_FW_CLIENT_GRD_PUS); /* obc: CR_FW_CLIENT_OBC, grnd: CR_FW_CLIENT_GRD_PUS */ + + /* Load the Boot Report (197,1); set the action outcome to 'completed' */ + CrFwOutLoaderLoad(rep); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} diff --git a/CrIa/src/Services/CrIaServ197BootReportService/InCmd/CrIaServ197RepBoot.h b/CrIa/src/Services/CrIaServ197BootReportService/InCmd/CrIaServ197RepBoot.h new file mode 100644 index 0000000000000000000000000000000000000000..49c3c6e4137f2305e5ce5c72f6ea864ee006d64f --- /dev/null +++ b/CrIa/src/Services/CrIaServ197BootReportService/InCmd/CrIaServ197RepBoot.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ197RepBoot.h + * + * Declaration of the Generate Boot Report in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV197_REP_BOOT_H +#define CRIA_SERV197_REP_BOOT_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Generate Boot Report in-coming command packet. + * The command parameters must have legal values + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ197RepBootValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Generate Boot Report in-coming command packet. + * Set the action outcome to 'success' + * @param smDesc the state machine descriptor + */ +void CrIaServ197RepBootStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Generate Boot Report in-coming command packet. + * Load the Boot Report (197,1); set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ197RepBootProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV197_REP_BOOT_H */ + diff --git a/CrIa/src/Services/CrIaServ197BootReportService/OutRep/CrIaServ197BootRep.c b/CrIa/src/Services/CrIaServ197BootReportService/OutRep/CrIaServ197BootRep.c new file mode 100644 index 0000000000000000000000000000000000000000..fd92008a248f070c27233e7c71bc583edf77b217 --- /dev/null +++ b/CrIa/src/Services/CrIaServ197BootReportService/OutRep/CrIaServ197BootRep.c @@ -0,0 +1,31 @@ +/** + * @file CrIaServ197BootRep.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Boot Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ197BootRep.h" + + +void CrIaServ197BootRepUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); + + /* Do nothing */ + /* NOTE: content of packet is set in Progress Action of TC(197,1) */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ197BootReportService/OutRep/CrIaServ197BootRep.h b/CrIa/src/Services/CrIaServ197BootReportService/OutRep/CrIaServ197BootRep.h new file mode 100644 index 0000000000000000000000000000000000000000..ae552077d0cfa09f2d687637bacbe43f66f9c76e --- /dev/null +++ b/CrIa/src/Services/CrIaServ197BootReportService/OutRep/CrIaServ197BootRep.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ197BootRep.h + * + * Declaration of the Boot Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV197_BOOT_REP_H +#define CRIA_SERV197_BOOT_REP_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Boot Report telemetry packet. + * Retrieve content of Boot Report from IBSW + * @param smDesc the state machine descriptor + */ +void CrIaServ197BootRepUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV197_BOOT_REP_H */ + diff --git a/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.c b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.c new file mode 100644 index 0000000000000000000000000000000000000000..320a3abf4d6081d8249725a919b5c22d31ed54e4 --- /dev/null +++ b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.c @@ -0,0 +1,1203 @@ +/** + * @file CrIaServ198ProcStart.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Start Procedure in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#if !(__sparc__) +#include <stdio.h> /* only for NULL */ +#include <stdlib.h> /* free */ +#endif + +/** FW Profile function definitions */ +#include <FwProfile/FwSmConfig.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwPrCore.h> + +#include "CrIaServ198ProcStart.h" +#include "CrFwCmpData.h" +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaConstants.h> +#include <Services/General/CrSemConstants.h> +#include <CrIaInCmp.h> +#include <IfswUtilities.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <CrIaIasw.h> /* for Event Reporting and extern sm and prDescriptors */ + +#include "../../../IfswDebug.h" + +/* access to RAM */ +#if (__sparc__) +#include <wrap_malloc.h> +#else +#include "Sdp/SdpBuffers.h" +#endif + + +int CheckSdbParameters (struct SdbLayout *cfg) +{ + unsigned int CibSize, SibSize, GibSize; + + /* + check overall size for shared FULL/WIN memory config + For SIB and CIB, the larger of FULL/WIN is used. + + NOTE: here we check these sizes in the same way they are + actually applied in CrIaSdbFunc.c CrIaSdbAction1 . + */ + CibSize = cfg->CibNFull * cfg->CibSizeFull; + if ((unsigned int)(cfg->CibNWin * cfg->CibSizeWin) > CibSize) + CibSize = cfg->CibNWin * cfg->CibSizeWin; + + SibSize = cfg->SibNFull * cfg->SibSizeFull; + if ((unsigned int)(cfg->SibNWin * cfg->SibSizeWin) > SibSize) + SibSize = cfg->SibNWin * cfg->SibSizeWin; + + /* the GIB is not shared */ + GibSize = cfg->GibNFull * cfg->GibSizeFull + cfg->GibNWin * cfg->GibSizeWin; + + DEBUGP("S(198,1) CONFIG SDB Sizes are: %d %d %d vs SDB size %d\n", SibSize, CibSize, GibSize, SDB_SIZE); + DEBUGP(" Win: %d %d %d\n", cfg->SibSizeWin, cfg->CibSizeWin, cfg->GibSizeWin); + DEBUGP(" Full: %d %d %d\n", cfg->SibSizeFull, cfg->CibSizeFull, cfg->GibSizeFull); + + if ((CibSize + SibSize)*1024 > SDB_SIZE) + { + /* error, too much RAM is requested */ + return 1; + } + + if ((GibSize * 1024) > SRAM1_RES_SIZE) + { + /* error, too much RAM is requested */ + return 1; + } + + return 0; +} + + +CrFwBool_t CrIaServ198ProcStartValidityCheck(FwPrDesc_t prDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + struct SdbLayout SdbCfg; + + unsigned short ProcId; + + /* variables for Save Images */ + unsigned short saveTarget; + unsigned char fbfInit, fbfEnd; + + /* variables for FBF Save and FBF Load */ + unsigned char fbfId, fbfNBlocks; + unsigned short fbfRamAreaId, AddrId; + unsigned int fbfRamAddr, Addr; + + /* variables for FBF To Ground */ + unsigned char nmbFbf; + /*unsigned char fbfInit; declaration used from Save Images above */ + unsigned char fbfSize; + + /* variables for ... */ + unsigned int imageRep; /* Acq Full Drop, Cal Full Snap, Sci Stack */ + unsigned int expTime; /* Acq Full Drop, Cal Full Snap, Sci Stack */ + unsigned int nmbImages; /* Cal Full Snap, Sci Stack */ + unsigned short centSel; /* Cal Full Snap, Sci Stack */ + unsigned short ccdRdMode; /* Sci Stack */ + unsigned short winPosX; /* Sci Stack */ + unsigned short winPosY; /* Sci Stack */ + unsigned short winSizeX; /* Sci Stack */ + unsigned short winSizeY; /* Sci Stack */ + + unsigned int expTimeAcq; /* Nom Sci - Acq */ + unsigned int imageRepAcq; /* Nom Sci - Acq */ + + unsigned int expTimeCal1; /* Nom Sci - Cal1 */ + unsigned int imageRepCal1; /* Nom Sci - Cal1 */ + unsigned int nmbImagesCal1; /* Nom Sci - Cal1 */ + unsigned short centSelCal1; /* Nom Sci - Cal1 */ + + unsigned int nmbImagesSci; /* Nom Sci - Sci */ + unsigned short ccdRdModeSci; /* Nom Sci - Sci */ + unsigned int expTimeSci; /* Nom Sci - Sci */ + unsigned int imageRepSci; /* Nom Sci - Sci */ + unsigned short winPosXSci; /* Nom Sci - Sci */ + unsigned short winPosYSci; /* Nom Sci - Sci */ + unsigned short winSizeXSci; /* Nom Sci - Sci */ + unsigned short winSizeYSci; /* Nom Sci - Sci */ + unsigned short centSelSci; /* Nom Sci - Sci */ + + unsigned int expTimeCal2; /* Nom Sci - Cal2 */ + unsigned int imageRepCal2; /* Nom Sci - Cal2 */ + unsigned int nmbImagesCal2; /* Nom Sci - Cal2 */ + unsigned short centSelCal2; /* Nom Sci - Cal2 */ + + /*unsigned short saveTarget; declaration used from Save Images above */ /* Nom Sci - Save Images */ + /*unsigned char fbfInit; declaration used from Save Images above */ /* Nom Sci - Save Images */ + /*unsigned char fbfEnd; declaration used from Save Images above */ /* Nom Sci - Save Images */ + + unsigned short stckOrderCal1; /* Nom Sci - Stack Order Cal1 */ + unsigned short stckOrderSci; /* Nom Sci - Stack Order Sci */ + unsigned short stckOrderCal2; /* Nom Sci - Stack Order Cal2 */ + + /* variables for CONFIG_SDB */ + unsigned char GetCibNFull, GetSibNFull, GetGibNFull, GetSibNWin, GetCibNWin, GetGibNWin; /* NOTE: in the DP CibN is ushort, ConfigSdb_CibN is uchar, in the ICD it's uchar */ + unsigned short SdbCmd; + unsigned short CibSizeFull, SibSizeFull, GibSizeFull, CibSizeWin, SibSizeWin, GibSizeWin; + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The procedure identifier must be in the range 1..MAX_ID_PROC */ + + CrIaServ198ProcStartParamGetProcId (&ProcId, pckt); + + switch (ProcId) + { + /* --- Validity Check of SAVE_IMG_PR ------------------------------------------------------------------------ */ + case (CRIA_SERV198_SAVE_IMG_PR): + + /* get the Save Target (GROUND or FLASH) */ + CrIaServ198SaveImgPrParamGetSaveTarget(&saveTarget, pckt); + + /* get the FbfInit */ + CrIaServ198SaveImgPrParamGetFbfInit(&fbfInit, pckt); + + /* get the FbfEnd */ + CrIaServ198SaveImgPrParamGetFbfEnd(&fbfEnd, pckt); + + if ((saveTarget > 1) || + ((saveTarget == SAVETARGET_FLASH) && ((!fbfInit) || (fbfInit > FBF_NFILES))) || + ((saveTarget == SAVETARGET_FLASH) && ((!fbfEnd) || (fbfEnd > FBF_NFILES)))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + break; + + /* --- Validity Check of ACQ_FULL_DROP_PR -------------------------------------------------------------------- */ + case (CRIA_SERV198_ACQ_FULL_DROP): + + /* get the expTime */ + CrIaServ198AcqFullDropParamGetExpTime(&expTime, pckt); + + /* get the imageRep */ + CrIaServ198AcqFullDropParamGetImageRep(&imageRep, pckt); + + if (((expTime < 1) || (expTime > 700000)) || + ((imageRep < 400) || (imageRep > 750000)) || + (expTime > imageRep)) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + break; + + /* --- Validity Check of CAL_FULL_SNAP_PR -------------------------------------------------------------------- */ + case (CRIA_SERV198_CAL_FULL_SNAP): + + /* get the expTime */ + CrIaServ198CalFullSnapParamGetExpTime(&expTime, pckt); + + /* get the imageRep */ + CrIaServ198CalFullSnapParamGetImageRep(&imageRep, pckt); + + /* get the nmbImages */ + CrIaServ198CalFullSnapParamGetNmbImages(&nmbImages, pckt); + + /* get the centSel */ + CrIaServ198CalFullSnapParamGetCentSel(¢Sel, pckt); + + if (((expTime < 1) || (expTime > 700000)) || + (expTime > imageRep) || + ((imageRep < 400) || (imageRep > 750000)) || + (!nmbImages) || + ((!centSel) || (centSel > 3))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + break; + + /* --- Validity Check of FBF_LOAD_PR ------------------------------------------------------------------------- */ + case (CRIA_SERV198_FBF_LOAD_PR): + + CrIaServ198FbfLoadPrParamGetFbfNBlocks(&fbfNBlocks, pckt); + if (fbfNBlocks > FBF_SIZE) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + CrIaServ198FbfLoadPrParamGetFbfId(&fbfId, pckt); + if ((!fbfId) || (fbfId > FBF_NFILES)) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* check AREAID and/or ADDRESS */ + CrIaServ198FbfLoadPrParamGetFbfRamAreaId(&fbfRamAreaId, pckt); + CrIaServ198FbfLoadPrParamGetFbfRamAddr(&fbfRamAddr, pckt); + + Addr = (unsigned int) areaIdToAddress (fbfRamAreaId, fbfRamAddr); + if (Addr == 0) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + if (fbfRamAreaId == AREAID_RAMADDR) + { + AddrId = verifyAddress(fbfRamAddr); + + if (AddrId == ADDRID_INVALID) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + } + + break; + + /* --- Validity Check of FBF_SAVE_PR ------------------------------------------------------------------------- */ + case (CRIA_SERV198_FBF_SAVE_PR): + + CrIaServ198FbfSavePrParamGetFbfNBlocks(&fbfNBlocks, pckt); + if (fbfNBlocks > FBF_SIZE) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + CrIaServ198FbfSavePrParamGetFbfId(&fbfId, pckt); + if ((!fbfId) || (fbfId > FBF_NFILES)) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* check AREAID and/or ADDRESS */ + CrIaServ198FbfSavePrParamGetFbfRamAreaId(&fbfRamAreaId, pckt); + CrIaServ198FbfSavePrParamGetFbfRamAddr(&fbfRamAddr, pckt); + + Addr = (unsigned int) areaIdToAddress (fbfRamAreaId, fbfRamAddr); + if (Addr == 0) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + cmpData->outcome = 0; + return 0; + } + + if (fbfRamAreaId == AREAID_RAMADDR) + { + AddrId = verifyAddress(fbfRamAddr); + + if (AddrId == ADDRID_INVALID) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + } + + break; + + /* --- Validity Check of SCI_STACK_PR ------------------------------------------------------------------------ */ + case (CRIA_SERV198_SCI_STACK_PR): + + /* get the nmbImages */ + CrIaServ198SciStackPrParamGetNmbImages(&nmbImages, pckt); + + /* get the CCD Readout Mode */ + CrIaServ198SciStackPrParamGetCcdRdMode(&ccdRdMode, pckt); + + /* get the expTime */ + CrIaServ198SciStackPrParamGetExpTime(&expTime, pckt); + + /* get the imageRep */ + CrIaServ198SciStackPrParamGetImageRep(&imageRep, pckt); + + /* get the Win Pos X */ + CrIaServ198SciStackPrParamGetWinPosX(&winPosX, pckt); + + /* get the Win Pos Y */ + CrIaServ198SciStackPrParamGetWinPosY(&winPosY, pckt); + + /* get the Win Size X */ + CrIaServ198SciStackPrParamGetWinSizeX(&winSizeX, pckt); + + /* get the Win Size Y */ + CrIaServ198SciStackPrParamGetWinSizeY(&winSizeY, pckt); + + /* get the centSel */ + CrIaServ198SciStackPrParamGetCentSel(¢Sel, pckt); + + /* Mantis 2094: SEM coordinate check modified */ + if ((!nmbImages) || + (ccdRdMode > SEM_CCD_MODE_FAINT_STAR_FAST) || + ((expTime < 1) || (expTime > 700000)) || + (expTime > imageRep) || + ((imageRep < 400) || (imageRep > 750000)) || + (winPosX > 1023) || + ((winPosY < 1) || (winPosY > 1022)) || + ((winSizeX < 1) || (winSizeX > 1024)) || + ((winSizeY < 1) || (winSizeY > 1022)) || + ((!centSel) || (centSel > 3))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + break; + + /* --- Validity Check of FBF_TO_GND_PR ----------------------------------------------------------------------- */ + case (CRIA_SERV198_FBF_TO_GND_PR): + + /* get the nmbFbf */ + CrIaServ198FbfToGndPrParamGetNmbFbf(&nmbFbf, pckt); + + /* get the fbfInit */ + CrIaServ198FbfToGndPrParamGetFbfInit(&fbfInit, pckt); + + /* get the fbfSize */ + CrIaServ198FbfToGndPrParamGetFbfSize(&fbfSize, pckt); + + if (((!nmbFbf) || (nmbFbf > (FBF_NFILES - fbfInit))) || + ((!fbfInit) || (fbfInit > FBF_NFILES)) || + (((!fbfSize) || (fbfSize > FBF_SIZE)))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + break; + + /* --- Validity Check of NOM_SCI_PR -------------------------------------------------------------------------- */ + case (CRIA_SERV198_NOM_SCI_PR): + + /* check SDB configuration */ + + CrIaServ198NomSciPrParamGetCibNFull(&GetCibNFull, pckt); + CrIaServ198NomSciPrParamGetCibSizeFull(&CibSizeFull, pckt); + CrIaServ198NomSciPrParamGetSibNFull(&GetSibNFull, pckt); + CrIaServ198NomSciPrParamGetSibSizeFull(&SibSizeFull, pckt); + CrIaServ198NomSciPrParamGetGibNFull(&GetGibNFull, pckt); + CrIaServ198NomSciPrParamGetGibSizeFull(&GibSizeFull, pckt); + CrIaServ198NomSciPrParamGetSibNWin(&GetSibNWin, pckt); + CrIaServ198NomSciPrParamGetSibSizeWin(&SibSizeWin, pckt); + CrIaServ198NomSciPrParamGetCibNWin(&GetCibNWin, pckt); + CrIaServ198NomSciPrParamGetCibSizeWin(&CibSizeWin, pckt); + CrIaServ198NomSciPrParamGetGibNWin(&GetGibNWin, pckt); + CrIaServ198NomSciPrParamGetGibSizeWin(&GibSizeWin, pckt); + + SdbCfg.CibNFull = (unsigned short) GetCibNFull; + SdbCfg.SibNFull = (unsigned short) GetSibNFull; + SdbCfg.GibNFull = (unsigned short) GetGibNFull; + SdbCfg.CibNWin = (unsigned short) GetCibNWin; + SdbCfg.SibNWin = (unsigned short) GetSibNWin; + SdbCfg.GibNWin = (unsigned short) GetGibNWin; + SdbCfg.CibSizeFull = CibSizeFull; + SdbCfg.SibSizeFull = SibSizeFull; + SdbCfg.GibSizeFull = GibSizeFull; + SdbCfg.CibSizeWin = CibSizeWin; + SdbCfg.SibSizeWin = SibSizeWin; + SdbCfg.GibSizeWin = GibSizeWin; + + /* the check must be carried out separately for FULL ... */ + SdbCfg.mode = CrIaSdb_CONFIG_FULL; + if (CheckSdbParameters (&SdbCfg) != 0) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* ... and for WIN */ + SdbCfg.mode = CrIaSdb_CONFIG_WIN; + if (CheckSdbParameters (&SdbCfg) != 0) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* get the Exposure Time for Acquisition */ + CrIaServ198NomSciPrParamGetExpTimeAcq(&expTimeAcq, pckt); + + /* get the Image Repetition Period for Acquisition */ + CrIaServ198NomSciPrParamGetImageRepAcq(&imageRepAcq, pckt); + + if (((expTimeAcq < 1) || (expTimeAcq > 700000)) || + (expTimeAcq > imageRepAcq) || + ((imageRepAcq < 400) || (imageRepAcq > 750000))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* get the Exposure Time for Calibration 1 */ + CrIaServ198NomSciPrParamGetExpTimeCal1(&expTimeCal1, pckt); + + /* get the Image Repetition Period for Calibration 1 */ + CrIaServ198NomSciPrParamGetImageRepCal1(&imageRepCal1, pckt); + + /* get the Number of Images for Calibration 1 */ + CrIaServ198NomSciPrParamGetNmbImagesCal1(&nmbImagesCal1, pckt); + + /* get the Centroid Selection for Calibration 1 */ + CrIaServ198NomSciPrParamGetCentSelCal1(¢SelCal1, pckt); + + if (((expTimeCal1 < 1) || (expTimeCal1 > 700000)) || + (expTimeCal1 > imageRepCal1) || + ((imageRepCal1 < 400) || (imageRepCal1 > 750000)) || + (!nmbImagesCal1) || + ((!centSelCal1) || (centSelCal1 > 3))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* get the Number of Images for Science Observation */ + CrIaServ198NomSciPrParamGetNmbImagesSci(&nmbImagesSci, pckt); + + /* get the CCD Readou Mode for Science Observation */ + CrIaServ198NomSciPrParamGetCcdRdModeSci(&ccdRdModeSci, pckt); + + /* get the Exposure Time for Science Observation */ + CrIaServ198NomSciPrParamGetExpTimeSci(&expTimeSci, pckt); + + /* get the Image Repitition Period for Science Observation */ + CrIaServ198NomSciPrParamGetImageRepSci(&imageRepSci, pckt); + + /* get the Win Pos X for Science Observation */ + CrIaServ198NomSciPrParamGetWinPosXSci(&winPosXSci, pckt); + + /* get the Win Pos Y for Science Observation */ + CrIaServ198NomSciPrParamGetWinPosYSci(&winPosYSci, pckt); + + /* get the Win Size X for Science Observation */ + CrIaServ198NomSciPrParamGetWinSizeXSci(&winSizeXSci, pckt); + + /* get the WinSize Y for Science Observation */ + CrIaServ198NomSciPrParamGetWinSizeYSci(&winSizeYSci, pckt); + + /* get the Centroid Selection for Science Observation */ + CrIaServ198NomSciPrParamGetCentSelSci(¢SelSci, pckt); + + /* Mantis 2094: SEM coordinate check modified */ + if (((expTimeSci < 1) || (expTimeSci > 700000)) || + (expTimeSci > imageRepSci) || + ((imageRepSci < 400) || (imageRepSci > 750000)) || + (!nmbImagesSci) || + (ccdRdModeSci > SEM_CCD_MODE_FAINT_STAR_FAST) || + (winPosXSci > 1023) || + ((winPosYSci < 1) || (winPosYSci > 1022)) || + ((winSizeXSci < 1) || (winSizeXSci > 1024)) || + ((winSizeYSci < 1) || (winSizeYSci > 1022)) || + ((!centSelSci) || (centSelSci > 3))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* get the Exposure Time for Calibration 2 */ + CrIaServ198NomSciPrParamGetExpTimeCal2(&expTimeCal2, pckt); + + /* get the Image Repetition Period for Calibration 2 */ + CrIaServ198NomSciPrParamGetImageRepCal2(&imageRepCal2, pckt); + + /* get the Number of Images for Calibration 2 */ + CrIaServ198NomSciPrParamGetNmbImagesCal2(&nmbImagesCal2, pckt); + + /* get the Centroid Selection for Calibration 2 */ + CrIaServ198NomSciPrParamGetCentSelCal2(¢SelCal2, pckt); + + if (((expTimeCal2 < 1) || (expTimeCal2 > 700000)) || + (expTimeCal2 > imageRepCal2) || + ((imageRepCal2 < 400) || (imageRepCal2 > 750000)) || + (!nmbImagesCal2) || + ((!centSelCal2) || (centSelCal2 > 3))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + /* get the Save Target (GROUND or FLASH) for Save Images */ + CrIaServ198NomSciPrParamGetSaveTarget(&saveTarget, pckt); + + /* get the fbfInit for Save Images */ + CrIaServ198NomSciPrParamGetFbfInit(&fbfInit, pckt); + + /* get the fbfEnd for Save Images */ + CrIaServ198NomSciPrParamGetFbfEnd(&fbfEnd, pckt); + + if ((saveTarget > 1) || + ((saveTarget == SAVETARGET_FLASH) && ((!fbfInit) || (fbfInit > FBF_NFILES))) || + ((saveTarget == SAVETARGET_FLASH) && ((!fbfEnd) || (fbfEnd > FBF_NFILES)))) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + + /* get the Stacking Order for Calibration 1 */ + CrIaServ198NomSciPrParamGetStckOrderCal1(&stckOrderCal1, pckt); + + /* get the Stacking Order for Science Observation */ + CrIaServ198NomSciPrParamGetStckOrderSci(&stckOrderSci, pckt); + + /* get the Stacking Order for Calibration 2 */ + CrIaServ198NomSciPrParamGetStckOrderCal2(&stckOrderCal2, pckt); + + if ((!stckOrderCal1) || + (!stckOrderSci) || + (!stckOrderCal2)) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + break; + + /* --- Validity Check of CONFIG_SDB_PR ----------------------------------------------------------------------- */ + case (CRIA_SERV198_CONFIG_SDB_PR): + + /* get the SDB command */ + CrIaServ198ConfigSdbPrParamGetSdbCmd(&SdbCmd, pckt); + + /* if it is RESET, then don't care about the rest */ + if (SdbCmd == CMD_RESET) + break; + + /* get and check other parameters */ + CrIaServ198ConfigSdbPrParamGetCibNFull(&GetCibNFull, pckt); + CrIaServ198ConfigSdbPrParamGetCibSizeFull(&CibSizeFull, pckt); + CrIaServ198ConfigSdbPrParamGetSibNFull(&GetSibNFull, pckt); + CrIaServ198ConfigSdbPrParamGetSibSizeFull(&SibSizeFull, pckt); + CrIaServ198ConfigSdbPrParamGetGibNFull(&GetGibNFull, pckt); + CrIaServ198ConfigSdbPrParamGetGibSizeFull(&GibSizeFull, pckt); + CrIaServ198ConfigSdbPrParamGetSibNWin(&GetSibNWin, pckt); + CrIaServ198ConfigSdbPrParamGetSibSizeWin(&SibSizeWin, pckt); + CrIaServ198ConfigSdbPrParamGetCibNWin(&GetCibNWin, pckt); + CrIaServ198ConfigSdbPrParamGetCibSizeWin(&CibSizeWin, pckt); + CrIaServ198ConfigSdbPrParamGetGibNWin(&GetGibNWin, pckt); + CrIaServ198ConfigSdbPrParamGetGibSizeWin(&GibSizeWin, pckt); + + SdbCfg.CibNFull = (unsigned short) GetCibNFull; + SdbCfg.SibNFull = (unsigned short) GetSibNFull; + SdbCfg.GibNFull = (unsigned short) GetGibNFull; + SdbCfg.CibNWin = (unsigned short) GetCibNWin; + SdbCfg.SibNWin = (unsigned short) GetSibNWin; + SdbCfg.GibNWin = (unsigned short) GetGibNWin; + SdbCfg.CibSizeFull = CibSizeFull; + SdbCfg.SibSizeFull = SibSizeFull; + SdbCfg.GibSizeFull = GibSizeFull; + SdbCfg.CibSizeWin = CibSizeWin; + SdbCfg.SibSizeWin = SibSizeWin; + SdbCfg.GibSizeWin = GibSizeWin; + + SdbCfg.mode = CrIaSdb_CONFIG_WIN; + + if (SdbCmd == CMD_RESET_FULL) + { + SdbCfg.mode = CrIaSdb_CONFIG_FULL; + } + if (SdbCmd == CMD_CONFIG_FULL) + { + SdbCfg.mode = CrIaSdb_CONFIG_FULL; + } + + if (CheckSdbParameters (&SdbCfg) != 0) + { + SendTcAccRepFail(pckt, ACK_ILL_PR_PAR); + return 0; + } + + break; + + /* --- Validity Check default case --------------------------------------------------------------------------- */ + default: + /* not a valid ProcId */ + SendTcAccRepFail(pckt, ACK_ILL_PR_ID); + return 0; + } + + DEBUGP("Service (198,1) Validity check passed\n"); + + cmpData->outcome = 1; + + SendTcAccRepSucc(pckt); + + return 1; +} + + +void CrIaServ198ProcStartStartAction(FwSmDesc_t smDesc) +{ + unsigned short ProcId; + unsigned short status; + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff the target procedure is stopped and the procedure parameters satisfy their constraints */ + + CrIaServ198ProcStartParamGetProcId (&ProcId, pckt); + + /* check if the procedure is in stopped state */ + if (procPr[ProcId-1] != NULL) + { + status = FwPrIsStarted(procPr[ProcId-1]); + + if (status != PR_STOPPED) + { + SendTcStartRepFail(pckt, ACK_PR_BUSY, 0, (unsigned short)status); + return; + } + } + + /* Set the action outcome to 'completed' */ + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; +} + + +void CrIaServ198ProcStartProgressAction(FwSmDesc_t smDesc) +{ + unsigned short ProcId; + + /* variables for Save Images */ + unsigned short saveTarget; + unsigned char fbfInit, fbfEnd; + + /* variables for FBF Save and FBF Load */ + unsigned char fbfId, fbfNBlocks; + unsigned short fbfRamAreaId; + unsigned int fbfRamAddr; + + /* variables for Calibrate Full Snap */ + unsigned short centSelCal; + + /* variables for Nominal Science */ + unsigned char acqFlag, cal1Flag, sciFlag, cal2Flag; + unsigned int expTimeAcq; + unsigned int imageRepAcq; + /* Cal1 */ + unsigned int expTimeCal1; + unsigned int imageRepCal1; + unsigned int nmbImagesCal1; + unsigned short centSelCal1; + /* Sci */ + unsigned int nmbImagesSci; + unsigned short ccdRdModeSci; + unsigned int imageRepSci; + unsigned int expTimeSci; + unsigned short winPosXSci, winPosYSci, winSizeXSci, winSizeYSci; + unsigned short centSelSci; + /* Cal2 */ + unsigned int expTimeCal2; + unsigned int imageRepCal2; + unsigned int nmbImagesCal2; + unsigned short centSelCal2; + /* Stacking Order */ + unsigned short stckOrderCal1; + unsigned short stckOrderSci; + unsigned short stckOrderCal2; + + /* variables in Science Stack */ + unsigned int nmbImages; + unsigned short ccdRdMode; + unsigned int imageRep; + unsigned int expTime; + unsigned short winPosX, winPosY, winSizeX, winSizeY; + + /* variables for Transfer FBF to Ground */ + unsigned char nmbFbf, fbfInitToGrd, fbfSize; + + /* variables for CONFIG_SDB */ + unsigned short SdbCmd, SdbState; + unsigned short cibNFull, sibNFull, gibNFull, sibNWin, cibNWin, gibNWin; + unsigned char GetCibNFull, GetSibNFull, GetGibNFull, GetSibNWin, GetCibNWin, GetGibNWin; + unsigned short CibSizeFull, SibSizeFull, GibSizeFull, CibSizeWin, SibSizeWin, GibSizeWin; + + unsigned int sdu2DownTransferSize; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Write the procedure parameters to the data pool; send the Start command to the target procedure; set the action outcome to 'completed' */ + + CrIaServ198ProcStartParamGetProcId (&ProcId, pckt); + + switch (ProcId) + { + case (CRIA_SERV198_SAVE_IMG_PR): + + /* get the Save Target (GROUND or FLASH) and write it into the data pool */ + CrIaServ198SaveImgPrParamGetSaveTarget(&saveTarget, pckt); + CrIaPaste(SAVEIMAGES_PSAVETARGET_ID, &saveTarget); + + /* get the FbfInit and write it into the data pool */ + CrIaServ198SaveImgPrParamGetFbfInit(&fbfInit, pckt); + CrIaPaste(SAVEIMAGES_PFBFINIT_ID, &fbfInit); + + /* get the FbfEnd and write it into the data pool */ + CrIaServ198SaveImgPrParamGetFbfEnd(&fbfEnd, pckt); + CrIaPaste(SAVEIMAGES_PFBFEND_ID, &fbfEnd); + + break; + + case (CRIA_SERV198_ACQ_FULL_DROP): + + /* get the expTime and write it into the data pool */ + CrIaServ198AcqFullDropParamGetExpTime(&expTime, pckt); + CrIaPaste(ACQFULLDROP_PEXPTIME_ID, &expTime); + + /* get the imageRep and write it into the data pool */ + CrIaServ198AcqFullDropParamGetImageRep(&imageRep, pckt); + CrIaPaste(ACQFULLDROP_PIMAGEREP_ID, &imageRep); + + break; + + case (CRIA_SERV198_CAL_FULL_SNAP): + + /* get the expTime and write it into the data pool */ + CrIaServ198CalFullSnapParamGetExpTime(&expTime, pckt); + CrIaPaste(CALFULLSNAP_PEXPTIME_ID, &expTime); + + /* get the imageRep and write it into the data pool */ + CrIaServ198CalFullSnapParamGetImageRep(&imageRep, pckt); + CrIaPaste(CALFULLSNAP_PIMAGEREP_ID, &imageRep); + + /* get the nmbImages and write it into the data pool */ + CrIaServ198CalFullSnapParamGetNmbImages(&nmbImages, pckt); + CrIaPaste(CALFULLSNAP_PNMBIMAGES_ID, &nmbImages); + + /* get the centSel and write it into the data pool */ + CrIaServ198CalFullSnapParamGetCentSel(¢SelCal, pckt); + CrIaPaste(CALFULLSNAP_PCENTSEL_ID, ¢SelCal); + + break; + + case (CRIA_SERV198_FBF_LOAD_PR): + + CrIaServ198FbfLoadPrParamGetFbfId(&fbfId, pckt); + CrIaPaste(FBFLOAD_PFBFID_ID, &fbfId); + + CrIaServ198FbfLoadPrParamGetFbfNBlocks(&fbfNBlocks, pckt); + CrIaPaste(FBFLOAD_PFBFNBLOCKS_ID, &fbfNBlocks); + + CrIaServ198FbfLoadPrParamGetFbfRamAreaId(&fbfRamAreaId, pckt); + CrIaPaste(FBFLOAD_PFBFRAMAREAID_ID, &fbfRamAreaId); + + CrIaServ198FbfLoadPrParamGetFbfRamAddr(&fbfRamAddr, pckt); + + /* the FBF Load function only needs the physical RAM address, + which we calculate here considering the Area ID */ + + fbfRamAddr = (unsigned int) areaIdToAddress (fbfRamAreaId, fbfRamAddr); + + CrIaPaste(FBFLOAD_PFBFRAMADDR_ID, &fbfRamAddr); + + break; + + case (CRIA_SERV198_FBF_SAVE_PR): + + /* get the FbfId and write it into the data pool */ + CrIaServ198FbfSavePrParamGetFbfId(&fbfId, pckt); + CrIaPaste(FBFSAVE_PFBFID_ID, &fbfId); + + /* get the FbfNBlocks and write it into the data pool */ + CrIaServ198FbfSavePrParamGetFbfNBlocks(&fbfNBlocks, pckt); + CrIaPaste(FBFSAVE_PFBFNBLOCKS_ID, &fbfNBlocks); + + /* get the FbfRamAreaId and write it into the data pool */ + CrIaServ198FbfSavePrParamGetFbfRamAreaId(&fbfRamAreaId, pckt); + CrIaPaste(FBFSAVE_PFBFRAMAREAID_ID, &fbfRamAreaId); + + /* get the FbfRamAddr and write it into the data pool */ + CrIaServ198FbfSavePrParamGetFbfRamAddr(&fbfRamAddr, pckt); + + /* the FBF Save function only needs the physical RAM address, + which we calculate here considering the Area ID */ + + fbfRamAddr = (unsigned int) areaIdToAddress (fbfRamAreaId, fbfRamAddr); + + CrIaPaste(FBFSAVE_PFBFRAMADDR_ID, &fbfRamAddr); + + break; + + case (CRIA_SERV198_SCI_STACK_PR): + + CrIaServ198SciStackPrParamGetNmbImages(&nmbImages, pckt); + CrIaPaste(SCIWIN_PNMBIMAGES_ID, &nmbImages); + + CrIaServ198SciStackPrParamGetCcdRdMode(&ccdRdMode, pckt); + CrIaPaste(SCIWIN_PCCDRDMODE_ID, &ccdRdMode); + + /* NOT USED + CrIaServ198SciStackPrParamGetStackSnap(&stackSnap, pckt); + CrIaPaste(SCIWIN_PSTACKSNAP_ID, &stackSnap); + */ + + CrIaServ198SciStackPrParamGetExpTime(&expTime, pckt); + CrIaPaste(SCIWIN_PEXPTIME_ID, &expTime); + + CrIaServ198SciStackPrParamGetImageRep(&imageRep, pckt); + CrIaPaste(SCIWIN_PIMAGEREP_ID, &imageRep); + + CrIaServ198SciStackPrParamGetWinPosX(&winPosX, pckt); + CrIaPaste(SCIWIN_PWINPOSX_ID, &winPosX); + + CrIaServ198SciStackPrParamGetWinPosY(&winPosY, pckt); + CrIaPaste(SCIWIN_PWINPOSY_ID, &winPosY); + + CrIaServ198SciStackPrParamGetWinSizeX(&winSizeX, pckt); + CrIaPaste(SCIWIN_PWINSIZEX_ID, &winSizeX); + + CrIaServ198SciStackPrParamGetWinSizeY(&winSizeY, pckt); + CrIaPaste(SCIWIN_PWINSIZEY_ID, &winSizeY); + + break; + + case (CRIA_SERV198_FBF_TO_GND_PR): + + CrIaServ198FbfToGndPrParamGetNmbFbf(&nmbFbf, pckt); + CrIaPaste(TRANSFBFTOGRND_PNMBFBF_ID, &nmbFbf); + + CrIaServ198FbfToGndPrParamGetFbfInit(&fbfInitToGrd, pckt); + CrIaPaste(TRANSFBFTOGRND_PFBFINIT_ID, &fbfInitToGrd); + + CrIaServ198FbfToGndPrParamGetFbfSize(&fbfSize, pckt); + CrIaPaste(TRANSFBFTOGRND_PFBFSIZE_ID, &fbfSize); + + break; + + case (CRIA_SERV198_NOM_SCI_PR): + + CrIaServ198NomSciPrParamGetAcqFlag(&acqFlag, pckt); + CrIaPaste(NOMSCI_PACQFLAG_ID, &acqFlag); + + CrIaServ198NomSciPrParamGetCal1Flag(&cal1Flag, pckt); + CrIaPaste(NOMSCI_PCAL1FLAG_ID, &cal1Flag); + + CrIaServ198NomSciPrParamGetSciFlag(&sciFlag, pckt); + CrIaPaste(NOMSCI_PSCIFLAG_ID, &sciFlag); + + CrIaServ198NomSciPrParamGetCal2Flag(&cal2Flag, pckt); + CrIaPaste(NOMSCI_PCAL2FLAG_ID, &cal2Flag); + + CrIaServ198NomSciPrParamGetCibNFull(&GetCibNFull, pckt); + CrIaPaste(NOMSCI_PCIBNFULL_ID, &GetCibNFull); + + CrIaServ198NomSciPrParamGetCibSizeFull(&CibSizeFull, pckt); + CrIaPaste(NOMSCI_PCIBSIZEFULL_ID, &CibSizeFull); + + CrIaServ198NomSciPrParamGetSibNFull(&GetSibNFull, pckt); + CrIaPaste(NOMSCI_PSIBNFULL_ID, &GetSibNFull); + + CrIaServ198NomSciPrParamGetSibSizeFull(&SibSizeFull, pckt); + CrIaPaste(NOMSCI_PSIBSIZEFULL_ID, &SibSizeFull); + + CrIaServ198NomSciPrParamGetGibNFull(&GetGibNFull, pckt); + CrIaPaste(NOMSCI_PGIBNFULL_ID, &GetGibNFull); + + CrIaServ198NomSciPrParamGetGibSizeFull(&GibSizeFull, pckt); + CrIaPaste(NOMSCI_PGIBSIZEFULL_ID, &GibSizeFull); + + CrIaServ198NomSciPrParamGetSibNWin(&GetSibNWin, pckt); + CrIaPaste(NOMSCI_PSIBNWIN_ID, &GetSibNWin); + + CrIaServ198NomSciPrParamGetSibSizeWin(&SibSizeWin, pckt); + CrIaPaste(NOMSCI_PSIBSIZEWIN_ID, &SibSizeWin); + + CrIaServ198NomSciPrParamGetCibNWin(&GetCibNWin, pckt); + CrIaPaste(NOMSCI_PCIBNWIN_ID, &GetCibNWin); + + CrIaServ198NomSciPrParamGetCibSizeWin(&CibSizeWin, pckt); + CrIaPaste(NOMSCI_PCIBSIZEWIN_ID, &CibSizeWin); + + CrIaServ198NomSciPrParamGetGibNWin(&GetGibNWin, pckt); + CrIaPaste(NOMSCI_PGIBNWIN_ID, &GetGibNWin); + + CrIaServ198NomSciPrParamGetGibSizeWin(&GibSizeWin, pckt); + CrIaPaste(NOMSCI_PGIBSIZEWIN_ID, &GibSizeWin); + + CrIaServ198NomSciPrParamGetExpTimeAcq(&expTimeAcq, pckt); + CrIaPaste(NOMSCI_PEXPTIMEACQ_ID, &expTimeAcq); + + CrIaServ198NomSciPrParamGetImageRepAcq(&imageRepAcq, pckt); + CrIaPaste(NOMSCI_PIMAGEREPACQ_ID, &imageRepAcq); + + CrIaServ198NomSciPrParamGetExpTimeCal1(&expTimeCal1, pckt); + CrIaPaste(NOMSCI_PEXPTIMECAL1_ID, &expTimeCal1); + + CrIaServ198NomSciPrParamGetImageRepCal1(&imageRepCal1, pckt); + CrIaPaste(NOMSCI_PIMAGEREPCAL1_ID, &imageRepCal1); + + CrIaServ198NomSciPrParamGetNmbImagesCal1(&nmbImagesCal1, pckt); + CrIaPaste(NOMSCI_PNMBIMAGESCAL1_ID, &nmbImagesCal1); + + CrIaServ198NomSciPrParamGetCentSelCal1(¢SelCal1, pckt); + CrIaPaste(NOMSCI_PCENTSELCAL1_ID, ¢SelCal1); + + CrIaServ198NomSciPrParamGetNmbImagesSci(&nmbImagesSci, pckt); + CrIaPaste(NOMSCI_PNMBIMAGESSCI_ID, &nmbImagesSci); + + CrIaServ198NomSciPrParamGetCcdRdModeSci(&ccdRdModeSci, pckt); + CrIaPaste(NOMSCI_PCCDRDMODESCI_ID, &ccdRdModeSci); + + /* NOT USED + CrIaServ198NomSciPrParamGetStackSnapSci(&stackSnapSci, pckt); + CrIaPaste(NOMSCI_PSTACKSNAPSCI_ID, &stackSnapSci); + */ + + CrIaServ198NomSciPrParamGetExpTimeSci(&expTimeSci, pckt); + CrIaPaste(NOMSCI_PEXPTIMESCI_ID, &expTimeSci); + + CrIaServ198NomSciPrParamGetImageRepSci(&imageRepSci, pckt); + CrIaPaste(NOMSCI_PIMAGEREPSCI_ID, &imageRepSci); + + CrIaServ198NomSciPrParamGetWinPosXSci(&winPosXSci, pckt); + CrIaPaste(NOMSCI_PWINPOSXSCI_ID, &winPosXSci); + + CrIaServ198NomSciPrParamGetWinPosYSci(&winPosYSci, pckt); + CrIaPaste(NOMSCI_PWINPOSYSCI_ID, &winPosYSci); + + CrIaServ198NomSciPrParamGetWinSizeXSci(&winSizeXSci, pckt); + CrIaPaste(NOMSCI_PWINSIZEXSCI_ID, &winSizeXSci); + + CrIaServ198NomSciPrParamGetWinSizeYSci(&winSizeYSci, pckt); + CrIaPaste(NOMSCI_PWINSIZEYSCI_ID, &winSizeYSci); + + CrIaServ198NomSciPrParamGetCentSelSci(¢SelSci, pckt); + CrIaPaste(NOMSCI_PCENTSELSCI_ID, ¢SelSci); + + CrIaServ198NomSciPrParamGetExpTimeCal2(&expTimeCal2, pckt); + CrIaPaste(NOMSCI_PEXPTIMECAL2_ID, &expTimeCal2); + + CrIaServ198NomSciPrParamGetImageRepCal2(&imageRepCal2, pckt); + CrIaPaste(NOMSCI_PIMAGEREPCAL2_ID, &imageRepCal2); + + CrIaServ198NomSciPrParamGetNmbImagesCal2(&nmbImagesCal2, pckt); + CrIaPaste(NOMSCI_PNMBIMAGESCAL2_ID, &nmbImagesCal2); + + CrIaServ198NomSciPrParamGetCentSelCal2(¢SelCal2, pckt); + CrIaPaste(NOMSCI_PCENTSELCAL2_ID, ¢SelCal2); + + CrIaServ198NomSciPrParamGetSaveTarget(&saveTarget, pckt); + CrIaPaste(NOMSCI_PSAVETARGET_ID, &saveTarget); + + CrIaServ198NomSciPrParamGetFbfInit(&fbfInit, pckt); + CrIaPaste(NOMSCI_PFBFINIT_ID, &fbfInit); + + CrIaServ198NomSciPrParamGetFbfEnd(&fbfEnd, pckt); + CrIaPaste(NOMSCI_PFBFEND_ID, &fbfEnd); + + CrIaServ198NomSciPrParamGetStckOrderCal1(&stckOrderCal1, pckt); + CrIaPaste(NOMSCI_PSTCKORDERCAL1_ID, &stckOrderCal1); + + CrIaServ198NomSciPrParamGetStckOrderSci(&stckOrderSci, pckt); + CrIaPaste(NOMSCI_PSTCKORDERSCI_ID, &stckOrderSci); + + CrIaServ198NomSciPrParamGetStckOrderCal2(&stckOrderCal2, pckt); + CrIaPaste(NOMSCI_PSTCKORDERCAL2_ID, &stckOrderCal2); + + /* NOTE: the procedure parameters for the buffers are fetched in + the Nominal Science Procedure CrIaNomSciFunc */ + + break; + + /****************** + * * + * CONFIG SDB * + * * + ******************/ + case (CRIA_SERV198_CONFIG_SDB_PR): + + DEBUGP("Service (198,1) CONFIG_SDB\n"); + + /* get the SDB command */ + CrIaServ198ConfigSdbPrParamGetSdbCmd(&SdbCmd, pckt); + + DEBUGP("the command is %d\n", SdbCmd); + + /* --- RESET --- */ + if (SdbCmd == CMD_RESET) + { + /* make the SM transition */ + FwSmMakeTrans(smDescSdb, Reset); + sdu2DownTransferSize = 0; + CrIaPaste(SDU2DOWNTRANSFERSIZE_ID, &sdu2DownTransferSize); + + /* set data pool variable to unconfigured */ + /* NOTE: this is not done in the SDB SM */ + SdbState = CrIaSdb_UNCONFIGURED; + CrIaPaste(SDBSTATE_ID, &SdbState); + +#if (__sparc__) + release (SDB); + release (RES); +#else + sdballoc (0, 1); /* reset on PC */ + resalloc (0, 1); +#endif + } + + /* --- CONFIGURE_FULL and CONFIGURE_WIN --- */ + /* both configure commands use all parameters */ + if ((SdbCmd == CMD_CONFIG_FULL) || (SdbCmd == CMD_CONFIG_WIN)) + { + /* get parameters and enter in DP */ + CrIaServ198ConfigSdbPrParamGetCibNFull(&GetCibNFull, pckt); + CrIaServ198ConfigSdbPrParamGetCibSizeFull(&CibSizeFull, pckt); + CrIaServ198ConfigSdbPrParamGetSibNFull(&GetSibNFull, pckt); + CrIaServ198ConfigSdbPrParamGetSibSizeFull(&SibSizeFull, pckt); + CrIaServ198ConfigSdbPrParamGetGibNFull(&GetGibNFull, pckt); + CrIaServ198ConfigSdbPrParamGetGibSizeFull(&GibSizeFull, pckt); + CrIaServ198ConfigSdbPrParamGetSibNWin(&GetSibNWin, pckt); + CrIaServ198ConfigSdbPrParamGetSibSizeWin(&SibSizeWin, pckt); + CrIaServ198ConfigSdbPrParamGetCibNWin(&GetCibNWin, pckt); + CrIaServ198ConfigSdbPrParamGetCibSizeWin(&CibSizeWin, pckt); + CrIaServ198ConfigSdbPrParamGetGibNWin(&GetGibNWin, pckt); + CrIaServ198ConfigSdbPrParamGetGibSizeWin(&GibSizeWin, pckt); + + /* "private" copy */ + CrIaPaste(CONFIGSDB_PCIBNFULL_ID, &GetCibNFull); + CrIaPaste(CONFIGSDB_PCIBSIZEFULL_ID, &CibSizeFull); + CrIaPaste(CONFIGSDB_PSIBNFULL_ID, &GetSibNFull); + CrIaPaste(CONFIGSDB_PSIBSIZEFULL_ID, &SibSizeFull); + CrIaPaste(CONFIGSDB_PGIBNFULL_ID, &GetGibNFull); + CrIaPaste(CONFIGSDB_PGIBSIZEFULL_ID, &GibSizeFull); + CrIaPaste(CONFIGSDB_PSIBNWIN_ID, &GetSibNWin); + CrIaPaste(CONFIGSDB_PSIBSIZEWIN_ID, &SibSizeWin); + CrIaPaste(CONFIGSDB_PCIBNWIN_ID, &GetCibNWin); + CrIaPaste(CONFIGSDB_PCIBSIZEWIN_ID, &CibSizeWin); + CrIaPaste(CONFIGSDB_PGIBNWIN_ID, &GetGibNWin); + CrIaPaste(CONFIGSDB_PGIBSIZEWIN_ID, &GibSizeWin); + + DEBUGP("We want to enter SibSizeWin in the data pool (pri): %d\n", SibSizeWin); + DEBUGP("We want to enter CibSizeWin in the data pool (pri): %d\n", CibSizeWin); + DEBUGP("We want to enter GibSizeWin in the data pool (pri): %d\n", GibSizeWin); + DEBUGP("We want to enter SibSizeWin in the data pool (pri): %d\n", SibSizeFull); + DEBUGP("We want to enter CibSizeWin in the data pool (pri): %d\n", CibSizeFull); + DEBUGP("We want to enter GibSizeWin in the data pool (pri): %d\n", GibSizeFull); + + /* set them in data pool, but take care: + the procedure specific variables like CONFIGSDB_PCIBNFULL are + uchar, but the actually used ones like CIBNFULL are ushort! */ + cibNFull = (unsigned short) GetCibNFull; + sibNFull = (unsigned short) GetSibNFull; + gibNFull = (unsigned short) GetGibNFull; + cibNWin = (unsigned short) GetCibNWin; + sibNWin = (unsigned short) GetSibNWin; + gibNWin = (unsigned short) GetGibNWin; + + /* NOTE: here the ushorts are used! */ + CrIaPaste(CIBNFULL_ID, &cibNFull); + CrIaPaste(CIBSIZEFULL_ID, &CibSizeFull); + CrIaPaste(SIBNFULL_ID, &sibNFull); + CrIaPaste(SIBSIZEFULL_ID, &SibSizeFull); + CrIaPaste(GIBNFULL_ID, &gibNFull); + CrIaPaste(GIBSIZEFULL_ID, &GibSizeFull); + CrIaPaste(SIBNWIN_ID, &sibNWin); + CrIaPaste(SIBSIZEWIN_ID, &SibSizeWin); + CrIaPaste(CIBNWIN_ID, &cibNWin); + CrIaPaste(CIBSIZEWIN_ID, &CibSizeWin); + CrIaPaste(GIBNWIN_ID, &gibNWin); + CrIaPaste(GIBSIZEWIN_ID, &GibSizeWin); + } + + /* then also issue the transition */ + if (SdbCmd == CMD_CONFIG_FULL) + { + FwSmMakeTrans(smDescSdb, ConfigFull); + sdu2DownTransferSize = GibSizeFull*1024; + CrIaPaste(SDU2DOWNTRANSFERSIZE_ID, &sdu2DownTransferSize); + } + + if (SdbCmd == CMD_CONFIG_WIN) + { + FwSmMakeTrans(smDescSdb, ConfigWin); + sdu2DownTransferSize = GibSizeWin*1024; + CrIaPaste(SDU2DOWNTRANSFERSIZE_ID, &sdu2DownTransferSize); + } + + /* --- RESET_FULL and RESET_WIN --- + - no change of configuration + - only reset the pointers (gibOut) to the Win or Full */ + + /* the pointers (gibOut) are reset in the SDB entry action, no need to do this here */ + + /* issue the transition */ + if (SdbCmd == CMD_RESET_FULL) + { + FwSmMakeTrans(smDescSdb, ResetFull); + } + + if (SdbCmd == CMD_RESET_WIN) + { + FwSmMakeTrans(smDescSdb, ResetWin); + } + + break; + + default: + /* we never reach this */ + return; + } + + + /* Send the Start command to the target procedure */ + if (procPr[ProcId-1] != NULL) + { + FwPrStart(procPr[ProcId-1]); + } + + /* Set the action outcome to 'completed' */ + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.h b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.h new file mode 100644 index 0000000000000000000000000000000000000000..c7329eb16fa23d4842926bb6d40de0db7c7b6b9e --- /dev/null +++ b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStart.h @@ -0,0 +1,50 @@ +/** + * @file CrIaServ198ProcStart.h + * + * Declaration of the Start Procedure in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV198_PROC_START_H +#define CRIA_SERV198_PROC_START_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +#include <CrIaPrSm/CrIaSdbCreate.h> /* for the SDB config defines */ + +/* local names for the SDB config command procedure, + do not mix with SM defines made in CrIaSdbCreate */ +#define CMD_RESET 0 +#define CMD_CONFIG_FULL 1 +#define CMD_CONFIG_WIN 2 +#define CMD_RESET_FULL 3 +#define CMD_RESET_WIN 4 + + +/** + * Validity check of the Start Procedure in-coming command packet. + * The procedure identifier must be in the range 1..MAX_ID_PROC + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ198ProcStartValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Start Procedure in-coming command packet. + * Set the action outcome to 'success' iff the target procedure is stopped and the procedure parameters satisfy their constraints + * @param smDesc the state machine descriptor + */ +void CrIaServ198ProcStartStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Start Procedure in-coming command packet. + * Write the procedure parameters to the data pool; send the Start command to the target procedure; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ198ProcStartProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV198_PROC_START_H */ + diff --git a/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStop.c b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStop.c new file mode 100644 index 0000000000000000000000000000000000000000..b72a9df9b0a0718458a2a0ae627896cf69b9b33c --- /dev/null +++ b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStop.c @@ -0,0 +1,146 @@ +/** + * @file CrIaServ198ProcStop.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Stop Procedure in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ198ProcStop.h" +#include "CrIaServ198ProcStart.h" /* for the ACK_PR_IDLE and the PrStatusList */ + +/** FW Profile function definitions */ +#include <FwProfile/FwPrCore.h> /* for the FwPrStop(prDesc) */ + +#include "CrFwCmpData.h" +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaConstants.h> +#include <CrIaInCmp.h> +#include <IfswUtilities.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <CrIaIasw.h> /* for Event Reporting and extern sm and prDescriptors */ + + +CrFwBool_t CrIaServ198ProcStopValidityCheck(FwPrDesc_t prDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + unsigned short ProcId; + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* The procedure identifier must be in the range 1..MAX_ID_PROC */ + + CrIaServ198ProcStopParamGetProcId (&ProcId, pckt); + + if ((ProcId == 0) || (ProcId > MAX_ID_PROC)) + { + /* not a valid ProcId */ + SendTcAccRepFail(pckt, ACK_ILL_PR_ID); + return 0; + } + + cmpData->outcome = 1; + + SendTcAccRepSucc(pckt); + + return 1; +} + +void CrIaServ198ProcStopStartAction(FwSmDesc_t smDesc) +{ + unsigned short ProcId; + unsigned short status; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff the target procedure is started */ + + CrIaServ198ProcStopParamGetProcId (&ProcId, pckt); + + /* check if the procedure is in stopped state */ + if (procPr[ProcId-1] != NULL) + { + status = FwPrIsStarted(procPr[ProcId-1]); + + if (status != PR_STARTED) + { + SendTcStartRepFail(pckt, ACK_PR_IDLE, 0, (unsigned short)status); + return; + } + } + + /* Set the action outcome to 'completed' */ + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; +} + + +void CrIaServ198ProcStopProgressAction(FwSmDesc_t smDesc) +{ + unsigned short ProcId; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* get ProcId */ + CrIaServ198ProcStopParamGetProcId (&ProcId, pckt); + + /* Send the Stop command to the target procedure */ + if (procPr[ProcId-1] != NULL) + { + FwPrStop(procPr[ProcId-1]); + } + + /* Set the action outcome to 'completed' */ + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStop.h b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStop.h new file mode 100644 index 0000000000000000000000000000000000000000..c9d5ba8eb2ce8a4a123ebdf337604a21db328be5 --- /dev/null +++ b/CrIa/src/Services/CrIaServ198ProcedureControlService/InCmd/CrIaServ198ProcStop.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ198ProcStop.h + * + * Declaration of the Stop Procedure in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV198_PROC_STOP_H +#define CRIA_SERV198_PROC_STOP_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Stop Procedure in-coming command packet. + * The procedure identifier must be in the range 1..MAX_ID_PROC + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ198ProcStopValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Stop Procedure in-coming command packet. + * Set the action outcome to 'success' iff the target procedure is started + * @param smDesc the state machine descriptor + */ +void CrIaServ198ProcStopStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Stop Procedure in-coming command packet. + * Send the Stop command to the target procedure; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ198ProcStopProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV198_PROC_STOP_H */ + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccFail.c b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccFail.c new file mode 100644 index 0000000000000000000000000000000000000000..a9b5ab56c04a7130ef1b4d3c99f495a3ac6eb848 --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccFail.c @@ -0,0 +1,32 @@ +/** + * @file CrIaServ1AccFail.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Telecommand Acceptance Report – Failure out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ1AccFail.h" + + +void CrIaServ1AccFailUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + + /* Load the value of the report parameters */ + /* NOT USED: done in IfswUtilities function, which packs and finalizes out-going packet */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccFail.h b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccFail.h new file mode 100644 index 0000000000000000000000000000000000000000..08d5c237f548911fcc5f7c332e6a0fad0a712d4e --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccFail.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ1AccFail.h + * + * Declaration of the Telecommand Acceptance Report – Failure out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV1_ACC_FAIL_H +#define CRIA_SERV1_ACC_FAIL_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Telecommand Acceptance Report – Failure telemetry packet. + * Load the value of the report parameters + * @param smDesc the state machine descriptor + */ +void CrIaServ1AccFailUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV1_ACC_FAIL_H */ + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccSucc.c b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccSucc.c new file mode 100644 index 0000000000000000000000000000000000000000..8ebd46b17852a543c7bcb210e19e32fa1a674b6e --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccSucc.c @@ -0,0 +1,32 @@ +/** + * @file CrIaServ1AccSucc.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Telecommand Acceptance Report – Success out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ1AccSucc.h" + + +void CrIaServ1AccSuccUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + + /* Load the value of the report parameters */ + /* NOT USED: done in IfswUtilities function, which packs and finalizes out-going packet */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccSucc.h b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccSucc.h new file mode 100644 index 0000000000000000000000000000000000000000..4ee07d5e04c415710ee51bb4d9270168873ca4f2 --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1AccSucc.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ1AccSucc.h + * + * Declaration of the Telecommand Acceptance Report – Success out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV1_ACC_SUCC_H +#define CRIA_SERV1_ACC_SUCC_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Telecommand Acceptance Report – Success telemetry packet. + * Load the value of the report parameters + * @param smDesc the state machine descriptor + */ +void CrIaServ1AccSuccUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV1_ACC_SUCC_H */ + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartFail.c b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartFail.c new file mode 100644 index 0000000000000000000000000000000000000000..d607c435aaa41545d70b356000388a0a597f7654 --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartFail.c @@ -0,0 +1,32 @@ +/** + * @file CrIaServ1StartFail.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Telecommand Start Report – Failure out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ1StartFail.h" + + +void CrIaServ1StartFailUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + + /* Load the value of the report parameters */ + /* NOT USED: done in IfswUtilities function, which packs and finalizes out-going packet */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartFail.h b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartFail.h new file mode 100644 index 0000000000000000000000000000000000000000..a2c7dc6151962627425d2a2a88c0e65a28b5a915 --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartFail.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ1StartFail.h + * + * Declaration of the Telecommand Start Report – Failure out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV1_START_FAIL_H +#define CRIA_SERV1_START_FAIL_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Telecommand Start Report – Failure telemetry packet. + * Load the value of the report parameters + * @param smDesc the state machine descriptor + */ +void CrIaServ1StartFailUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV1_START_FAIL_H */ + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartSucc.c b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartSucc.c new file mode 100644 index 0000000000000000000000000000000000000000..a16dd9c41ff1fb75766f9c3e03c1da8ebbf0451e --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartSucc.c @@ -0,0 +1,32 @@ +/** + * @file CrIaServ1StartSucc.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Telecommand Start Report – Success out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ1StartSucc.h" + + +void CrIaServ1StartSuccUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + + /* Load the value of the report parameters */ + /* NOT USED: done in IfswUtilities function, which packs and finalizes out-going packet */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartSucc.h b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartSucc.h new file mode 100644 index 0000000000000000000000000000000000000000..6c3899fee2686fe79d35544b3f30c49acf81819f --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1StartSucc.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ1StartSucc.h + * + * Declaration of the Telecommand Start Report – Success out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV1_START_SUCC_H +#define CRIA_SERV1_START_SUCC_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Telecommand Start Report – Success telemetry packet. + * Load the value of the report parameters + * @param smDesc the state machine descriptor + */ +void CrIaServ1StartSuccUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV1_START_SUCC_H */ + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermFail.c b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermFail.c new file mode 100644 index 0000000000000000000000000000000000000000..f38991b1deee20e3f962f2ab0b80473331740778 --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermFail.c @@ -0,0 +1,32 @@ +/** + * @file CrIaServ1TermFail.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Telecommand Termination Report – Failure out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ1TermFail.h" + + +void CrIaServ1TermFailUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + + /* Load the value of the report parameters */ + /* NOT USED: done in IfswUtilities function, which packs and finalizes out-going packet */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermFail.h b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermFail.h new file mode 100644 index 0000000000000000000000000000000000000000..b4dd211debf43308be3bafe6bef0bc6753fcb0c0 --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermFail.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ1TermFail.h + * + * Declaration of the Telecommand Termination Report – Failure out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV1_TERM_FAIL_H +#define CRIA_SERV1_TERM_FAIL_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Telecommand Termination Report – Failure telemetry packet. + * Load the value of the report parameters + * @param smDesc the state machine descriptor + */ +void CrIaServ1TermFailUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV1_TERM_FAIL_H */ + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermSucc.c b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermSucc.c new file mode 100644 index 0000000000000000000000000000000000000000..b41124c53f4d71a3a68b6ddd77dcbbbf62abc68f --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermSucc.c @@ -0,0 +1,32 @@ +/** + * @file CrIaServ1TermSucc.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Telecommand Termination Report – Success out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ1TermSucc.h" + + +void CrIaServ1TermSuccUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + + /* Load the value of the report parameters */ + /* NOT USED: done in IfswUtilities function, which packs and finalizes out-going packet */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermSucc.h b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermSucc.h new file mode 100644 index 0000000000000000000000000000000000000000..ff38924a428a3a5aa58ce02ddf9f05fad068e678 --- /dev/null +++ b/CrIa/src/Services/CrIaServ1CommandVerificationService/OutRep/CrIaServ1TermSucc.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ1TermSucc.h + * + * Declaration of the Telecommand Termination Report – Success out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV1_TERM_SUCC_H +#define CRIA_SERV1_TERM_SUCC_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Telecommand Termination Report – Success telemetry packet. + * Load the value of the report parameters + * @param smDesc the state machine descriptor + */ +void CrIaServ1TermSuccUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV1_TERM_SUCC_H */ + diff --git a/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210DisWdog.c b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210DisWdog.c new file mode 100644 index 0000000000000000000000000000000000000000..4f5e65f4e97fb41e976c61b3808ce3bc30cfd52e --- /dev/null +++ b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210DisWdog.c @@ -0,0 +1,101 @@ +/** + * @file CrIaServ210DisWdog.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Disable Watchdog in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ210DisWdog.h" +#include <CrFwCmpData.h> +#include <FwSmConfig.h> + +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#if (__sparc__) +#include <ibsw_interface.h> +#endif + +#include "../../../IfswDebug.h" + + +void CrIaServ210DisWdogStartAction(FwSmDesc_t smDesc) +{ + unsigned char wdogEnb; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the watchdog is enabled */ + + CrIaCopy(ISWATCHDOGENABLED_ID, &wdogEnb); + + if (wdogEnb == 1) + { + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + + SendTcStartRepFail(pckt, 1124, 0, (unsigned short)wdogEnb); /* ACK_ILL_WD_STATUS = 1124 = 0x0464 */ + + return; +} + +void CrIaServ210DisWdogProgressAction(FwSmDesc_t smDesc) +{ + unsigned char wdogEnb; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Call the IBSW function which disables the watchdog */ +#if (__sparc__) + CrIbDisableWd(); +#endif + + /* NOTE: not necessary: stop the Watchdog Reset Procedure */ + + /* set the enable status of the watchdog in the data pool to: 'disabled' */ + wdogEnb = 0; + CrIaPaste(ISWATCHDOGENABLED_ID, &wdogEnb); + + /* set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + DEBUGP("S210: Disabled WD\n"); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210DisWdog.h b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210DisWdog.h new file mode 100644 index 0000000000000000000000000000000000000000..3f2044f8c3f6e66ece2a4184b0a128aa16f51083 --- /dev/null +++ b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210DisWdog.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ210DisWdog.h + * + * Declaration of the Disable Watchdog in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV210_DIS_WDOG_H +#define CRIA_SERV210_DIS_WDOG_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Disable Watchdog in-coming command packet. + * Set the action outcome to 'success' iff the watchdog is enabled + * @param smDesc the state machine descriptor + */ +void CrIaServ210DisWdogStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Disable Watchdog in-coming command packet. + * Call the IBSW function which disables the watchdog; set the enable status of the watchdog in the data pool to: 'disabled'; stop the Watchdog Reset Procedure; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ210DisWdogProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV210_DIS_WDOG_H */ + diff --git a/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210EnbWdog.c b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210EnbWdog.c new file mode 100644 index 0000000000000000000000000000000000000000..72263e37a74003d0fab4cce27cff659c1e733542 --- /dev/null +++ b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210EnbWdog.c @@ -0,0 +1,101 @@ +/** + * @file CrIaServ210EnbWdog.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Enable Watchdog in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ210EnbWdog.h" +#include <CrFwCmpData.h> +#include <FwSmConfig.h> + +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#if (__sparc__) +#include <ibsw_interface.h> +#endif + +#include "../../../IfswDebug.h" + + +void CrIaServ210EnbWdogStartAction(FwSmDesc_t smDesc) +{ + unsigned char wdogEnb; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + cmpData->outcome = 0; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Set the action outcome to 'success' iff the watchdog is disabled */ + + CrIaCopy(ISWATCHDOGENABLED_ID, &wdogEnb); + + if (wdogEnb == 0) + { + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; + } + + SendTcStartRepFail(pckt, 1124, 0, (unsigned short)wdogEnb); /* ACK_ILL_WD_STATUS = 1124 = 0x0464 */ + + return; +} + +void CrIaServ210EnbWdogProgressAction(FwSmDesc_t smDesc) +{ + unsigned char wdogEnb; + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + /* Call the IBSW function which enables the watchdog */ +#if (__sparc__) + CrIbEnableWd(); +#endif + + /* NOTE: not necessary: start the Watchdog Reset Procedure */ + + /* set the enable status of the watchdog in the data pool to: 'enabled' */ + wdogEnb = 1; + CrIaPaste(ISWATCHDOGENABLED_ID, &wdogEnb); + + /* set the action outcome to 'completed' */ + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + DEBUGP("S210: Enabled WD\n"); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210EnbWdog.h b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210EnbWdog.h new file mode 100644 index 0000000000000000000000000000000000000000..df07960f5def9059c0f25564b272d2d9ee31fe8e --- /dev/null +++ b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210EnbWdog.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ210EnbWdog.h + * + * Declaration of the Enable Watchdog in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV210_ENB_WDOG_H +#define CRIA_SERV210_ENB_WDOG_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Enable Watchdog in-coming command packet. + * Set the action outcome to 'success' iff the watchdog is disabled + * @param smDesc the state machine descriptor + */ +void CrIaServ210EnbWdogStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Enable Watchdog in-coming command packet. + * Call the IBSW function which enables the watchdog; start the Watchdog Reset Procedure; set the enable status of the watchdog in the data pool to: 'enabled' set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ210EnbWdogProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV210_ENB_WDOG_H */ + diff --git a/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210ResetDpu.c b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210ResetDpu.c new file mode 100644 index 0000000000000000000000000000000000000000..4b2c839cc6f9c8e5c15b463a7b5cd10a406fa62d --- /dev/null +++ b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210ResetDpu.c @@ -0,0 +1,91 @@ +/** + * @file CrIaServ210ResetDpu.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Reset DPU in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ210ResetDpu.h" +#include <CrFwCmpData.h> +#include <FwSmConfig.h> + +#include <IfswUtilities.h> +#include <CrIaPrSm/CrIaSemCreate.h> /* for SwitchOff transition command and CrIaSem_OFF mode */ + +#if (__sparc__) +#include <ibsw_interface.h> +#include <exchange_area.h> +#else +#include <stdlib.h> /* for exit() */ +#endif + +#include "../../../IfswDebug.h" + + +void CrIaServ210ResetDpuStartAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + SendTcAccRepSucc(pckt); /* in the case that no validity check is done also a successful acknowledge report will be sent */ + + /* Start the DPU Reset Procedure and set the action outcome to 'success' */ + + /* NOTE: not needed: start the DPU Reset Procedure */ + + /* Send the SwitchOff command to the SEM State Machine (Mantis 2052) */ + FwSmMakeTrans(smDescSem, SwitchOff); + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; +} + +void CrIaServ210ResetDpuProgressAction(FwSmDesc_t smDesc) +{ + CrFwCmpData_t* cmpData; + + /* Call the IBSW function which triggers a DPU reset; set the action outcome to 'completed' - HAHA */ + + DEBUGP("Service (210,5) => Carrying out Warm Reset!\nBye.\n"); + + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + + /* return 2 ('continue') if the SEM State Machine is in a state other than off; + if SEM State Machine is in off, command the DPU reset and return 1 ('completed') (Mantis 2052) */ + if (FwSmGetCurState(smDescSem) != CrIaSem_OFF) + { + cmpData->outcome = 2; + return; + } + else + { +#if (__sparc__) + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_CO); +#else + exit (210); +#endif + } + + return; +} + diff --git a/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210ResetDpu.h b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210ResetDpu.h new file mode 100644 index 0000000000000000000000000000000000000000..365628f992339bfa5c40e8d46878ceaa73f2b632 --- /dev/null +++ b/CrIa/src/Services/CrIaServ210BootManagementService/InCmd/CrIaServ210ResetDpu.h @@ -0,0 +1,31 @@ +/** + * @file CrIaServ210ResetDpu.h + * + * Declaration of the Reset DPU in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV210_RESET_DPU_H +#define CRIA_SERV210_RESET_DPU_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Start action of the Reset DPU in-coming command packet. + * Start the DPU Reset Procedre and set the action outcome to 'success' + * @param smDesc the state machine descriptor + */ +void CrIaServ210ResetDpuStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Reset DPU in-coming command packet. + * Call the IBSW function which triggers a DPU reset; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ210ResetDpuProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV210_RESET_DPU_H */ + diff --git a/CrIa/src/Services/CrIaServ211ParameterUpdateService/InCmd/CrIaServ211UpdatePar.c b/CrIa/src/Services/CrIaServ211ParameterUpdateService/InCmd/CrIaServ211UpdatePar.c new file mode 100644 index 0000000000000000000000000000000000000000..786c24c7abd31cc666d173e444fff1830b595443 --- /dev/null +++ b/CrIa/src/Services/CrIaServ211ParameterUpdateService/InCmd/CrIaServ211UpdatePar.c @@ -0,0 +1,263 @@ +/** + * @file CrIaServ211UpdatePar.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Update Parameter in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ211UpdatePar.h" +#include <CrFwCmpData.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <Services/General/CrIaParamGetter.h> + +#include "../../../IfswDebug.h" + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrConfigIa/CrFwUserConstants.h> +#include <Services/General/CrIaConstants.h> + +#include <byteorder.h> +#include <stdint.h> + + +/* see 22.1 TC(211,1) Update Parameter ParamType + * + * TYPE_UINT8 1 + * TYPE_UINT16 2 + * TYPE_UINT32 3 + * TYPE_INT8 4 + * TYPE_INT16 5 + * TYPE_INT32 6 + * TYPE_BOOL 7 + * TYPE_FLOAT 8 + * TYPE_DOUBLE 9 + * TYPE_CUC 10 + * + * only 4 byte types are used (for now? TBC), + * hence the limit below: + */ + +#define MAX_TYPE_ID 8 + +/* The data pool uses much more relaxed integer types, but they will default + * to those below, so this is fine and much more explicit. (Remember, an int is + * only guaranteed to be at least 16 bits by the standard) + */ +unsigned char type_length[] = {0, + sizeof(uint8_t), sizeof(uint16_t), sizeof(uint32_t), + sizeof(int8_t), sizeof(int16_t), sizeof(int32_t), + sizeof(uint8_t), sizeof(float), sizeof(double), + sizeof(CrFwTimeStamp_t) + }; + + +CrFwBool_t CrIaServ211UpdateParValidityCheck(FwPrDesc_t prDesc) +{ + unsigned char len; + unsigned char param_type; + + unsigned short offset = 0; + unsigned short num_params; + unsigned short array_elem_id; + + unsigned int i; + unsigned int param_id; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* Data item identifiers must be legal; parameter size (as determined by its type) must match the size of the data item to be updated; for array-like data items: array element index must be smaller than array length */ + + CrIaServ211UpdateParParamGetNoParams(&num_params, pckt); + + for (i = 0; i < num_params; i++) + { + + CrIaServ211UpdateParParamGetParamId(¶m_id, offset, pckt); + CrIaServ211UpdateParParamGetParamType(¶m_type, offset, pckt); + CrIaServ211UpdateParParamGetArrayElemId(&array_elem_id, offset, pckt); + + len = type_length[param_type]; + + if (param_id == 0) /* Mantis 2247 handling of closed back-door */ + { + SendTcAccRepFail(pckt, ACK_ILL_DID); + return 0; + } + + if (param_id > DP_ID_MAX) + { + SendTcAccRepFail(pckt, ACK_ILL_DID); + return 0; + } + + if (param_type > MAX_TYPE_ID) + { + SendTcAccRepFail(pckt, ACK_ILL_PTYP); + return 0; + } + + if (len != GetDataPoolSize(param_id)) + { + SendTcAccRepFail(pckt, ACK_WR_PLEN); + return 0; + } + + if (array_elem_id >= GetDataPoolMult(param_id)) + { + SendTcAccRepFail(pckt, ACK_ILL_ELEM); + return 0; + } + + /* next block */ + offset += (sizeof(param_id) + sizeof(param_type) + + sizeof(array_elem_id) + len); + } + + cmpData->outcome = 1; + + SendTcAccRepSucc(pckt); + + return 1; +} + + + +void CrIaServ211UpdateParStartAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' */ + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; +} + + + +void CrIaServ211UpdateParProgressAction(FwSmDesc_t smDesc) +{ + unsigned char len; + unsigned char param_type; + + unsigned short offset = 0; + unsigned short num_params; + unsigned short array_elem_id; + + unsigned int i; + unsigned int tmp; + unsigned int param_id; + + unsigned char *ptr; + unsigned char utemp8 = 1; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Update the data item value; set the action outcome to 'completed' */ + + CrIaServ211UpdateParParamGetNoParams(&num_params, pckt); + + for (i = 0; i < num_params; i++) + { + + CrIaServ211UpdateParParamGetParamId(¶m_id, offset, pckt); + CrIaServ211UpdateParParamGetParamType(¶m_type, offset, pckt); + CrIaServ211UpdateParParamGetArrayElemId(&array_elem_id, offset, pckt); + + len = type_length[param_type]; + + tmp = 0; + + /* get the right spot */ + ptr = ((unsigned char *) &tmp) + (sizeof(uint32_t) - len); + + CrIaServ211UpdateParParamGetParamValue(ptr, offset, len, pckt); + +#if !(__sparc__) + switch (len) + { + case 2: + be16_to_cpus((unsigned short *) ptr); + break; + case 4: + be32_to_cpus((unsigned int *) ptr); + break; + } +#endif + + /* we use the paste single array element function also for the non-array parameters + * Because the parameter is passed below using a possibly larger container + * dataype, we have to adapt the pointer with the difference of the + * container sizes, similar to what will happen in the called function + * CrIaPasteArrayItem -> (TmType vs ImplType) + */ + CrIaPasteArrayItem(param_id, ptr, array_elem_id); + + /* Mantis 2219 */ + if ((param_id == FBF_ENB_ID) && (*ptr == 1)) + { + CrIaPasteArrayItem(ISFBFVALID_ID, &utemp8, array_elem_id); + } + + /* next block */ + offset += (sizeof(param_id) + sizeof(param_type) + + sizeof(array_elem_id) + len); + } + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ211ParameterUpdateService/InCmd/CrIaServ211UpdatePar.h b/CrIa/src/Services/CrIaServ211ParameterUpdateService/InCmd/CrIaServ211UpdatePar.h new file mode 100644 index 0000000000000000000000000000000000000000..257365c15db2a258bc5441446eefe9279cc10cf3 --- /dev/null +++ b/CrIa/src/Services/CrIaServ211ParameterUpdateService/InCmd/CrIaServ211UpdatePar.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ211UpdatePar.h + * + * Declaration of the Update Parameter in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV211_UPDATE_PAR_H +#define CRIA_SERV211_UPDATE_PAR_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Update Parameter in-coming command packet. + * Data item identifiers must be legal; parameter size (as determined by its type) must match the size of the data item to be updated; for array-like data items: array element index must be smaller than array length + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ211UpdateParValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Update Parameter in-coming command packet. + * Set the action outcome to 'success' + * @param smDesc the state machine descriptor + */ +void CrIaServ211UpdateParStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Update Parameter in-coming command packet. + * Update the data item value; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ211UpdateParProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV211_UPDATE_PAR_H */ + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3ClrHkDr.c b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3ClrHkDr.c new file mode 100644 index 0000000000000000000000000000000000000000..1ad4175be66394a96eb465d6af85093742559b72 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3ClrHkDr.c @@ -0,0 +1,152 @@ +/** + * @file CrIaServ3ClrHkDr.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Clear Housekeeping Data Report in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ3ClrHkDr.h" +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaConstants.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +CrFwBool_t CrIaServ3ClrHkDrValidityCheck(FwPrDesc_t prDesc) +{ + unsigned char sid; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* SID must be in interval: (1..SID_MAX) */ + CrIaServ3ClrHkDrParamGetSid(&sid, pckt); + + if (sid && sid <= SID_MAX) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_SID); + return 0; +} + + +void CrIaServ3ClrHkDrStartAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID */ + + CrIaServ3ClrHkDrParamGetSid(&sid, pckt); + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* sid not found in list */ + if (rdlSlot == RDL_SIZE) + { + DEBUGP("SID %d not found!\n", sid); + SendTcStartRepFail(pckt, ACK_SID_NOT_USED, 1, (unsigned short)sid); + return; + } + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + return; +} + + +void CrIaServ3ClrHkDrProgressAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot, rdlFree, rdlEnabled; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Mark the entry in the RDL corresponding to the argument SID as 'free'; set the action outcome to 'completed'. */ + + CrIaServ3ClrHkDrParamGetSid(&sid, pckt); + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + rdlFree = 1; + CrIaPasteArrayItem(ISRDLFREE_ID, &rdlFree, rdlSlot); + + /* in addition, we disable it */ + rdlEnabled = 0; + CrIaPasteArrayItem(RDLENABLEDLIST_ID, &rdlEnabled, rdlSlot); + + /* NOTE: Do not clear the SID here, especially for predefined HK SID slots (see Mantis 1755) */ + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + return; +} + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3ClrHkDr.h b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3ClrHkDr.h new file mode 100644 index 0000000000000000000000000000000000000000..ac447a90a646fbc5dad0a23e989660059f62458b --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3ClrHkDr.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ3ClrHkDr.h + * + * Declaration of the Clear Housekeeping Data Report in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV3_CLR_HK_DR_H +#define CRIA_SERV3_CLR_HK_DR_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Clear Housekeeping Data Report in-coming command packet. + * SID must be in interval: (1..SID_MAX) + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ3ClrHkDrValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Clear Housekeeping Data Report in-coming command packet. + * Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID + * @param smDesc the state machine descriptor + */ +void CrIaServ3ClrHkDrStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Clear Housekeeping Data Report in-coming command packet. + * Mark the entry in the RDL corresponding to the argument SID as 'free'; set the action outcome to 'completed'. + * @param smDesc the state machine descriptor + */ +void CrIaServ3ClrHkDrProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV3_CLR_HK_DR_H */ + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DefineHkDr.c b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DefineHkDr.c new file mode 100644 index 0000000000000000000000000000000000000000..ddaa2348b5e1dac4ee0356fb19277b1c18549065 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DefineHkDr.c @@ -0,0 +1,347 @@ +/** + * @file CrIaServ3DefineHkDr.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Define New Housekeeping Data Report in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ3DefineHkDr.h" +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaConstants.h> /* for OFFSET_PAR_LENGTH_IN_CMD_PCKT */ + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <OutLoader/CrFwOutLoader.h> +#include <OutFactory/CrFwOutFactory.h> +#include <OutCmp/CrFwOutCmp.h> + +/* #include <string.h> */ + +#include "IfswDebug.h" + +#define LISTITEMSIZE 4 + +CrFwBool_t CrIaServ3DefineHkDrValidityCheck(FwPrDesc_t prDesc) +{ + unsigned char sid; + + unsigned short items; + + unsigned int i, size; + unsigned int item_id; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* SID must be in interval: (1..SID_MAX); number of Data Item Identifiers in interval: (1..RD_MAX_ITEMS); identifiers must be in interval: (1..DP_ID_MAX); total size of data items must be at most RD_MAX_SIZE */ + + CrIaServ3DefineHkDrParamGetSid(&sid, pckt); + CrIaServ3DefineHkDrParamGetNoDataItemId(&items, pckt); + + /* check range of SID */ + if (sid == 0 || sid > SID_MAX) + { + SendTcAccRepFail(pckt, ACK_ILL_SID); + return 0; + } + + /* check number of items */ + if (items == 0 || items > RD_MAX_ITEMS) + { + SendTcAccRepFail(pckt, ACK_ILL_NDI); + return 0; + } + + /* check data item IDs for their range validity */ + for (i = 0; i < items; i++) + { + CrIaServ3DefineHkDrParamGetDataItemId(&item_id, LISTITEMSIZE, i * LISTITEMSIZE, pckt); + + if (item_id == 0 || item_id > DP_ID_MAX) + { + SendTcAccRepFail(pckt, ACK_ILL_DID); + return 0; + } + } + + /* get and check total size of data items */ + for (i=0, size=0; i < items; i++) + { + CrIaServ3DefineHkDrParamGetDataItemId(&item_id, LISTITEMSIZE, i * LISTITEMSIZE, pckt); + + size += GetDataPoolSize(item_id) * GetDataPoolMult(item_id); + } + + /* Compare size of parameter part of the new generated report with maximum size of parameter part. */ + /* size of parameter part: RD_MAX_SIZE (packet size) - header_size - discriminant_size (SID) - CRC_size */ + if (size > (RD_MAX_SIZE - OFFSET_PAR_LENGTH_OUT_REP_PCKT - 1 - CRC_LENGTH)) + { + SendTcAccRepFail(pckt, ACK_ILL_DSIZE); + return 0; + } + + SendTcAccRepSucc(pckt); + + return 1; +} + + +void CrIaServ3DefineHkDrStartAction(FwSmDesc_t smDesc) +{ + unsigned char sid; + + unsigned char rdlSid, rdlFree; + unsigned int i; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff the argument SID is not already in use and if there is a free slot in the RDL */ + + CrIaServ3DefineHkDrParamGetSid(&sid, pckt); + + /* check if the sid is not already taken */ + for (i = 0; i < RDL_SIZE; i++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, i); + + if (rdlSid == sid) + { + /* the sid is taken, but is it actually marked as used? */ + CrIaCopyArrayItem(ISRDLFREE_ID, &rdlFree, i); + + if (rdlFree == 0) + { + SendTcStartRepFail(pckt, ACK_SID_IN_USE, 1, (unsigned short)sid); + return; + } + } + } + + /* look for the first free RDL slot */ + for (i = 0; i < RDL_SIZE; i++) + { + CrIaCopyArrayItem(ISRDLFREE_ID, &rdlFree, i); + + if (rdlFree == 1) + break; + } + /* i contains now the index of the free RDL slot */ + + if (i == RDL_SIZE) + { + SendTcStartRepFail(pckt, ACK_RDL_NO_SLOT, 0, (unsigned int)i); + return; + } + + cmpData->outcome = 1; + + SendTcStartRepSucc(pckt); + + return; +} + + +/** + * @brief Progress Action of the Service 3 Define New Housekeeping + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Load report definition in the command parameter into a free slot of the RDL and mark the slot as 'not free' + * - Set the enable status in the RDL of the newly-defined report definition to 'enabled' + * - Run the OutComponent Load Procedure to load the newly-defined report in its POCL + * if report was not loaded in POCL: + * - Clear the definition of the new report in the RDL by marking its slot as 'free' + * + * @param[in] smDesc state machine descriptor + * @param[out] none + */ +void CrIaServ3DefineHkDrProgressAction(FwSmDesc_t smDesc) +{ + unsigned char rdlSid, rdlFree, rdlSlot; + unsigned char rdlEnabled; + + unsigned short numItems; + unsigned short getPeriod; + + unsigned int i; + unsigned int itemId, rdlListId; + unsigned int rdlPeriod; + unsigned int rdlCycCnt; + unsigned int hkPacketSize; + + unsigned short RdlDataItemList[RD_MAX_ITEMS]; + + FwSmDesc_t rep; + + CrFwGroup_t group = 1; /* PCAT = 2 */ + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Run procedure of figure CrIaPrgAct3s1 */ + /* NOTE: not needed: Run procedure */ + + CrIaServ3DefineHkDrParamGetSid(&rdlSid, pckt); + + /* look for the first free RDL slot */ + for (i = 0; i < RDL_SIZE; i++) + { + CrIaCopyArrayItem(ISRDLFREE_ID, &rdlFree, i); + + if (rdlFree == 1) + break; + } + /* i contains now the index of the free RDL slot */ + rdlSlot = i; + + /* paste sid into the RdlSidList */ + CrIaPasteArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + + /* mark as taken */ + rdlFree = 0; + CrIaPasteArrayItem(ISRDLFREE_ID, &rdlFree, rdlSlot); + + /* get and enter Period */ + CrIaServ3DefineHkDrParamGetPeriod(&getPeriod, pckt); /* NOTE: getter is in ushort, but RDL entry is uint */ + + rdlPeriod = (unsigned int) getPeriod; + CrIaPasteArrayItem(RDLPERIODLIST_ID, &rdlPeriod, rdlSlot); + + /* clear the RDL before */ + CrIaServ3DefineHkDrParamGetNoDataItemId(&numItems, pckt); + + /* enter items */ + for (i=0; i < numItems; i++) + { + CrIaServ3DefineHkDrParamGetDataItemId(&itemId, LISTITEMSIZE, i * LISTITEMSIZE, pckt); + RdlDataItemList[i] = itemId; + } + + /* fill rest of list with zeroes */ + for ( ; i < RD_MAX_ITEMS; i++) + RdlDataItemList[i] = 0; + + /* get the data pool handle of the list */ + switch (rdlSlot) + { + case 0: + rdlListId = RDLDATAITEMLIST_0_ID; + break; + case 1: + rdlListId = RDLDATAITEMLIST_1_ID; + break; + case 2: + rdlListId = RDLDATAITEMLIST_2_ID; + break; + case 3: + rdlListId = RDLDATAITEMLIST_3_ID; + break; + case 4: + rdlListId = RDLDATAITEMLIST_4_ID; + break; + case 5: + rdlListId = RDLDATAITEMLIST_5_ID; + break; + case 6: + rdlListId = RDLDATAITEMLIST_6_ID; + break; + case 7: + rdlListId = RDLDATAITEMLIST_7_ID; + break; + case 8: + rdlListId = RDLDATAITEMLIST_8_ID; + break; + case 9: + rdlListId = RDLDATAITEMLIST_9_ID; + break; + default : + SendTcTermRepFail(pckt, ACK_RDL_NO_SLOT, 0, (unsigned short)rdlSlot); + return; + } + + /* copy the local elements (16 bit) into the data pool list (element-wise) */ + CrIaPaste(rdlListId, RdlDataItemList); + + /* enable the list */ + rdlEnabled = 1; + CrIaPasteArrayItem(RDLENABLEDLIST_ID, &rdlEnabled, rdlSlot); + + /* we also set the cycle counter for this RDL to 1 */ + rdlCycCnt = 0; + CrIaPasteArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + + /* determine the size of this HK packet to be created */ + hkPacketSize = getHkDataSize(rdlSid); + + /* prepare packet */ + rep = CrFwOutFactoryMakeOutCmp(CRIA_SERV3, CRIA_SERV3_HK_DR, rdlSid, hkPacketSize); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + + /* clear the definition of the new report in the RDL by marking its slot as 'free' */ + /* mark as free */ + rdlFree = 1; + CrIaPasteArrayItem(ISRDLFREE_ID, &rdlFree, rdlSlot); + + return; + } + + CrFwOutCmpSetGroup(rep, group); + CrFwOutLoaderLoad(rep); /* Mantis 1857: a load failure will result in the generation of an error by the OutManager */ + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + return; +} + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DefineHkDr.h b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DefineHkDr.h new file mode 100644 index 0000000000000000000000000000000000000000..da796b42c70c970e4bf892feacc616b30bff0be1 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DefineHkDr.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ3DefineHkDr.h + * + * Declaration of the Define New Housekeeping Data Report in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV3_DEFINE_HK_DR_H +#define CRIA_SERV3_DEFINE_HK_DR_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Define New Housekeeping Data Report in-coming command packet. + * SID must be in interval: (1..SID_MAX); number of Data Item Identifiers in interval: (1..RD_MAX_ITEMS); identifiers must be in interval: (1..DP_ID_MAX); total size of data items must be at most RD_MAX_SIZE + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ3DefineHkDrValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Define New Housekeeping Data Report in-coming command packet. + * Set the action outcome to 'success' iff the argument SID is not already in use and if there is a free slot in the RDL + * @param smDesc the state machine descriptor + */ +void CrIaServ3DefineHkDrStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Define New Housekeeping Data Report in-coming command packet. + * Run procedure of figure CrIaPrgAct3s1 + * @param smDesc the state machine descriptor + */ +void CrIaServ3DefineHkDrProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV3_DEFINE_HK_DR_H */ + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DisHkDrGen.c b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DisHkDrGen.c new file mode 100644 index 0000000000000000000000000000000000000000..cc728fa3fc35ea8d84b26d8f9f145e08a7867aba --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DisHkDrGen.c @@ -0,0 +1,148 @@ +/** + * @file CrIaServ3DisHkDrGen.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Disable Housekeeping Data Report Generation in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ3DisHkDrGen.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaConstants.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +CrFwBool_t CrIaServ3DisHkDrGenValidityCheck(FwPrDesc_t prDesc) +{ + unsigned char sid; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* SID must be in interval: (1..SID_MAX) */ + + CrIaServ3DisHkDrGenParamGetSid(&sid, pckt); + + if (sid && sid <= SID_MAX) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_SID); + return 0; +} + + +void CrIaServ3DisHkDrGenStartAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID */ + + CrIaServ3DisHkDrGenParamGetSid(&sid, pckt); + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* sid not found in list */ + if (rdlSlot == RDL_SIZE) + { + DEBUGP("SID %d not found!\n", sid); + SendTcStartRepFail(pckt, ACK_SID_NOT_USED, 1, (unsigned short)sid); + return; + } + + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; +} + + +void CrIaServ3DisHkDrGenProgressAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot, rdlEnabled; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the enable status of the entry in the RDL corresponding to the argument SID to 'disabled'; set the action outcome to 'completed'. */ + + CrIaServ3DisHkDrGenParamGetSid(&sid, pckt); + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + rdlEnabled = 0; + CrIaPasteArrayItem(RDLENABLEDLIST_ID, &rdlEnabled, rdlSlot); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + return; +} + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DisHkDrGen.h b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DisHkDrGen.h new file mode 100644 index 0000000000000000000000000000000000000000..1d47e6236705beccb7f4e3db93de62c5feeae749 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3DisHkDrGen.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ3DisHkDrGen.h + * + * Declaration of the Disable Housekeeping Data Report Generation in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV3_DIS_HK_DR_GEN_H +#define CRIA_SERV3_DIS_HK_DR_GEN_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Disable Housekeeping Data Report Generation in-coming command packet. + * SID must be in interval: (1..SID_MAX) + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ3DisHkDrGenValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Disable Housekeeping Data Report Generation in-coming command packet. + * Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID + * @param smDesc the state machine descriptor + */ +void CrIaServ3DisHkDrGenStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Disable Housekeeping Data Report Generation in-coming command packet. + * Set the enable status of the entry in the RDL corresponding to the argument SID to 'disabled'; set the action outcome to 'completed'. + * @param smDesc the state machine descriptor + */ +void CrIaServ3DisHkDrGenProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV3_DIS_HK_DR_GEN_H */ + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3EnbHkDrGen.c b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3EnbHkDrGen.c new file mode 100644 index 0000000000000000000000000000000000000000..2c3f2094801ce51de670cb7730e5d8dd14e815a5 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3EnbHkDrGen.c @@ -0,0 +1,153 @@ +/** + * @file CrIaServ3EnbHkDrGen.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Enable Housekeeping Data Report Generation in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ3EnbHkDrGen.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaConstants.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +CrFwBool_t CrIaServ3EnbHkDrGenValidityCheck(FwPrDesc_t prDesc) +{ + unsigned char sid; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* SID must be in interval: (1..SID_MAX) */ + + CrIaServ3EnbHkDrGenParamGetSid(&sid, pckt); + + if (sid && sid <= SID_MAX) + { + SendTcAccRepSucc(pckt); + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_SID); + + return 0; +} + + +void CrIaServ3EnbHkDrGenStartAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID */ + + CrIaServ3EnbHkDrGenParamGetSid(&sid, pckt); + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* sid not found in list */ + if (rdlSlot == RDL_SIZE) + { + DEBUGP("SID %d not found!\n", sid); + SendTcStartRepFail(pckt, ACK_SID_NOT_USED, 1, (unsigned short)sid); + return; + } + + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; +} + + +void CrIaServ3EnbHkDrGenProgressAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot, rdlEnabled; + + unsigned int rdlCycCnt; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the enable status of the entry in the RDL corresponding to the argument SID to 'enabled' and set the cycle counter of the same RDL entry to zero; set the action outcome to 'completed'. */ + + CrIaServ3EnbHkDrGenParamGetSid(&sid, pckt); + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + rdlEnabled = 1; + CrIaPasteArrayItem(RDLENABLEDLIST_ID, &rdlEnabled, rdlSlot); + + rdlCycCnt = 0; + CrIaPasteArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + return; +} diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3EnbHkDrGen.h b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3EnbHkDrGen.h new file mode 100644 index 0000000000000000000000000000000000000000..4e93f10f3d01b1467d2aa7d84f325d70de9ef3ec --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3EnbHkDrGen.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ3EnbHkDrGen.h + * + * Declaration of the Enable Housekeeping Data Report Generation in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV3_ENB_HK_DR_GEN_H +#define CRIA_SERV3_ENB_HK_DR_GEN_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Enable Housekeeping Data Report Generation in-coming command packet. + * SID must be in interval: (1..SID_MAX) + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ3EnbHkDrGenValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Enable Housekeeping Data Report Generation in-coming command packet. + * Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID + * @param smDesc the state machine descriptor + */ +void CrIaServ3EnbHkDrGenStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Enable Housekeeping Data Report Generation in-coming command packet. + * Set the enable status of the entry in the RDL corresponding to the argument SID to 'enabled' and set the cycle counter of the same RDL entry to zero; set the action outcome to 'completed'. + * @param smDesc the state machine descriptor + */ +void CrIaServ3EnbHkDrGenProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV3_ENB_HK_DR_GEN_H */ + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3SetHkRepFreq.c b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3SetHkRepFreq.c new file mode 100644 index 0000000000000000000000000000000000000000..4b9d8ac9a7b96ce239974e7c76889a26f32e4d07 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3SetHkRepFreq.c @@ -0,0 +1,160 @@ +/** + * @file CrIaServ3SetHkRepFreq.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Set Housekeeping Reporting Frequency in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ3SetHkRepFreq.h" +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaConstants.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +CrFwBool_t CrIaServ3SetHkRepFreqValidityCheck(FwPrDesc_t prDesc) +{ + unsigned char sid; + unsigned short period; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* SID must be in interval: (1..SID_MAX) and period must be a non-negative integer */ + + CrIaServ3SetHkRepFreqParamGetSid(&sid, pckt); + CrIaServ3SetHkRepFreqParamGetPeriod(&period, pckt); + + if (sid == 0 || sid > SID_MAX) + { + SendTcAccRepFail(pckt, ACK_ILL_SID); + return 0; + } + + /* no check on period necessary, because it has an unsigned dataype and 0 is valid */ + + SendTcAccRepSucc(pckt); + return 1; +} + + +void CrIaServ3SetHkRepFreqStartAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID */ + + CrIaServ3SetHkRepFreqParamGetSid(&sid, pckt); + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* sid not found in list */ + if (rdlSlot == RDL_SIZE) + { + DEBUGP("SID %d not found!\n", sid); + SendTcStartRepFail(pckt, ACK_SID_NOT_USED, 1, (unsigned short)sid); + return; + } + + cmpData->outcome = 1; + SendTcStartRepSucc(pckt); + return; +} + + +void CrIaServ3SetHkRepFreqProgressAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot; + + unsigned short getPeriod; + + unsigned int rdlPeriod, rdlCycCnt; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the period of the entry in the RDL corresponding to the argument SID to the value specified in the command argument; set the cycle counter in the same RDL entry to zero; set the action outcome to 'completed'. */ + + CrIaServ3SetHkRepFreqParamGetSid(&sid, pckt); + CrIaServ3SetHkRepFreqParamGetPeriod(&getPeriod, pckt); /* NOTE: datatype in packet and in DP are different */ + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + rdlPeriod = (unsigned int) getPeriod; /* NOTE: datatype in packet and in DP are different */ + + CrIaPasteArrayItem(RDLPERIODLIST_ID, &rdlPeriod, rdlSlot); + + rdlCycCnt = 0; + CrIaPasteArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + + cmpData->outcome = 1; + + SendTcTermRepSucc(pckt); + return; +} + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3SetHkRepFreq.h b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3SetHkRepFreq.h new file mode 100644 index 0000000000000000000000000000000000000000..12fc10868e57653abeedb4d3740ad56d471d61d5 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/InCmd/CrIaServ3SetHkRepFreq.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ3SetHkRepFreq.h + * + * Declaration of the Set Housekeeping Reporting Frequency in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV3_SET_HK_REP_FREQ_H +#define CRIA_SERV3_SET_HK_REP_FREQ_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Set Housekeeping Reporting Frequency in-coming command packet. + * SID must be in interval: (1..SID_MAX) and period must be a non-negative integer + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ3SetHkRepFreqValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Set Housekeeping Reporting Frequency in-coming command packet. + * Set the action outcome to 'success' iff there is an entry in the RDL corresponding to the argument SID + * @param smDesc the state machine descriptor + */ +void CrIaServ3SetHkRepFreqStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Set Housekeeping Reporting Frequency in-coming command packet. + * Set the period of the entry in the RDL corresponding to the argument SID to the value specified in the command argument; set the cycle counter in the same RDL entry to zero; set the action outcome to 'completed'. + * @param smDesc the state machine descriptor + */ +void CrIaServ3SetHkRepFreqProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV3_SET_HK_REP_FREQ_H */ + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/OutRep/CrIaServ3HkDr.c b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/OutRep/CrIaServ3HkDr.c new file mode 100644 index 0000000000000000000000000000000000000000..2b01181972b0ebbf607f6915888504154c8fb9b7 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/OutRep/CrIaServ3HkDr.c @@ -0,0 +1,263 @@ +/** + * @file CrIaServ3HkDr.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Housekeeping Data Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ3HkDr.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaConstants.h> /* for ACK_SID_NOT_USED */ + +#include <CrIaPckt.h> +#include <IfswUtilities.h> +#include <CrFramework/OutCmp/CrFwOutCmp.h> +#include <Pckt/CrFwPckt.h> + +#include <CrFwCmpData.h> +#include <CrIaPckt.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <stdlib.h> +#include "../../../IfswDebug.h" + + +CrFwBool_t CrIaServ3HkDrEnableCheck(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlFree, rdlSid, rdlSlot; + + CrFwPckt_t pckt; + CrFwDiscriminant_t disc; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + disc = CrFwPcktGetDiscriminant(pckt); + + /* IsEnabled = (RDL entry corresponding to argument SID is not free) */ + + /* discriminant for HK is the SID */ + sid = (unsigned char) disc; + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* get information if the list is used */ + CrIaCopyArrayItem(ISRDLFREE_ID, &rdlFree, rdlSlot); + + if (rdlFree == 0) + return 1; + + return 0; +} + + +/** + * @brief Ready Check action of the Service 3 Housekeeping Data Report + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Check the enable status + * if enabled: + * - Check the cycle counter + * + * @param[in] smDesc state machine descriptor + * @param[out] 1 ('ready') or 0 ('not ready') + */ +CrFwBool_t CrIaServ3HkDrReadyCheck(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot, rdlEnabled; + unsigned int rdlPeriod, rdlCycCnt; + + CrFwPckt_t pckt; + CrFwDiscriminant_t disc; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + disc = CrFwPcktGetDiscriminant(pckt); + + /* Execute the procedure of figure CrIaReadyChk3s25 (NOTE: is manually implemented) */ + + /* disc for HK is the SID */ + sid = (unsigned char) disc; + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* + DEBUGP("ready check for SID %d %d in slot %d\n", sid, rdlSid, rdlSlot); + */ + CrIaCopyArrayItem(RDLENABLEDLIST_ID, &rdlEnabled, rdlSlot); + CrIaCopyArrayItem(RDLPERIODLIST_ID, &rdlPeriod, rdlSlot); + CrIaCopyArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + /* + DEBUGP("enb %d per %d cyc %d\n", rdlEnabled, rdlPeriod, rdlCycCnt); + */ + if (rdlEnabled == 0) + return 0; + + /* in the case p=0 we move on to the repeat check, where this special case is handled */ + /* if (rdl_period == 0) + return 1; */ + + /* for all normal "waiting" cases: */ + /* cycle == 0 -> return 1 ; reset cycle counter to period - 1; write cycle counter back to data pool */ + if (rdlCycCnt == 0) + { + rdlCycCnt = rdlPeriod - 1; + CrIaPasteArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + return 1; + } + + /* If period == 0, then the cycle counter will be decremented once to -1 and stay there */ + /* if period 0xffffffff is commanded, it will never output a HK, but this will only be discovered after 20 years */ + if (rdlCycCnt != 0xffffffff) + rdlCycCnt--; + + CrIaPasteArrayItem(RDLCYCCNTLIST_ID, &rdlCycCnt, rdlSlot); + + return 0; +} + +void CrIaServ3HkDrUpdateAction(FwSmDesc_t smDesc) +{ + unsigned char sid, rdlSid, rdlSlot; + unsigned short rdlDest; + + unsigned int i; + unsigned int len, typelen; + unsigned int offset = 0; + unsigned int rdlListId = 0; + + unsigned short RdlDataItemList[250]; + + CrFwPckt_t pckt; + CrFwDiscriminant_t disc; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + disc = CrFwPcktGetDiscriminant(pckt); + + /* Load the values of the data pool items associated to the RDL entry corresponding to the report's SID */ + + sid = (unsigned char) disc; + + /* look for the slot */ + for (rdlSlot = 0; rdlSlot < RDL_SIZE; rdlSlot++) + { + CrIaCopyArrayItem(RDLSIDLIST_ID, &rdlSid, rdlSlot); + if (sid == rdlSid) + break; + } + + /* get the data pool handle of the list */ + switch (rdlSlot) + { + case 0: + rdlListId = RDLDATAITEMLIST_0_ID; + break; + case 1: + rdlListId = RDLDATAITEMLIST_1_ID; + break; + case 2: + rdlListId = RDLDATAITEMLIST_2_ID; + break; + case 3: + rdlListId = RDLDATAITEMLIST_3_ID; + break; + case 4: + rdlListId = RDLDATAITEMLIST_4_ID; + break; + case 5: + rdlListId = RDLDATAITEMLIST_5_ID; + break; + case 6: + rdlListId = RDLDATAITEMLIST_6_ID; + break; + case 7: + rdlListId = RDLDATAITEMLIST_7_ID; + break; + case 8: + rdlListId = RDLDATAITEMLIST_8_ID; + break; + case 9: + rdlListId = RDLDATAITEMLIST_9_ID; + break; + default : + SendTcTermRepFail(pckt, ACK_RDL_NO_SLOT, 0, (unsigned short)rdlSlot); + return; + } + + CrIaCopy(rdlListId, RdlDataItemList); + + for (i = 0; i < RD_MAX_ITEMS; i++) + { + if (RdlDataItemList[i] == 0) + break; + + typelen = GetDataPoolSize((unsigned int)RdlDataItemList[i]); + len = GetDataPoolMult((unsigned int)RdlDataItemList[i]) * typelen; + +#if (__sparc__) + switch (typelen) + { + case 4: + CrIaCopy(RdlDataItemList[i], (unsigned int *) &pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1 + offset]); + break; + case 2: + CrIaCopy(RdlDataItemList[i], (unsigned short *) &pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1 + offset]); + break; + default: + CrIaCopy(RdlDataItemList[i], &pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1 + offset]); + break; + } +#else + CrIaCopyPcPckt(RdlDataItemList[i], &pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1 + offset]); +#endif + + offset += len; + } + + CrIaCopyArrayItem(RDLDESTLIST_ID, &rdlDest, rdlSlot); + + CrFwOutCmpSetDest(smDesc, rdlDest); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/OutRep/CrIaServ3HkDr.h b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/OutRep/CrIaServ3HkDr.h new file mode 100644 index 0000000000000000000000000000000000000000..a46f3308b0624878dbb120a86f5d7975c4939784 --- /dev/null +++ b/CrIa/src/Services/CrIaServ3HousekeepingDataReportingService/OutRep/CrIaServ3HkDr.h @@ -0,0 +1,40 @@ +/** + * @file CrIaServ3HkDr.h + * + * Declaration of the Housekeeping Data Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV3_HK_DR_H +#define CRIA_SERV3_HK_DR_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Enable check of the Housekeeping Data Report telemetry packet. + * IsEnabled = (RDL entry corresponding to argument SID is not free) + * @param smDesc the state machine descriptor + * @return the enable check result + */ +CrFwBool_t CrIaServ3HkDrEnableCheck(FwSmDesc_t smDesc); + +/** + * Ready check of the Housekeeping Data Report telemetry packet. + * Execute the procedure of figure CrIaReadyChk3s25 (NOTE: is manually implemented) + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrIaServ3HkDrReadyCheck(FwSmDesc_t smDesc); + +/** + * Update action of the Housekeeping Data Report telemetry packet. + * Load the values of the data pool items associated to the RDL entry corresponding to the report's SID + * @param smDesc the state machine descriptor + */ +void CrIaServ3HkDrUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV3_HK_DR_H */ + diff --git a/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5DisEvtRepGen.c b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5DisEvtRepGen.c new file mode 100644 index 0000000000000000000000000000000000000000..3ca8c95827675b95e1916849bfa07b12c22287be --- /dev/null +++ b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5DisEvtRepGen.c @@ -0,0 +1,149 @@ +/** + * @file CrIaServ5DisEvtRepGen.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Disable Event Report Generation in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ5DisEvtRepGen.h" + +#include "../../../IfswDebug.h" + +#include "CrIaIasw.h" +#include "CrFwCmpData.h" +#include "IfswUtilities.h" +#include "Services/General/CrIaConstants.h" +#include <CrIaInCmp.h> + +#include <Services/General/CrIaParamGetter.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h> /* for EventIndex() */ + + +CrFwBool_t CrIaServ5DisEvtRepGenValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* cmpSpecificData; + CrFwPckt_t pckt; + unsigned short evtId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* Event identifier must be legal */ + + /* Get event identifier */ + CrIaServ5DisEvtRepGenParamGetEvtId(&evtId, pckt); + DEBUGP("CrIaServ5DisEvtRepGenValidityCheck: evtId = %d\n", evtId); + + /* Check event identifier */ + if (EventIndex (evtId) != 0) + { + SendTcAccRepSucc(pckt); + + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_EID); + + return 0; +} + +void CrIaServ5DisEvtRepGenStartAction(FwSmDesc_t smDesc) +{ + unsigned char evtRepEnbldStatus; + unsigned short evtId; + + CrFwInCmdData_t* inSpecificData; + CrFwCmpData_t* cmpData; + CrFwPckt_t pckt; + + + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff the argument event identifier is enabled */ + + /* Get event identifier */ + CrIaServ5DisEvtRepGenParamGetEvtId(&evtId, pckt); + DEBUGP("CrIaServ5DisEvtRepGenStartAction: evtId = %d\n", evtId); + + /* Get status in data pool */ + CrIaCopyArrayItem(EVTENABLEDLIST_ID, &evtRepEnbldStatus, EventIndex(evtId)); + + /* Check if the argument event identifier is disabled */ + if (evtRepEnbldStatus != 0) + { + SendTcStartRepSucc(pckt); + + cmpData->outcome = 1; + + return; + } + + SendTcStartRepFail(pckt, ACK_EID_DIS, 10, (unsigned short)evtId); /* 10, because the evtId is in position 10 */ + + return; +} + +void CrIaServ5DisEvtRepGenProgressAction(FwSmDesc_t smDesc) +{ + unsigned char evtRepEnbldStatus; + unsigned short evtId; + + CrFwInCmdData_t* inSpecificData; + CrFwCmpData_t* cmpData; + CrFwPckt_t pckt; + + + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the enable status of the argument event identifier to 'disabled'; + set the action outcome to 'completed' */ + + /* Get event identifier */ + CrIaServ5EnbEvtRepGenParamGetEvtId(&evtId, pckt); + DEBUGP("CrIaServ5EnbEvtRepGenProgressAction: evtId = %d\n", evtId); + + /* Set status in data pool */ + evtRepEnbldStatus = 0; + CrIaPasteArrayItem(EVTENABLEDLIST_ID, &evtRepEnbldStatus, EventIndex(evtId)); + + SendTcTermRepSucc(pckt); + + cmpData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5DisEvtRepGen.h b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5DisEvtRepGen.h new file mode 100644 index 0000000000000000000000000000000000000000..03a489ea5ae434942db30a70c8b44c8d53d55c18 --- /dev/null +++ b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5DisEvtRepGen.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ5DisEvtRepGen.h + * + * Declaration of the Disable Event Report Generation in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV5_DIS_EVT_REP_GEN_H +#define CRIA_SERV5_DIS_EVT_REP_GEN_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Disable Event Report Generation in-coming command packet. + * Event identifier must be legal + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ5DisEvtRepGenValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Disable Event Report Generation in-coming command packet. + * Set the action outcome to 'success' iff the argument event identifier is enabled + * @param smDesc the state machine descriptor + */ +void CrIaServ5DisEvtRepGenStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Disable Event Report Generation in-coming command packet. + * Set the enable status of the argument event identifier to 'disabled'; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ5DisEvtRepGenProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV5_DIS_EVT_REP_GEN_H */ + diff --git a/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5EnbEvtRepGen.c b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5EnbEvtRepGen.c new file mode 100644 index 0000000000000000000000000000000000000000..bf425ebb3264167a4a339905d70512ee9f169d51 --- /dev/null +++ b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5EnbEvtRepGen.c @@ -0,0 +1,149 @@ +/** + * @file CrIaServ5EnbEvtRepGen.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Enable Event Report Generation in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ5EnbEvtRepGen.h" + +#include "../../../IfswDebug.h" + +#include "CrIaIasw.h" +#include "CrFwCmpData.h" +#include "IfswUtilities.h" +#include "Services/General/CrIaConstants.h" +#include <CrIaInCmp.h> + +#include <Services/General/CrIaParamGetter.h> +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h> /* for EventIndex() */ + + +CrFwBool_t CrIaServ5EnbEvtRepGenValidityCheck(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* cmpData; + CrFwInCmdData_t* cmpSpecificData; + CrFwPckt_t pckt; + unsigned short evtId; + + /* Get in packet */ + cmpData = (CrFwCmpData_t*)FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t*)(cmpData->cmpSpecificData); + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* Event identifier must be legal */ + + /* Get event identifier */ + CrIaServ5EnbEvtRepGenParamGetEvtId(&evtId, pckt); + DEBUGP("CrIaServ5EnbEvtRepGenValidityCheck: evtId = %d\n", evtId); + + /* Check event identifier */ + if (EventIndex (evtId) != 0) + { + SendTcAccRepSucc(pckt); + + return 1; + } + + SendTcAccRepFail(pckt, ACK_ILL_EID); + + return 0; +} + +void CrIaServ5EnbEvtRepGenStartAction(FwSmDesc_t smDesc) +{ + unsigned char evtRepEnbldStatus; + unsigned short evtId; + + CrFwInCmdData_t* inSpecificData; + CrFwPckt_t pckt; + CrFwCmpData_t* cmpData; + + + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the action outcome to 'success' iff the argument event identifier is disabled */ + + /* Get event identifier */ + CrIaServ5EnbEvtRepGenParamGetEvtId(&evtId, pckt); + DEBUGP("CrIaServ5EnbEvtRepGenStartAction: evtId = %d\n", evtId); + + /* Get status in data pool */ + CrIaCopyArrayItem(EVTENABLEDLIST_ID, &evtRepEnbldStatus, EventIndex(evtId)); + + /* Check if the argument event identifier is disabled */ + if (evtRepEnbldStatus == 0) + { + SendTcStartRepSucc(pckt); + + cmpData->outcome = 1; + + return; + } + + SendTcStartRepFail(pckt, ACK_EID_ENB, 10, (unsigned short)evtId); /* 10, because the evtId is in position 10 */ + + return; +} + +void CrIaServ5EnbEvtRepGenProgressAction(FwSmDesc_t smDesc) +{ + unsigned char evtRepEnbldStatus; + unsigned short evtId; + + CrFwInCmdData_t* inSpecificData; + CrFwCmpData_t* cmpData; + CrFwPckt_t pckt; + + + cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + inSpecificData = (CrFwInCmdData_t*)cmpData->cmpSpecificData; + pckt = inSpecificData->pckt; + + cmpData->outcome = 0; + + /* Set the enable status of the argument event identifier to 'enabled'; + set the action outcome to 'completed'. */ + + /* Get event identifier */ + CrIaServ5EnbEvtRepGenParamGetEvtId(&evtId, pckt); + DEBUGP("CrIaServ5EnbEvtRepGenProgressAction: evtId = %d\n", evtId); + + /* Set status in data pool */ + CrIaCopy(EVTFILTERDEF_ID, &evtRepEnbldStatus); + CrIaPasteArrayItem(EVTENABLEDLIST_ID, &evtRepEnbldStatus, EventIndex(evtId)); + + SendTcTermRepSucc(pckt); + + cmpData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5EnbEvtRepGen.h b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5EnbEvtRepGen.h new file mode 100644 index 0000000000000000000000000000000000000000..e17eb5a41f3ad8c378850d73f862d0454039161e --- /dev/null +++ b/CrIa/src/Services/CrIaServ5EventReportingService/InCmd/CrIaServ5EnbEvtRepGen.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ5EnbEvtRepGen.h + * + * Declaration of the Enable Event Report Generation in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV5_ENB_EVT_REP_GEN_H +#define CRIA_SERV5_ENB_EVT_REP_GEN_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Enable Event Report Generation in-coming command packet. + * Event identifier must be legal + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ5EnbEvtRepGenValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Enable Event Report Generation in-coming command packet. + * Set the action outcome to 'success' iff the argument event identifier is disabled + * @param smDesc the state machine descriptor + */ +void CrIaServ5EnbEvtRepGenStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Enable Event Report Generation in-coming command packet. + * Set the enable status of the argument event identifier to 'enabled'; set the action outcome to 'completed'. + * @param smDesc the state machine descriptor + */ +void CrIaServ5EnbEvtRepGenProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV5_ENB_EVT_REP_GEN_H */ + diff --git a/CrIa/src/Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.c b/CrIa/src/Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.c new file mode 100644 index 0000000000000000000000000000000000000000..92f7747437f17ff71fb3d0621b3885020a8fc5fe --- /dev/null +++ b/CrIa/src/Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.c @@ -0,0 +1,236 @@ +/** + * @file CrIaServ5Event.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the event telemetry packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ5Event.h" + +#include "CrIaIasw.h" +#include "CrFwCmpData.h" +#include "CrIaPckt.h" + +#include <Services/General/CrIaConstants.h> + +#include <FwProfile/FwSmConfig.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +/* we use an unsigned char as datatype, so we need to saturate at 255 */ +#define MAX_EVENT_COUNT 0xff + +/* array to count the events raised. it should be reset using ResetEventCounts() periodically */ +unsigned char eventCounts[N_EVT_ID]; + + +/* get the array index where the event has its flag in evtRepEnbld */ +unsigned char EventIndex (unsigned short eventId) +{ + switch (eventId) + { + /* + NOTE: the following errors report that the outgoing communication is broken, + thus it makes no sense to put them in the ougoing queue. They will run into the + default clause instead and do nothing here. They still make their way into + the error log. + + case ERR_OUTSTREAM_PQ_FULL: 102, return 2; + case ERR_POCL_FULL: 105, return 4; + case ERR_OUTCMP_NO_MORE_PCKT: 108, return 5; + */ + + case CRIA_SERV5_EVT_INV_DEST: /* 101 */ + return 1; + case CRIA_SERV5_EVT_SEQ_CNT_ERR: /* 200 */ + return 2; + case CRIA_SERV5_EVT_INREP_CR_FAIL: /* 201 */ + return 3; + case CRIA_SERV5_EVT_PCRL2_FULL: /* 202 */ + return 4; + case CRIA_SERV5_EVT_FD_FAILED: /* 203 */ + return 5; + case CRIA_SERV5_EVT_RP_STARTED: /* 204 */ + return 6; + case CRIA_SERV5_EVT_SEM_TR: /* 205 */ + return 7; + case CRIA_SERV5_EVT_IASW_TR: /* 206 */ + return 8; + case CRIA_SERV5_EVT_SDSC_ILL: /* 208 */ + return 9; + case CRIA_SERV5_EVT_SDSC_OOS: /* 209 */ + return 10; + case CRIA_SERV5_EVT_CLCT_SIZE: /* 210 */ + return 11; + case CRIA_SERV5_EVT_SIB_SIZE: /* 211 */ + return 12; + case CRIA_SERV5_EVT_FBF_LOAD_RISK: /* 212 */ + return 13; + case CRIA_SERV5_EVT_FBF_SAVE_DENIED: /* 213 */ + return 14; + case CRIA_SERV5_EVT_FBF_SAVE_ABRT: /* 214 */ + return 15; + case CRIA_SERV5_EVT_SDB_CNF_FAIL: /* 215 */ + return 16; + case CRIA_SERV5_EVT_CMPR_SIZE: /* 216 */ + return 17; + case CRIA_SERV5_EVT_SEMOP_TR: /* 217 */ + return 18; + case CRIA_SERV5_EVT_SC_PR_STRT: /* 218 */ + return 19; + case CRIA_SERV5_EVT_SC_PR_END: /* 219 */ + return 20; + case CRIA_SERV5_EVT_INSTRM_PQF: /* 220 */ + return 21; + case CRIA_SERV5_EVT_OCMP_INVD: /* 221 */ + return 22; + case CRIA_SERV5_EVT_OCMP_ILLGR: /* 222 */ + return 23; + case CRIA_SERV5_EVT_IN_ILLGR: /* 223 */ + return 24; + case CRIA_SERV5_EVT_INV_CENT: /* 230 */ + return 25; + case CRIA_SERV5_EVT_INIT_SUCC: /* 301 */ + return 27; + case CRIA_SERV5_EVT_INIT_FAIL: /* 302 */ + return 28; + case CRIA_SERV5_EVT_THRD_OR: /* 303 */ + return 29; + case CRIA_SERV5_EVT_NOTIF_ERR: /* 304 */ + return 30; + case CRIA_SERV5_EVT_1553_ERR_L: /* 311 */ + return 32; + case CRIA_SERV5_EVT_1553_ERR_M: /* 312 */ + return 33; + case CRIA_SERV5_EVT_1553_ERR_H: /* 313 */ + return 34; + case CRIA_SERV5_EVT_SPW_ERR_L: /* 315 */ + return 35; + case CRIA_SERV5_EVT_SPW_ERR_M: /* 316 */ + return 36; + case CRIA_SERV5_EVT_SPW_ERR_H: /* 317 */ + return 37; + case CRIA_SERV5_EVT_FL_EL_ERR: /* 320 */ + return 38; + case CRIA_SERV5_EVT_FL_FBF_ERR: /* 325 */ + return 39; + case CRIA_SERV5_EVT_FL_FBF_BB: /* 326 */ + return 40; + case CRIA_SERV5_EVT_SBIT_ERR: /* 330 */ + return 41; + case CRIA_SERV5_EVT_DBIT_ERR: /* 335 */ + return 42; + case CRIA_SERV5_EVT_SYNC_LOSS: /* 350 */ + return 43; + case CRIA_SERV5_EVT_SDP_NOMEM: /* 1001 */ + return 44; + case CRIA_SERV5_EVT_SEM_ILL_ST: /* 1400 */ + return 45; + case CRIA_SERV5_EVT_PROCBUF_INSUF: /* 1501 */ + return 46; + case CRIA_SERV5_EVT_XIB_FULL: /* 1503 */ + return 47; + case CRIA_SERV5_EVT_IMG_INSUF: /* 1504 */ + return 48; + case CRIA_SERV5_EVT_ACQ_FAIL: /* 1450 */ + return 49; + + /* NOTE: 59 is maximum... */ + + default: + DEBUGP("ERR: Event %d has no place in the evtRepEnbld list, using 0!\n", eventId); + break; + } + + return 0; /* all unknown events have index 0 */ +} + + +void ResetEventCounts (void) +{ + int i; + + for (i=0; i<N_EVT_ID; i++) + eventCounts[i] = 0; + + return; +} + + +/* increment event counter in the eventCounts array with saturation at 255 and report the number of counts */ +/* NOTE: in order to only query the event counts without incrementing use: eventCounts[EventIndex(EVENT)] */ +unsigned char CountEvent(unsigned short eventId) +{ + int idx; + idx = EventIndex (eventId); + + if (eventCounts[idx] != MAX_EVENT_COUNT) + eventCounts[idx]++; + + return eventCounts[idx]; +} + + +CrFwBool_t CrIaServ5EventEnableCheck(FwSmDesc_t smDesc) +{ + /* Implement the check logic here: */ + DEBUGP("CrIaServ5EventEnableCheck: Check if Event Report Generation is enabled or disabled.\n"); + + (void) smDesc; + + /* v09+ event filter "the good one" is implemented in CrIaEvtRep. + This also covers if an event is enabled or not. + No need to double check here! */ + + return 1; +} + + +CrFwBool_t CrIaServ5EventReadyCheck(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + + /* Implement the check logic here: */ + DEBUGP("CrIaServ5EventReadyCheck: isReady = TRUE\n"); + + return 1; +} + + +CrFwBool_t CrIaServ5EventRepeatCheck(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + + /* Implement the check logic here: */ + DEBUGP("CrIaServ5EventRepeatCheck: isRepeat = FALSE\n"); + + return 0; +} + +void CrIaServ5EventUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + + /* Implement the action logic here: */ + DEBUGP("CrIaServ5EventUpdateAction: load the value of the report parameters; for (5,3) & (5,4) make an entry in the Error Log.\n"); + + /* NOTE: empty, because all functionality is carried out in CrIaIasw.c */ + + return; +} + diff --git a/CrIa/src/Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h b/CrIa/src/Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h new file mode 100644 index 0000000000000000000000000000000000000000..493415b4fa46f566b9fd16288d9df49b2bda6272 --- /dev/null +++ b/CrIa/src/Services/CrIaServ5EventReportingService/OutRep/CrIaServ5Event.h @@ -0,0 +1,51 @@ +/** + * @file CrIaServ5Event.h + * + * Declaration of the event telemetry packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV5_EVENT_H +#define CRIA_SERV5_EVENT_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + + +unsigned char EventIndex (unsigned short eventId); + +void ResetEventCounts (void); + +unsigned char CountEvent(unsigned short eventId); + +/** + * Enable check of the event telemetry packet. + * @param smDesc the state machine descriptor + * @return the enable check result + */ +CrFwBool_t CrIaServ5EventEnableCheck(FwSmDesc_t smDesc); + +/** + * Ready check of the event telemetry packet. + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrIaServ5EventReadyCheck(FwSmDesc_t smDesc); + +/** + * Repeat check of the event telemetry packet. + * @param smDesc the state machine descriptor + * @return the repeat check result + */ +CrFwBool_t CrIaServ5EventRepeatCheck(FwSmDesc_t smDesc); + +/** + * Update action of the event telemetry packet. + * @param smDesc the state machine descriptor + */ +void CrIaServ5EventUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV5_EVENT_H */ + diff --git a/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6DumpMem.c b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6DumpMem.c new file mode 100644 index 0000000000000000000000000000000000000000..69cadcf596a6b258aca0d9664bed1f8c499bf6df --- /dev/null +++ b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6DumpMem.c @@ -0,0 +1,185 @@ +/** + * @file CrIaServ6DumpMem.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Dump Memory using Absolute Addresses in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ6DumpMem.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <stddef.h> +#include <Pckt/CrFwPckt.h> +#include <OutFactory/CrFwOutFactory.h> +#include <OutCmp/CrFwOutCmp.h> +#include <OutLoader/CrFwOutLoader.h> + +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaParamSetter.h> + +#include <CrIaDataPoolId.h> /* for MAX_DUMP_SIZE */ +#include <CrIaDataPool.h> /* for MAX_DUMP_SIZE */ + +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> + +#include <byteorder.h> +#include <stdio.h> + + + +CrFwBool_t CrIaServ6DumpMemValidityCheck(FwPrDesc_t prDesc) +{ + unsigned short dpu_mem_id; + + unsigned int mem_start_addr; + unsigned int mem_stop_addr; + unsigned int dump_len; + unsigned int addr_id; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* Memory block identifier must be legal; start address and length of dump must be legal; length and address must be double-word aligned */ + + CrIaServ6DumpMemParamGetDpuMemoryId(&dpu_mem_id, pckt); + CrIaServ6DumpMemParamGetStartAddress(&mem_start_addr, pckt); + CrIaServ6DumpMemParamGetBlockLength(&dump_len, pckt); + + mem_stop_addr = mem_start_addr + dump_len; + + /* check 4B alignment of provided address and length */ + /* NOTE: the spec wants 8B alignment, but actually this is not necessary. We can go for 4B (better) alignment */ + if (mem_start_addr & 0x3) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_SRC); + return 0; + } + if (dump_len & 0x3) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_LEN); + return 0; + } + if (dump_len > MAX_DUMP_SIZE) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_LEN); + return 0; + } + + /* check memory block identifier and whether it fits with the given addresses */ + addr_id = verifyAddress (mem_start_addr); + + /* check if the ram id fits with the given start address */ + if (cvtAddrIdToRamId(addr_id) != dpu_mem_id) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_ID); + return 0; + } + + /* check if the end address is within the same segment */ + if (addr_id != verifyAddress (mem_stop_addr)) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_LEN); + return 0; + } + + SendTcAccRepSucc(pckt); + return 1; +} + + +void CrIaServ6DumpMemStartAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' */ + + SendTcStartRepSucc(pckt); + cmpData->outcome = 1; + return; +} + + +void CrIaServ6DumpMemProgressAction(FwSmDesc_t smDesc) +{ + unsigned short dpu_mem_id; + unsigned int mem_start_addr; + unsigned int dump_len; + + FwSmDesc_t rep; + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + CrFwDestSrc_t source; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + source = CrFwPcktGetSrc (pckt); + + /* Generate a (6,6) report configured to collect the content of the memory area specified in this command; set the action outcome to 'completed' */ + + CrIaServ6DumpMemParamGetDpuMemoryId(&dpu_mem_id, pckt); + CrIaServ6DumpMemParamGetStartAddress(&mem_start_addr, pckt); + CrIaServ6DumpMemParamGetBlockLength(&dump_len, pckt); + + /* the size is dump_len + 16 (header) + 10 (service header) + 2 (crc) */ + rep = CrFwOutFactoryMakeOutCmp (CRIA_SERV6, CRIA_SERV6_MEM_DUMP, 0, dump_len + 28); + if (rep == NULL) + { + /* handled by Resource FdCheck */ + cmpData->outcome = 0; + return; + } + + CrFwOutCmpSetDest (rep, source); + + CrIaServ6MemDumpParamSetDpuMemoryId (rep, dpu_mem_id); + CrIaServ6MemDumpParamSetStartAddress (rep, mem_start_addr); + CrIaServ6MemDumpParamSetBlockLength (rep, dump_len); + + /* NOTE: the actual copy of the data into the packet done in the outrep update action */ + + CrFwOutLoaderLoad (rep); + + SendTcTermRepSucc(pckt); + cmpData->outcome = 1; + + /* Mantis 2066 */ + CrIaPaste(LASTDUMPADDR_ID, &mem_start_addr); + + return; +} diff --git a/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6DumpMem.h b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6DumpMem.h new file mode 100644 index 0000000000000000000000000000000000000000..a0c2b967a3f003b5efee2418e733f48f1211ed12 --- /dev/null +++ b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6DumpMem.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ6DumpMem.h + * + * Declaration of the Dump Memory using Absolute Addresses in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV6_DUMP_MEM_H +#define CRIA_SERV6_DUMP_MEM_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Dump Memory using Absolute Addresses in-coming command packet. + * Memory block identifier must be legal; start address and length of dump must be legal; length and address must be double-word aligned + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ6DumpMemValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Dump Memory using Absolute Addresses in-coming command packet. + * Set the action outcome to 'success' + * @param smDesc the state machine descriptor + */ +void CrIaServ6DumpMemStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Dump Memory using Absolute Addresses in-coming command packet. + * Generate a (6,6) report configured to collect the content of the memory area specified in this command; set the action outcome to 'completed' + * @param smDesc the state machine descriptor + */ +void CrIaServ6DumpMemProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV6_DUMP_MEM_H */ + diff --git a/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6LoadMem.c b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6LoadMem.c new file mode 100644 index 0000000000000000000000000000000000000000..f7fe0deceb885a8bfcb2deec46f9fde8d40f7761 --- /dev/null +++ b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6LoadMem.c @@ -0,0 +1,219 @@ +/** + * @file CrIaServ6LoadMem.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Load Memory using Absolute Addresses in-coming command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ6LoadMem.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <Pckt/CrFwPckt.h> +#include <OutFactory/CrFwOutFactory.h> +#include <OutCmp/CrFwOutCmp.h> +#include <OutLoader/CrFwOutLoader.h> + +#include <Services/General/CrIaParamGetter.h> + +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> + +#include <CrIaDataPoolId.h> +#include <CrIaDataPool.h> + +#include <stdio.h> + +#if (__sparc__) +#include <io.h> /* ioread32be(), iowrite32be() */ +#endif + +#define MAX_PATCH_LEN 1002 + + +CrFwBool_t CrIaServ6LoadMemValidityCheck(FwPrDesc_t prDesc) +{ + unsigned short dpu_mem_id; + + unsigned int mem_start_addr; + unsigned int mem_stop_addr; + unsigned int patch_len; + unsigned int pckt_size; + unsigned int copy_size; + unsigned int addr_id; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + pckt_size = CrFwPcktGetLength(pckt); + + /* Verify Checksum of incoming packet */ + if (!CheckCrc(pckt)) + { + SendTcAccRepFail(pckt, ACK_WRONG_CHKSM); + return 0; + } + + /* Memory block identifier must be legal; start address of patch must be legal; length of patch must be consistent with set of patch values provided in patch command; length and address must be double-word aligned */ + + CrIaServ6LoadMemParamGetDpuMemoryId(&dpu_mem_id, pckt); + CrIaServ6LoadMemParamGetStartAddress(&mem_start_addr, pckt); + CrIaServ6LoadMemParamGetBlockLength(&patch_len, pckt); + + mem_stop_addr = mem_start_addr + patch_len; + + /* check 4B alignment of provided address and length */ + if (mem_start_addr & 0x3) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_SRC); + return 0; + } + if (patch_len & 0x3) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_LEN); + return 0; + } + + /* check memory block identifier and whether it fits with the given addresses */ + addr_id = verifyAddress (mem_start_addr); + + /* check if the ram id fits with the given start address */ + if (cvtAddrIdToRamId(addr_id) != dpu_mem_id) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_ID); + return 0; + } + + /* check if the end address is within the same segment */ + if (addr_id != verifyAddress (mem_stop_addr)) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_LEN); + return 0; + } + + /* check if the given length fits with the size of the packet */ + copy_size = pckt_size - OFFSET_PAR_LENGTH_IN_CMD_PCKT - 10 - 2; + if (patch_len != copy_size) + { + SendTcAccRepFail(pckt, ACK_ILL_MEM_LEN); + return 0; + } + + SendTcAccRepSucc(pckt); + return 1; +} + + +void CrIaServ6LoadMemStartAction(FwSmDesc_t smDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Set the action outcome to 'success' */ + + SendTcStartRepSucc(pckt); + cmpData->outcome = 1; + return; +} + + +/** + * @brief Progress action of the Service 3 Housekeeping Data Report + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Copy the data + * - Read back and compare data + * + * @param[in] smDesc state machine descriptor + * @param[out] none + */ +void CrIaServ6LoadMemProgressAction(FwSmDesc_t smDesc) +{ + unsigned int i; + unsigned int len; + + unsigned int mem_start_addr; + unsigned int patch_len; + + unsigned char patch[MAX_PATCH_LEN]; /* NOTE: we should get this away from the stack */ + unsigned int *buf, *mem; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + +#ifdef PC_TARGET + /* on PC we just go back */ + (void) i; + (void) len; + (void) mem_start_addr; + (void) patch_len; + (void) patch; + (void) buf; + (void) mem; + (void) pckt; + SendTcTermRepSucc(pckt); + cmpData->outcome = 1; + return; +#else + CrIaServ6LoadMemParamGetStartAddress(&mem_start_addr, pckt); + CrIaServ6LoadMemParamGetBlockLength(&patch_len, pckt); + CrIaServ6LoadMemParamGetBlockData(patch, patch_len, pckt); + + /* copy the data */ + len = patch_len >> 2; + buf = (unsigned int *)patch; + mem = (unsigned int *) mem_start_addr; + + for (i=0; i<len; i++) + iowrite32be(buf[i], &mem[i]); + + /* Mantis 2066 */ + CrIaPaste(LASTPATCHEDADDR_ID, &mem_start_addr); + + /* read back and compare */ + for (i = 0; i < len; i++) + { + if (ioread32be(&mem[i]) != buf[i]) + { + SendTcTermRepFail(pckt, ACK_MEM_FAIL, 0, (unsigned short)i); /* NOTE: the last parameter contains the failing index */ + cmpData->outcome = 0; + return; + } + } + + SendTcTermRepSucc(pckt); + cmpData->outcome = 1; + return; +#endif +} + diff --git a/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6LoadMem.h b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6LoadMem.h new file mode 100644 index 0000000000000000000000000000000000000000..88dc14b64f17efd9cb43b0eee8a6a93ae23ef895 --- /dev/null +++ b/CrIa/src/Services/CrIaServ6MemoryManagementService/InCmd/CrIaServ6LoadMem.h @@ -0,0 +1,39 @@ +/** + * @file CrIaServ6LoadMem.h + * + * Declaration of the Load Memory using Absolute Addresses in-coming command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV6_LOAD_MEM_H +#define CRIA_SERV6_LOAD_MEM_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Validity check of the Load Memory using Absolute Addresses in-coming command packet. + * Memory block identifier must be legal; start address of patch must be legal; length of patch must be consistent with set of patch values provided in patch command; length and address must be double-word aligned + * @param prDesc the procedure descriptor + * @return the validity check result + */ +CrFwBool_t CrIaServ6LoadMemValidityCheck(FwPrDesc_t prDesc); + +/** + * Start action of the Load Memory using Absolute Addresses in-coming command packet. + * Set the action outcome to 'success' + * @param smDesc the state machine descriptor + */ +void CrIaServ6LoadMemStartAction(FwSmDesc_t smDesc); + +/** + * Progress action of the Load Memory using Absolute Addresses in-coming command packet. + * Execute the behaviour shown in figure ProgressAction6s2 + * @param smDesc the state machine descriptor + */ +void CrIaServ6LoadMemProgressAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV6_LOAD_MEM_H */ + diff --git a/CrIa/src/Services/CrIaServ6MemoryManagementService/OutRep/CrIaServ6MemDump.c b/CrIa/src/Services/CrIaServ6MemoryManagementService/OutRep/CrIaServ6MemDump.c new file mode 100644 index 0000000000000000000000000000000000000000..3fe23d3ab62ffaaf4d154fa73a14c56f41f9a8f3 --- /dev/null +++ b/CrIa/src/Services/CrIaServ6MemoryManagementService/OutRep/CrIaServ6MemDump.c @@ -0,0 +1,91 @@ +/** + * @file CrIaServ6MemDump.c + * @ingroup CrIaServices + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the Memory Dump using Absolute Addresses Report out-going report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaServ6MemDump.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> + +#include <Pckt/CrFwPckt.h> +#include <OutFactory/CrFwOutFactory.h> +#include <OutCmp/CrFwOutCmp.h> +#include <OutLoader/CrFwOutLoader.h> + +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrIaParamSetter.h> + +#include <CrIaDataPool.h> /* for MAX_DUMP_SIZE */ + +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> + + +#include <stdio.h> +#if (__sparc__) +#include <io.h> +#endif + + +void CrIaServ6MemDumpUpdateAction(FwSmDesc_t smDesc) +{ + unsigned int i; + unsigned int len; + + unsigned int mem_start_addr; + unsigned int dump_len; + + unsigned char dump[MAX_DUMP_SIZE]; /* NOTE: we should get this away from the stack */ + unsigned int *buf, *mem; + + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInCmdData_t *cmpSpecificData; + + cmpData = (CrFwCmpData_t *) FwSmGetData(smDesc); + cmpSpecificData = (CrFwInCmdData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* Use IBSW operation to collect the content of the area to be dumped and load it in the report */ + + CrIaServ6DumpRepMemParamGetStartAddress (&mem_start_addr, pckt); + CrIaServ6DumpRepMemParamGetBlockLength (&dump_len, pckt); + + /* make a local copy of the data */ + buf = (unsigned int *) dump; + mem = (unsigned int *) mem_start_addr; + + len = dump_len >> 2; + +#if (__sparc__) + for (i = 0; i < len; i++) + buf[i] = ioread32be(&mem[i]); +#else + /* on PC we only put a ramp in the packet */ + (void) mem; + for (i = 0; i < len; i++) + buf[i] = i; +#endif + + /* make the actual copy to the packet */ + CrIaServ6MemDumpParamSetBlockData (smDesc, dump, (unsigned short) dump_len); + + return; +} + diff --git a/CrIa/src/Services/CrIaServ6MemoryManagementService/OutRep/CrIaServ6MemDump.h b/CrIa/src/Services/CrIaServ6MemoryManagementService/OutRep/CrIaServ6MemDump.h new file mode 100644 index 0000000000000000000000000000000000000000..b316edd59030d57b367c65ed1575208fbe585c99 --- /dev/null +++ b/CrIa/src/Services/CrIaServ6MemoryManagementService/OutRep/CrIaServ6MemDump.h @@ -0,0 +1,24 @@ +/** + * @file CrIaServ6MemDump.h + * + * Declaration of the Memory Dump using Absolute Addresses Report out-going report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_SERV6_MEM_DUMP_H +#define CRIA_SERV6_MEM_DUMP_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the Memory Dump using Absolute Addresses Report telemetry packet. + * Use IBSW operation to collect the content of the area to be dumped and load it in the report + * @param smDesc the state machine descriptor + */ +void CrIaServ6MemDumpUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRIA_SERV6_MEM_DUMP_H */ + diff --git a/CrIa/src/Services/CrSemServ1CommandVerificationService/InRep/CrSemServ1ComVerif.c b/CrIa/src/Services/CrSemServ1CommandVerificationService/InRep/CrSemServ1ComVerif.c new file mode 100644 index 0000000000000000000000000000000000000000..1f9457650ffbe4b2b4c5cb61fbfaf1f41c2d27a8 --- /dev/null +++ b/CrIa/src/Services/CrSemServ1CommandVerificationService/InRep/CrSemServ1ComVerif.c @@ -0,0 +1,137 @@ +/** + * @file CrSemServ1ComVerif.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Command Verification in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ1ComVerif.h" + +#include "../../../IfswDebug.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaParamGetter.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +/* send function in the 1,1 and 1,3 forward */ +#include <OutStream/CrFwOutStream.h> + + +/** + * @brief Update action of the Service 1 SEM DAT Command Verification in-coming report + * + * Following steps are executed: + * if forwarding of SEM command verification is enabled: + * - Forward command verification to Ground + * + * @param[in] prDesc procedure descriptor + * @param[out] none + */ +void CrSemServ1ComVerifUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char subType, semS11flag, semS12flag, semS17flag, semS18flag; + + CRFW_UNUSED(prDesc); /* remove if smDesc is used in this function */ + + /* The Update Action of incoming service 1 reports shall run the SEM Command Verification Update Procedure. */ + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Get InRep SubType */ + subType = CrFwPcktGetServSubType(inPckt); + DEBUGP("Sub Type: %d\n", subType); + + if (subType == 1) + { + /* Check, if SEM_SERV1_1_FORWARD is enabled */ + CrIaCopy(SEM_SERV1_1_FORWARD_ID, &semS11flag); + DEBUGP("semS11flag: %d\n", semS11flag); + if (semS11flag == 1) + { + /* SendSemForwardTmService1(inPckt, subType); */ + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + } + + if (subType == 2) + { + /* Check, if SEM_SERV1_2_FORWARD is enabled */ + CrIaCopy(SEM_SERV1_2_FORWARD_ID, &semS12flag); + DEBUGP("semS12flag: %d\n", semS12flag); + if (semS12flag == 1) + { + /* SendSemForwardTmService1(inPckt, subType); */ + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + } + + if (subType == 7) + { + /* Check, if SEM_SERV1_7_FORWARD is enabled */ + CrIaCopy(SEM_SERV1_7_FORWARD_ID, &semS17flag); + DEBUGP("semS17flag: %d\n", semS17flag); + if (semS17flag == 1) + { + /* SendSemForwardTmService1(inPckt, subType); */ + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + } + + if (subType == 8) + { + /* Check, if SEM_SERV1_8_FORWARD is enabled */ + CrIaCopy(SEM_SERV1_8_FORWARD_ID, &semS18flag); + DEBUGP("semS18flag: %d\n", semS18flag); + if (semS18flag == 1) + { + /* SendSemForwardTmService1(inPckt, subType); */ + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + } + + return; +} + diff --git a/CrIa/src/Services/CrSemServ1CommandVerificationService/InRep/CrSemServ1ComVerif.h b/CrIa/src/Services/CrSemServ1CommandVerificationService/InRep/CrSemServ1ComVerif.h new file mode 100644 index 0000000000000000000000000000000000000000..9dfd48da2da884cd58f20f5189cf1737f2411577 --- /dev/null +++ b/CrIa/src/Services/CrSemServ1CommandVerificationService/InRep/CrSemServ1ComVerif.h @@ -0,0 +1,32 @@ +/** + * @file CrSemServ1ComVerif.h + * + * Declaration of the Command Verification in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV1_COM_VERIF_H +#define CRSEM_SERV3_COM_VERIF_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + +/** + * Validity check of the DAT HK in-coming report packet. + * Compute the CRC for the report and returns true if the CRC is correct and false otherwise. + * @param smDesc the state machine descriptor + * @return the validity check result + */ +CrFwBool_t CrSemServ1ComVerifValidityCheck(FwPrDesc_t prDesc); + +/** + * Update action of the DAT HK in-coming report packet. + * The Update Action of incoming service 3 reports shall run the SEM HK Update Procedure. + * @param smDesc the state machine descriptor + */ +void CrSemServ1ComVerifUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV1_COM_VERIF_H */ + diff --git a/CrIa/src/Services/CrSemServ21ScienceDataService/InRep/CrSemServ21DatCcdWindow.c b/CrIa/src/Services/CrSemServ21ScienceDataService/InRep/CrSemServ21DatCcdWindow.c new file mode 100644 index 0000000000000000000000000000000000000000..cbd2bf1aa46698607391dea125901aca24a034ad --- /dev/null +++ b/CrIa/src/Services/CrSemServ21ScienceDataService/InRep/CrSemServ21DatCcdWindow.c @@ -0,0 +1,62 @@ +/** + * @file CrSemServ21DatCcdWindow.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT CCD Window in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ21DatCcdWindow.h" + +#include <CrIaInCmp.h> + +#include <IfswDebug.h> + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <CrFwCmpData.h> + +#include <FwProfile/FwPrCore.h> /* for FwPrStart */ + +#include <CrIaIasw.h> /* for prDescSciData */ + + +void CrSemServ21DatCcdWindowUpdateAction(FwPrDesc_t prDesc) +{ + CrFwPckt_t pckt; + CrFwCmpData_t *cmpData; + CrFwInRepData_t *cmpSpecificData; + + /* The Update Action of the science data reports (21,3) shall run the Science Data Update Procedure. */ + + cmpData = (CrFwCmpData_t *) FwPrGetData(prDesc); + cmpSpecificData = (CrFwInRepData_t *) cmpData->cmpSpecificData; + pckt = cmpSpecificData->pckt; + + /* pass the pointer to the packet on to the science data update procedure */ + /* FwPrSetData(prDescSciDataUpd, pckt); */ + S21SemPacket = pckt; + + /* NOTE: could use Run instead of Start + Execute */ + FwPrStart(prDescSciDataUpd); + + FwPrExecute(prDescSciDataUpd); + + /* the Science Data Update procedure according to RS-001 Fig. 9.3. */ + /* It is implemented in CrIaSciDataUpdFunc */ + + cmpData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrSemServ21ScienceDataService/InRep/CrSemServ21DatCcdWindow.h b/CrIa/src/Services/CrSemServ21ScienceDataService/InRep/CrSemServ21DatCcdWindow.h new file mode 100644 index 0000000000000000000000000000000000000000..6583ab987725c30bfbf76d50114f16b91cdebd67 --- /dev/null +++ b/CrIa/src/Services/CrSemServ21ScienceDataService/InRep/CrSemServ21DatCcdWindow.h @@ -0,0 +1,34 @@ +/** + * @file CrSemServ21DatCcdWindow.h + * + * Declaration of the DAT CCD Window in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV21_DAT_CCD_WINDOW_H +#define CRSEM_SERV21_DAT_CCD_WINDOW_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + + +/** + * Validity check of the DAT CCD Window in-coming report packet. + * Compute the CRC for the report and returns true if the CRC is correct and false otherwise. + * @param smDesc the state machine descriptor + * @return the validity check result + */ +CrFwBool_t CrSemServ21DatCcdWindowValidityCheck(FwPrDesc_t prDesc); + + +/** + * Update action of the DAT CCD Window in-coming report packet. + * The Update Action of the science data reports (21,3) shall run the Science Data Update Procedure. + * @param prDesc the procedure descriptor + */ +void CrSemServ21DatCcdWindowUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV21_DAT_CCD_WINDOW_H */ + diff --git a/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataDisable.c b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataDisable.c new file mode 100644 index 0000000000000000000000000000000000000000..31e8e8ced37df37723d054a77e03eb5eb7d159c2 --- /dev/null +++ b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataDisable.c @@ -0,0 +1,25 @@ +/** + * @file CrSemServ21CmdCcdDataDisable.c + * + * Implementation of the CMD CCD Data Disable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#include "CrSemServ21CmdCcdDataDisable.h" + +#include "IfswDebug.h" + + +void CrSemServ21CmdCcdDataDisableUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + /* Collect target mode from data pool */ + + DEBUGP("CrSemServ21CmdCcdDataDisableUpdateAction() called.\n"); + + return; +} + diff --git a/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataDisable.h b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataDisable.h new file mode 100644 index 0000000000000000000000000000000000000000..9eefbc3e6033f17ae7ea289d24adef09d0c8bbcb --- /dev/null +++ b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataDisable.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ21CmdCcdDataDisable.h + * + * Declaration of the CMD CCD Data Disable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV21_CMD_CCD_DATA_DISABLE_H +#define CRSEM_SERV21_CMD_CCD_DATA_DISABLE_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the CMD CCD Data Disable telemetry packet. + * Collect target mode from data pool + * @param smDesc the state machine descriptor + */ +void CrSemServ21CmdCcdDataDisableUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV21_CMD_CCD_DATA_DISABLE_H */ + diff --git a/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataEnable.c b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataEnable.c new file mode 100644 index 0000000000000000000000000000000000000000..74e00b379b921cba6336da239faa9464b0aa238d --- /dev/null +++ b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataEnable.c @@ -0,0 +1,20 @@ +/** + * @file CrSemServ21CmdCcdDataEnable.c + * + * Implementation of the CMD CCD Data Enable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#include "CrSemServ21CmdCcdDataEnable.h" + + +void CrSemServ21CmdCcdDataEnableUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + /* Collect target mode from data pool */ + return; +} + diff --git a/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataEnable.h b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataEnable.h new file mode 100644 index 0000000000000000000000000000000000000000..0f17cdd68106ea113c02d14faf4f3ada42f3e4ca --- /dev/null +++ b/CrIa/src/Services/CrSemServ21ScienceDataService/OutCmd/CrSemServ21CmdCcdDataEnable.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ21CmdCcdDataEnable.h + * + * Declaration of the CMD CCD Data Enable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV21_CMD_CCD_DATA_ENABLE_H +#define CRSEM_SERV21_CMD_CCD_DATA_ENABLE_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the CMD CCD Data Enable telemetry packet. + * Collect target mode from data pool + * @param smDesc the state machine descriptor + */ +void CrSemServ21CmdCcdDataEnableUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV21_CMD_CCD_DATA_ENABLE_H */ + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatFunctParam.c b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatFunctParam.c new file mode 100644 index 0000000000000000000000000000000000000000..b387d498bee75a3ea1655570c9040f57a068e53a --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatFunctParam.c @@ -0,0 +1,63 @@ +/** + * @file CrSemServ220DatFunctParam.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Functional Parameter in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ220DatFunctParam.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <CrFwCmpData.h> + +/* send function in the 220,12 forward */ +#include <OutStream/CrFwOutStream.h> + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <IfswDebug.h> + + +void CrSemServ220DatFunctParamUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char semS22012flag; + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Check, if SEM_SERV220_12_FORWARD is enabled */ + CrIaCopy(SEM_SERV220_12_FORWARD_ID, &semS22012flag); + DEBUGP("semS22012flag: %d\n", semS22012flag); + if (semS22012flag == 1) + { + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + inData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatFunctParam.h b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatFunctParam.h new file mode 100644 index 0000000000000000000000000000000000000000..7f9697bcffb3d6df36eda5dd6a4cb8c193941a26 --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatFunctParam.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ220DatFunctParam.h + * + * Declaration of the DAT Functional Parameter in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV220_DAT_FUNCT_PARAM_H +#define CRSEM_SERV220_DAT_FUNCT_PARAM_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + + +/** + * Update action of the DAT Functional Parameter in-coming report packet. + * @param prDesc the procedure descriptor + */ +void CrSemServ220DatFunctParamUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV220_DAT_FUNCT_PARAM_H */ + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatOperParam.c b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatOperParam.c new file mode 100644 index 0000000000000000000000000000000000000000..d6d7fc27339b436320ff435b952379a03239771f --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatOperParam.c @@ -0,0 +1,63 @@ +/** + * @file CrSemServ220DatOperParam.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Operation Parameter in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ220DatOperParam.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <CrFwCmpData.h> + +/* send function in the 220,6 forward */ +#include <OutStream/CrFwOutStream.h> + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <IfswDebug.h> + + +void CrSemServ220DatOperParamUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char semS2206flag; + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Check, if SEM_SERV220_6_FORWARD is enabled */ + CrIaCopy(SEM_SERV220_6_FORWARD_ID, &semS2206flag); + DEBUGP("semS2206flag: %d\n", semS2206flag); + if (semS2206flag == 1) + { + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + inData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatOperParam.h b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatOperParam.h new file mode 100644 index 0000000000000000000000000000000000000000..a3a9ddec3bce07349138c8c2eb9fdcdc2e76d929 --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/InRep/CrSemServ220DatOperParam.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ220DatOperParam.h + * + * Declaration of the DAT Operation Parameter in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV220_DAT_OPER_PARAM_H +#define CRSEM_SERV220_DAT_OPER_PARAM_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + + +/** + * Update action of the DAT Operation Parameter in-coming report packet. + * @param prDesc the procedure descriptor + */ +void CrSemServ220DatOperParamUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV220_DAT_OPER_PARAM_H */ + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdFunctParam.c b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdFunctParam.c new file mode 100644 index 0000000000000000000000000000000000000000..362d9db16390b6dc4ccc0aeb0b87813d11ea33c9 --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdFunctParam.c @@ -0,0 +1,79 @@ +/** + * @file CrSemServ220CmdFunctParam.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM CMD Functional Parameter out-going command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ220CmdFunctParam.h" +#include "../../General/CrSemParamSetter.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +void CrSemServ220CmdFunctParamUpdateAction(FwSmDesc_t smDesc) +{ + unsigned short parCcdWindowStarPosX, parCcdWindowStarPosY; + unsigned short parCcdWindowStarPosX2, parCcdWindowStarPosY2; + unsigned short parDataAcqSrc; + unsigned int parVoltFeeVod, parVoltFeeVrd, parVoltFeeVss; /* NOTE: These are actually float, but we can treat them as uint because we don't look at them. */ + unsigned int parHeatTempFpaCcd, parHeatTempFeeStrap, parHeatTempFeeAnach, parHeatTempSpare; /* NOTE: These are actually float, but we can treat them as uint because we don't look at them. */ + + /* Collect configuration parameters from the data pool */ + CrIaCopy(PWINPOSX_ID, &parCcdWindowStarPosX); + CrIaCopy(PWINPOSY_ID, &parCcdWindowStarPosY); + CrIaCopy(PWINSIZEX_ID, &parCcdWindowStarPosX2); + CrIaCopy(PWINSIZEY_ID, &parCcdWindowStarPosY2); + CrIaCopy(PDTACQSRC_ID, &parDataAcqSrc); + CrIaCopy(PVOLTFEEVOD_ID, &parVoltFeeVod); + CrIaCopy(PVOLTFEEVRD_ID, &parVoltFeeVrd); + CrIaCopy(PVOLTFEEVSS_ID, &parVoltFeeVss); + CrIaCopy(PHEATTEMPFPACCD_ID, &parHeatTempFpaCcd); + CrIaCopy(PHEATTEMPFEESTRAP_ID, &parHeatTempFeeStrap); + CrIaCopy(PHEATTEMPFEEANACH_ID, &parHeatTempFeeAnach); + CrIaCopy(PHEATTEMPSPARE_ID, &parHeatTempSpare); + + PRDEBUGP("parCcdWindowStarPosX %d\n", parCcdWindowStarPosX); + PRDEBUGP("parCcdWindowStarPosY %d\n", parCcdWindowStarPosY); + PRDEBUGP("parCcdWindowStarPosX2 %d\n", parCcdWindowStarPosX2); + PRDEBUGP("parCcdWindowStarPosY2 %d\n", parCcdWindowStarPosY2); + PRDEBUGP("parDataAcqSrc %d\n", parDataAcqSrc); + PRDEBUGP("parVoltFeeVod %08x\n", parVoltFeeVod); + PRDEBUGP("parVoltFeeVrd %08x\n", parVoltFeeVrd); + PRDEBUGP("parVoltFeeVss %08x\n", parVoltFeeVss); + PRDEBUGP("parHeatTempFpaCcd %08x\n", parHeatTempFpaCcd); + PRDEBUGP("parHeatTempFeeStrap %08x\n", parHeatTempFeeStrap); + PRDEBUGP("parHeatTempFeeAnach %08x\n", parHeatTempFeeAnach); + PRDEBUGP("parHeatTempSpare %08x\n", parHeatTempSpare); + + /* Set parameters in command */ + CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosX(smDesc, parCcdWindowStarPosX); + CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosY(smDesc, parCcdWindowStarPosY); + CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosX2(smDesc, parCcdWindowStarPosX2); + CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosY2(smDesc, parCcdWindowStarPosY2); + CrSemServ220CmdFunctParamParamSetParDataAcqSrc(smDesc, parDataAcqSrc); + CrSemServ220CmdFunctParamParamSetParVoltFeeVod(smDesc, parVoltFeeVod); /* setter sets uint */ + CrSemServ220CmdFunctParamParamSetParVoltFeeVrd(smDesc, parVoltFeeVrd); /* setter sets uint */ + CrSemServ220CmdFunctParamParamSetParVoltFeeVss(smDesc, parVoltFeeVss); /* setter sets uint */ + CrSemServ220CmdFunctParamParamSetParHeatTempFpaCcd(smDesc, parHeatTempFpaCcd); /* setter sets uint */ + CrSemServ220CmdFunctParamParamSetParHeatTempFeeStrap(smDesc, parHeatTempFeeStrap); /* setter sets uint */ + CrSemServ220CmdFunctParamParamSetParHeatTempFeeAnach(smDesc, parHeatTempFeeAnach); /* setter sets uint */ + CrSemServ220CmdFunctParamParamSetParHeatTempSpare(smDesc, parHeatTempSpare); /* setter sets uint */ + + return; +} + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdFunctParam.h b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdFunctParam.h new file mode 100644 index 0000000000000000000000000000000000000000..ec116adab6198a603ca9d07228bd53d9c2ebc868 --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdFunctParam.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ220CmdFunctParam.h + * + * Declaration of the CMD Functional Parameter out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV220_CMD_FUNCT_PARAM_H +#define CRSEM_SERV220_CMD_FUNCT_PARAM_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the CMD Functional Parameter telemetry packet. + * Collect configuration parameters from the data pool + * @param smDesc the state machine descriptor + */ +void CrSemServ220CmdFunctParamUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV220_CMD_FUNCT_PARAM_H */ + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdOperParam.c b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdOperParam.c new file mode 100644 index 0000000000000000000000000000000000000000..2434ce6f0e461407f1d466ad4761670af9bd7c04 --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdOperParam.c @@ -0,0 +1,73 @@ +/** + * @file CrSemServ220CmdOperParam.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM CMD Operation Parameter out-going command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ220CmdOperParam.h" +#include "../../General/CrSemParamSetter.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +void CrSemServ220CmdOperParamUpdateAction(FwSmDesc_t smDesc) +{ + unsigned int parExposureTime; + unsigned int parRepetitionPeriod; + unsigned int parAcquisitionNum; + unsigned short parDataOversampling; /* setter needs char */ + unsigned char setDataOversampling; + unsigned short parCcdReadoutMode; /* setter needs char */ + unsigned char setCcdReadoutMode; + + /* Collect configuration parameters from the data pool */ + CrIaCopy(PEXPTIME_ID, &parExposureTime); + CrIaCopy(PIMAGEREP_ID, &parRepetitionPeriod); + + /* Mantis 2168: always command the maximum number of images */ + + parAcquisitionNum = 0xffffffff; + + if (useMaxAcquisitionNum == 0) + { + CrIaCopy(PACQNUM_ID, &parAcquisitionNum); + } + + CrIaCopy(PDATAOS_ID, &parDataOversampling); + setDataOversampling = (unsigned char) parDataOversampling; + CrIaCopy(PCCDRDMODE_ID, &parCcdReadoutMode); + setCcdReadoutMode = (unsigned char) parCcdReadoutMode; + /* set sciSubMode in data pool */ + CrIaPaste(SCISUBMODE_ID, &parCcdReadoutMode); + + PRDEBUGP("parExposureTime: %d\n", parExposureTime); + PRDEBUGP("parRepetitionPeriod: %d\n", parRepetitionPeriod); + PRDEBUGP("parAcquisitionNum : %d\n", parAcquisitionNum); + PRDEBUGP("setDataOversampling: %d\n", setDataOversampling); + PRDEBUGP("setCcdReadoutMode : %d\n", setCcdReadoutMode); + + /* Set parameters in command */ + CrSemServ220CmdOperParamParamSetParExposureTime(smDesc, parExposureTime); + CrSemServ220CmdOperParamParamSetParRepetitionPeriod(smDesc, parRepetitionPeriod); + CrSemServ220CmdOperParamParamSetParAcquisitionNum(smDesc, parAcquisitionNum); + CrSemServ220CmdOperParamParamSetParDataOversampling(smDesc, setDataOversampling); + CrSemServ220CmdOperParamParamSetParCcdReadoutMode(smDesc, setCcdReadoutMode); + + return; +} + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdOperParam.h b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdOperParam.h new file mode 100644 index 0000000000000000000000000000000000000000..a5a9e1a783be0ae6b689bcf7c8abb86cd495238f --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdOperParam.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ220CmdOperParam.h + * + * Declaration of the CMD Operation Parameter out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV220_CMD_OPER_PARAM_H +#define CRSEM_SERV220_CMD_OPER_PARAM_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the CMD Operation Parameter telemetry packet. + * Collect configuration parameters from the data pool + * @param smDesc the state machine descriptor + */ +void CrSemServ220CmdOperParamUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV220_CMD_OPER_PARAM_H */ + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdTempCtrlEnable.c b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdTempCtrlEnable.c new file mode 100644 index 0000000000000000000000000000000000000000..258c96d840dc6e71f596bae73b5e5443e97bb2a6 --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdTempCtrlEnable.c @@ -0,0 +1,36 @@ +/** + * @file CrSemServ220CmdTempCtrlEnable.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM CMD Temperature Control Enable out-going command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ220CmdTempCtrlEnable.h" +#include "../../General/CrSemParamSetter.h" + +#include "CrIaDataPool.h" +#include "CrIaDataPoolId.h" + + +void CrSemServ220CmdTempCtrlEnableUpdateAction(FwSmDesc_t smDesc) +{ + unsigned short pTempCtrlTarget; + + CrIaCopy(PTEMPCTRLTARGET_ID, &pTempCtrlTarget); + + CrSemServ220CmdTempCtrlEnableParamSetParTempControlTarget(smDesc, pTempCtrlTarget); + + return; +} + diff --git a/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdTempCtrlEnable.h b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdTempCtrlEnable.h new file mode 100644 index 0000000000000000000000000000000000000000..8bc5e986855cf09eac4c5067bfb82c416285ac83 --- /dev/null +++ b/CrIa/src/Services/CrSemServ220PrivateService220/OutCmd/CrSemServ220CmdTempCtrlEnable.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ220CmdTempCtrlEnable.h + * + * Declaration of the CMD Temperature Control Enable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE_H +#define CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Update action of the CMD Temperature Control Enable telemetry packet. + * TBD + * @param smDesc the state machine descriptor + */ +void CrSemServ220CmdTempCtrlEnableUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE_H */ + diff --git a/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerDis.c b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerDis.c new file mode 100644 index 0000000000000000000000000000000000000000..8e6c3e1c3ff1aece92deb019e0236fdd27ca0a0d --- /dev/null +++ b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerDis.c @@ -0,0 +1,26 @@ +/** + * @file CrSemServ221FpmPowerDis.c + * + * Implementation of the CMD FPM Power Disable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#include "CrSemServ221FpmPowerDis.h" +#include "../../../CrIaIasw.h" +#include <OutFactory/CrFwOutFactory.h> +#include <OutCmp/CrFwOutCmp.h> +#include <OutLoader/CrFwOutLoader.h> + +#include "../../../IfswDebug.h" + + +void CrSemServ221CmdFpmPowerDisableUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + DEBUGP("CrSemServ221CmdFpmPowerDisableUpdateAction: Switching-off power of SEM units\n"); + + return; +} diff --git a/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerDis.h b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerDis.h new file mode 100644 index 0000000000000000000000000000000000000000..79c08919335caf361bd9e85bc86ee8155b30edc3 --- /dev/null +++ b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerDis.h @@ -0,0 +1,23 @@ +/** + * @file CrSemServ221FpmPowerDis.h + * + * Declaration of the CMD FPM Power Disable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV221_CMD_FPM_POWER_DIS_H +#define CRSEM_SERV221_CMD_FPM_POWER_DIS_H + +#include "FwProfile/FwSmCore.h" +#include "CrFramework/CrFwConstants.h" + +/** + * Update action of the CMD FPM Power Disable telemetry packet. + * @param smDesc the state machine descriptor + */ +void CrSemServ221CmdFpmPowerDisableUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV221_CMD_FPM_POWER_DIS_H */ + diff --git a/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerEnb.c b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerEnb.c new file mode 100644 index 0000000000000000000000000000000000000000..58feb5fa8b653197cfa661559c36286a6a1e4d4a --- /dev/null +++ b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerEnb.c @@ -0,0 +1,26 @@ +/** + * @file CrSemServ221FpmPowerEnb.c + * + * Implementation of the CMD FPM Power Enable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#include "CrSemServ221FpmPowerEnb.h" +#include "../../../CrIaIasw.h" +#include <OutFactory/CrFwOutFactory.h> +#include <OutCmp/CrFwOutCmp.h> +#include <OutLoader/CrFwOutLoader.h> + +#include "../../../IfswDebug.h" + + +void CrSemServ221CmdFpmPowerEnableUpdateAction(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + /* Implement the action logic here: */ + DEBUGP("CrSemServ221CmdFpmPowerEnableUpdateAction: Switching-on power of SEM units\n"); + + return; +} diff --git a/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerEnb.h b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerEnb.h new file mode 100644 index 0000000000000000000000000000000000000000..5a1f9bbb1ff0e6951695c64736192c59000593b4 --- /dev/null +++ b/CrIa/src/Services/CrSemServ221PrivateService221/OutCmd/CrSemServ221FpmPowerEnb.h @@ -0,0 +1,23 @@ +/** + * @file CrSemServ220FpmPowerEnable.h + * + * Declaration of the CMD FPM Power Enable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV221_CMD_FPM_POWER_ENB_H +#define CRSEM_SERV221_CMD_FPM_POWER_ENB_H + +#include "FwProfile/FwSmCore.h" +#include "CrFramework/CrFwConstants.h" + +/** + * Update action of the CMD FPM Power Enable telemetry packet. + * @param smDesc the state machine descriptor + */ +void CrSemServ221CmdFpmPowerEnableUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV221_CMD_FPM_POWER_ENB_H */ + diff --git a/CrIa/src/Services/CrSemServ222PrivateService222/InRep/CrSemServ222DatTestLog.c b/CrIa/src/Services/CrSemServ222PrivateService222/InRep/CrSemServ222DatTestLog.c new file mode 100644 index 0000000000000000000000000000000000000000..95100b5477f61695ad326bacf9a9f70583c509d9 --- /dev/null +++ b/CrIa/src/Services/CrSemServ222PrivateService222/InRep/CrSemServ222DatTestLog.c @@ -0,0 +1,63 @@ +/** + * @file CrSemServ222DatTestLog.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Test Log in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ222DatTestLog.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <CrFwCmpData.h> + +/* send function in the 222,6 forward */ +#include <OutStream/CrFwOutStream.h> + +#include <CrIaIasw.h> +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <IfswDebug.h> + + +void CrSemServ222DatTestLogUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char semS2226flag; + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Check, if SEM_SERV222_6_FORWARD is enabled */ + CrIaCopy(SEM_SERV222_6_FORWARD_ID, &semS2226flag); + DEBUGP("semS2226flag: %d\n", semS2226flag); + if (semS2226flag == 1) + { + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + inData->outcome = 1; + + return; +} + diff --git a/CrIa/src/Services/CrSemServ222PrivateService222/InRep/CrSemServ222DatTestLog.h b/CrIa/src/Services/CrSemServ222PrivateService222/InRep/CrSemServ222DatTestLog.h new file mode 100644 index 0000000000000000000000000000000000000000..cc67f93e0facec6d54c64fa07e7db3d047928b7d --- /dev/null +++ b/CrIa/src/Services/CrSemServ222PrivateService222/InRep/CrSemServ222DatTestLog.h @@ -0,0 +1,24 @@ +/** + * @file CrSemServ222DatTestLog.h + * + * Declaration of the DAT Test Log in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV221_DAT_TEST_LOG_H +#define CRSEM_SERV221_DAT_TEST_LOG_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + + +/** + * Update action of the DAT Test Log in-coming report packet. + * @param prDesc the procedure descriptor + */ +void CrSemServ222DatTestLogUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV221_DAT_TEST_LOG_H */ + diff --git a/CrIa/src/Services/CrSemServ222PrivateService222/OutCmd/CrSemServ222DiagEnable.c b/CrIa/src/Services/CrSemServ222PrivateService222/OutCmd/CrSemServ222DiagEnable.c new file mode 100644 index 0000000000000000000000000000000000000000..9f86c828be0ff288d1f0644b62b36d863f943ce4 --- /dev/null +++ b/CrIa/src/Services/CrSemServ222PrivateService222/OutCmd/CrSemServ222DiagEnable.c @@ -0,0 +1,67 @@ +/** + * @file CrSemServ222DiagEnable.c + * + * Implementation of the CMD DIAGNOSTIC Enable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#include "CrSemServ222DiagEnable.h" +#include "../../General/CrSemParamSetter.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + + +void CrSemServ222CmdDiagEnableUpdateAction(FwSmDesc_t smDesc) +{ + unsigned short pStepEnDiagCcd, pStepEnDiagFee, pStepEnDiagTemp, pStepEnDiagAna, pStepEnDiagExpos; + unsigned short pStepDebDiagCcd, pStepDebDiagFee, pStepDebDiagTemp, pStepDebDiagAna, pStepDebDiagExpos; + + DEBUGP("CrSemServ222CmdDiagEnableUpdateAction\n"); + + /* get pStepEnDiagCcd PAR_STEP_ENABLE_ DIAG_CCD from data pool and set it in packet */ + CrIaCopy(PSTEPENDIAGCCD_ID, &pStepEnDiagCcd); + CrSemServ222CmdDiagEnableParamSetParStepEnDiagCcd(smDesc, pStepEnDiagCcd); + + /* pStepEnDiagFee PAR_STEP_ENABLE_ DIAG_FEE from data pool and set it in packet */ + CrIaCopy(PSTEPENDIAGFEE_ID, &pStepEnDiagFee); + CrSemServ222CmdDiagEnableParamSetParStepEnDiagFee(smDesc, pStepEnDiagFee); + + /* pStepEnDiagTemp PAR_STEP_ENABLE_ DIAG_TEMP_CONTROL from data pool and set it in packet */ + CrIaCopy(PSTEPENDIAGTEMP_ID, &pStepEnDiagTemp); + CrSemServ222CmdDiagEnableParamSetParStepEnDiagTemp(smDesc, pStepEnDiagTemp); + + /* pStepEnDiagAna PAR_STEP_ENABLE_ DIAG_ANALOG_HK from data pool and set it in packet */ + CrIaCopy(PSTEPENDIAGANA_ID, &pStepEnDiagAna); + CrSemServ222CmdDiagEnableParamSetParStepEnDiagAna(smDesc, pStepEnDiagAna); + + /* pStepEnDiagExpos PAR_STEP_ENABLE_ DIAG_EXPOS from data pool and set it in packet */ + CrIaCopy(PSTEPENDIAGEXPOS_ID, &pStepEnDiagExpos); + CrSemServ222CmdDiagEnableParamSetParStepEnDiagExpos(smDesc, pStepEnDiagExpos); + + /* pStepDebDiagCcd PAR_STEP_DEBUG_ DIAG_CCD from data pool and set it in packet */ + CrIaCopy(PSTEPDEBDIAGCCD_ID, &pStepDebDiagCcd); + CrSemServ222CmdDiagEnableParamSetParStepDebDiagCcd(smDesc, pStepDebDiagCcd); + + /* pStepDebDiagFee PAR_STEP_DEBUG_ DIAG_FEE from data pool and set it in packet */ + CrIaCopy(PSTEPDEBDIAGFEE_ID, &pStepDebDiagFee); + CrSemServ222CmdDiagEnableParamSetParStepDebDiagFee(smDesc, pStepDebDiagFee); + + /* pStepDebDiagTemp PAR_STEP_DEBUG_ DIAG_TEMP_CONTROL from data pool and set it in packet */ + CrIaCopy(PSTEPDEBDIAGTEMP_ID, &pStepDebDiagTemp); + CrSemServ222CmdDiagEnableParamSetParStepDebDiagTemp(smDesc, pStepDebDiagTemp); + + /* pStepDebDiagAna PAR_STEP_DEBUG_ DIAG_ANALOG_HK from data pool and set it in packet */ + CrIaCopy(PSTEPDEBDIAGANA_ID, &pStepDebDiagAna); + CrSemServ222CmdDiagEnableParamSetParStepDebDiagAna(smDesc, pStepDebDiagAna); + + /* pStepDebDiagExpos PAR_STEP_DEBUG_ DIAG_EXPOS from data pool and set it in packet */ + CrIaCopy(PSTEPDEBDIAGEXPOS_ID, &pStepDebDiagExpos); + CrSemServ222CmdDiagEnableParamSetParStepDebDiagExpos(smDesc, pStepDebDiagExpos); + + return; +} diff --git a/CrIa/src/Services/CrSemServ222PrivateService222/OutCmd/CrSemServ222DiagEnable.h b/CrIa/src/Services/CrSemServ222PrivateService222/OutCmd/CrSemServ222DiagEnable.h new file mode 100644 index 0000000000000000000000000000000000000000..1e8ba4da1e6adbcf583fc660e16e514e81f5ae8d --- /dev/null +++ b/CrIa/src/Services/CrSemServ222PrivateService222/OutCmd/CrSemServ222DiagEnable.h @@ -0,0 +1,23 @@ +/** + * @file CrSemServ222DiagEnable.h + * + * Declaration of the CMD DIAGNOSTIC Enable out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV222_CMD_DIAG_ENABLE_H +#define CRSEM_SERV222_CMD_DIAG_ENABLE_H + +#include "FwProfile/FwSmCore.h" +#include "CrFramework/CrFwConstants.h" + +/** + * Update action of the CMD DIAGNOSTIC Enable telemetry packet. + * @param smDesc the state machine descriptor + */ +void CrSemServ222CmdDiagEnableUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV222_CMD_DIAG_ENABLE_H */ + diff --git a/CrIa/src/Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.c b/CrIa/src/Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.c new file mode 100644 index 0000000000000000000000000000000000000000..273fb8ae81b01d13954ea752a01ab4959077a165 --- /dev/null +++ b/CrIa/src/Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.c @@ -0,0 +1,1184 @@ +/** + * @file CrSemServ3DatHk.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Housekeeping in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ3DatHk.h" + +#include "../../../IfswDebug.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrSemParamGetter.h> + +#include <byteorder.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> +#include <CrIaPrSm/CrIaFdCheckCreate.h> +#include <CrIaPrSm/CrIaSemCreate.h> /* for SEM State Machine state identifiers */ + +/* send function in the 3,25 1 and 3,25 2 forward */ +#include <OutStream/CrFwOutStream.h> + +/* imported global variables */ +extern unsigned short SemHkIaswStateExecCnt; /* needed by FdCheckFunc */ +extern FwSmBool_t flagDelayedSemHkPacket; /* needed by FdCheckFunc */ +extern unsigned int semAliveStatusDefCnt, semAliveStatusExtCnt; /* needed by FdCheckFunc */ +extern unsigned int warnLimitDefCnt, alarmLimitDefCnt; /* needed by FdCheckFunc (Default HK) */ +extern unsigned int warnLimitExtCnt, alarmLimitExtCnt; /* needed by FdCheckFunc (Extended HK) */ +static unsigned char warnLimitDef[NMB_LIMIT_CHECK_MAX], warnLimitExt[NMB_LIMIT_CHECK_MAX]; +static unsigned char semAliveStatusDef[NMB_LIMIT_CHECK_MAX], semAliveStatusExt[NMB_LIMIT_CHECK_MAX]; + +unsigned int defHkCycCntOld = 0, extHkCycCntOld = 0; +unsigned int defHkCycCntNew, extHkCycCntNew; +unsigned short defHkCycCntDiff, extHkCycCntDiff; /* number of cycles */ + + +typedef struct { + unsigned int nmbWarn; + unsigned int nmbAlarm; +} fdCheckLimit_t; + + +/* Mantis 2182 */ +void ClearWarnLimit (void) +{ + unsigned int i; + + for (i=0; i < NMB_LIMIT_CHECK_MAX; i++) + { + warnLimitDef[i] = 0; + warnLimitExt[i] = 0; + } + + return; +} + + +/* Mantis 2182 */ +void ClearAliveLimit (void) +{ + unsigned int i; + + for (i=0; i < NMB_LIMIT_CHECK_MAX; i++) + { + semAliveStatusDef[i] = 0; + semAliveStatusExt[i] = 0; + } + + return; +} + + +fdCheckLimit_t checkFloatSemLimit(unsigned int id, float value) +{ + unsigned char FdCheckGlbEn = 0, FdCheckIntEn = 0, FdCheckExtEn = 0; + float upperAlarmLimit = 0.0f, upperWarningLimit = 0.0f, lowerAlarmLimit = 0.0f, lowerWarningLimit = 0.0f; + fdCheckLimit_t FdCheckLimit; + unsigned short evt_data[2]; + unsigned short semState, semOperState; + unsigned char skipCheck; + + /* Mantis 2121: Only perform check of TEMP_FEE_*, VOLT_FEE_*, and CURR_FEE_CLK_BUF + after SEM State Machine has entered STABILIZE */ + CrIaCopy(SEMSTATE_ID, &semState); + CrIaCopy(SEMOPERSTATE_ID, &semOperState); + + /* initialize skipCheck */ + skipCheck = 0; + + switch (id) + { + /* Default HK */ + case TEMP_SEM_SCU_ID: + CrIaCopy(TEMP_SEM_SCU_LW_ID, &lowerWarningLimit); + CrIaCopy(TEMP_SEM_SCU_UW_ID, &upperWarningLimit); + CrIaCopy(TEMP_SEM_SCU_LA_ID, &lowerAlarmLimit); + CrIaCopy(TEMP_SEM_SCU_UA_ID, &upperAlarmLimit); + break; + case TEMP_SEM_PCU_ID: + CrIaCopy(TEMP_SEM_PCU_LW_ID, &lowerWarningLimit); + CrIaCopy(TEMP_SEM_PCU_UW_ID, &upperWarningLimit); + CrIaCopy(TEMP_SEM_PCU_LA_ID, &lowerAlarmLimit); + CrIaCopy(TEMP_SEM_PCU_UA_ID, &upperAlarmLimit); + break; + case VOLT_SCU_P3_4_ID: + CrIaCopy(VOLT_SCU_P3_4_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_SCU_P3_4_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_SCU_P3_4_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_SCU_P3_4_UA_ID, &upperAlarmLimit); + break; + case VOLT_SCU_P5_ID: + CrIaCopy(VOLT_SCU_P5_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_SCU_P5_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_SCU_P5_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_SCU_P5_UA_ID, &upperAlarmLimit); + break; + /* Extended HK */ + case TEMP_FEE_CCD_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(TEMP_FEE_CCD_LW_ID, &lowerWarningLimit); + CrIaCopy(TEMP_FEE_CCD_UW_ID, &upperWarningLimit); + CrIaCopy(TEMP_FEE_CCD_LA_ID, &lowerAlarmLimit); + CrIaCopy(TEMP_FEE_CCD_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case TEMP_FEE_STRAP_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(TEMP_FEE_STRAP_LW_ID, &lowerWarningLimit); + CrIaCopy(TEMP_FEE_STRAP_UW_ID, &upperWarningLimit); + CrIaCopy(TEMP_FEE_STRAP_LA_ID, &lowerAlarmLimit); + CrIaCopy(TEMP_FEE_STRAP_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case TEMP_FEE_ADC_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(TEMP_FEE_ADC_LW_ID, &lowerWarningLimit); + CrIaCopy(TEMP_FEE_ADC_UW_ID, &upperWarningLimit); + CrIaCopy(TEMP_FEE_ADC_LA_ID, &lowerAlarmLimit); + CrIaCopy(TEMP_FEE_ADC_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case TEMP_FEE_BIAS_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(TEMP_FEE_BIAS_LW_ID, &lowerWarningLimit); + CrIaCopy(TEMP_FEE_BIAS_UW_ID, &upperWarningLimit); + CrIaCopy(TEMP_FEE_BIAS_LA_ID, &lowerAlarmLimit); + CrIaCopy(TEMP_FEE_BIAS_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case TEMP_FEE_DEB_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(TEMP_FEE_DEB_LW_ID, &lowerWarningLimit); + CrIaCopy(TEMP_FEE_DEB_UW_ID, &upperWarningLimit); + CrIaCopy(TEMP_FEE_DEB_LA_ID, &lowerAlarmLimit); + CrIaCopy(TEMP_FEE_DEB_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_VOD_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_VOD_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_VOD_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_VOD_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_VOD_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_VRD_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_VRD_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_VRD_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_VRD_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_VRD_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_VOG_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_VOG_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_VOG_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_VOG_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_VOG_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_VSS_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_VSS_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_VSS_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_VSS_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_VSS_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_CCD_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_CCD_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_CCD_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_CCD_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_CCD_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_CLK_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_CLK_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_CLK_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_CLK_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_CLK_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_ANA_P5_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_ANA_P5_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_ANA_P5_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_ANA_P5_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_ANA_P5_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_ANA_N5_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_ANA_N5_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_ANA_N5_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_ANA_N5_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_ANA_N5_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_FEE_ANA_P3_3_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(VOLT_FEE_ANA_P3_3_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_FEE_ANA_P3_3_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_FEE_ANA_P3_3_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_FEE_ANA_P3_3_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case CURR_FEE_CLK_BUF_ID: + if ((semState == CrIaSem_OPER) && (semOperState != CrIaSem_STOPPED) && (semOperState != CrIaSem_STANDBY) && (semOperState != CrIaSem_TR_STABILIZE)) + { + CrIaCopy(CURR_FEE_CLK_BUF_LW_ID, &lowerWarningLimit); + CrIaCopy(CURR_FEE_CLK_BUF_UW_ID, &upperWarningLimit); + CrIaCopy(CURR_FEE_CLK_BUF_LA_ID, &lowerAlarmLimit); + CrIaCopy(CURR_FEE_CLK_BUF_UA_ID, &upperAlarmLimit); + } + else + skipCheck = 1; + break; + case VOLT_SCU_FPGA_P1_5_ID: + CrIaCopy(VOLT_SCU_FPGA_P1_5_LW_ID, &lowerWarningLimit); + CrIaCopy(VOLT_SCU_FPGA_P1_5_UW_ID, &upperWarningLimit); + CrIaCopy(VOLT_SCU_FPGA_P1_5_LA_ID, &lowerAlarmLimit); + CrIaCopy(VOLT_SCU_FPGA_P1_5_UA_ID, &upperAlarmLimit); + break; + case CURR_SCU_P3_4_ID: + CrIaCopy(CURR_SCU_P3_4_LW_ID, &lowerWarningLimit); + CrIaCopy(CURR_SCU_P3_4_UW_ID, &upperWarningLimit); + CrIaCopy(CURR_SCU_P3_4_LA_ID, &lowerAlarmLimit); + CrIaCopy(CURR_SCU_P3_4_UA_ID, &upperAlarmLimit); + break; + default: + + break; + } + + if (!skipCheck) + { + /* check if value is in alarm region */ + if ((value >= upperAlarmLimit) || (value <= lowerAlarmLimit)) + { + FdCheckLimit.nmbAlarm = 1; + } + else + { + FdCheckLimit.nmbAlarm = 0; + } + + /* check if value is in warning or alarm region */ + if ((value >= upperWarningLimit) || (value <= lowerWarningLimit)) + { + FdCheckLimit.nmbWarn = 1; + } + else + { + FdCheckLimit.nmbWarn = 0; + } + + /* Mantis 2182: if there is a warning or an alert (or both), we want to see only one event */ + if (FdCheckLimit.nmbAlarm || FdCheckLimit.nmbWarn) + { + /* send event report OOL only if SEM Limit FdCheck is enabled */ + CrIaCopy(FDGLBENABLE_ID, &FdCheckGlbEn); + if (FdCheckGlbEn == 1) + { + CrIaCopy(FDCHECKSEMLIMITINTEN_ID, &FdCheckIntEn); + CrIaCopy(FDCHECKSEMLIMITEXTEN_ID, &FdCheckExtEn); + if ((FdCheckIntEn == 1) && (FdCheckExtEn == 1)) + { + evt_data[0] = 0; /* IDs fit in 16 bit */ + evt_data[1] = id; + CrIaEvtRep(CRIA_SERV5_EVT_ERR_MED_SEV, CRIA_SERV5_EVT_OOL_PARAM, evt_data, 4); + } + } + } + } + else + { + FdCheckLimit.nmbAlarm = 0; + FdCheckLimit.nmbWarn = 0; + } + + return FdCheckLimit; +} + +void shiftWarnLimits(CrFwBool_t HkDef) +{ + int i; + for (i=0; i<NMB_LIMIT_CHECK_MAX-1; i++) + { + if (HkDef) + { + warnLimitDef[NMB_LIMIT_CHECK_MAX-i-1] = warnLimitDef[NMB_LIMIT_CHECK_MAX-i-2]; + DEBUGP("warnLimitDef[%d] = warnLimitDef[%d] = %d\n", i+1, i, warnLimitDef[i]); + } + else + { + warnLimitExt[NMB_LIMIT_CHECK_MAX-i-1] = warnLimitExt[NMB_LIMIT_CHECK_MAX-i-2]; + DEBUGP("warnLimitExt[%d] = warnLimitExt[%d] = %d\n", i+1, i, warnLimitExt[i]); + } + } + return; +} + +void shiftSemAliveStatus(CrFwBool_t HkDef) +{ + int i; + for (i=0; i<NMB_LIMIT_CHECK_MAX-1; i++) + { + if (HkDef) + { + semAliveStatusDef[NMB_LIMIT_CHECK_MAX-i-1] = semAliveStatusDef[NMB_LIMIT_CHECK_MAX-i-2]; + DEBUGP("semAliveStatusDef[%d] = semAliveStatusDef[%d] = %d\n", i+1, i, semAliveStatusDef[i]); + } + else + { + semAliveStatusExt[NMB_LIMIT_CHECK_MAX-i-1] = semAliveStatusExt[NMB_LIMIT_CHECK_MAX-i-2]; + DEBUGP("semAliveStatusExt[%d] = semAliveStatusExt[%d] = %d\n", i+1, i, semAliveStatusExt[i]); + } + } + return; +} + +unsigned int sumWarnLimits(CrFwBool_t HkDef) +{ + int i, nmbWarnLimits; + unsigned int sum = 0; + unsigned short semLimDelT; /* number of cycles */ + + CrIaCopy(SEM_LIM_DEL_T_ID, &semLimDelT); + + if (HkDef) + { + nmbWarnLimits = (unsigned short)(semLimDelT / defHkCycCntDiff) + 1; + DEBUGP("sumWarnLimits(): nmbWarnLimits = %d (semLimDelT: %d / defHkCycCntDiff: %d)\n", nmbWarnLimits, semLimDelT, defHkCycCntDiff); + } + else + { + nmbWarnLimits = (unsigned short)(semLimDelT / extHkCycCntDiff) + 1; + DEBUGP("sumWarnLimits(): nmbWarnLimits = %d (semLimDelT: %d / extHkCycCntDiff: %d)\n", nmbWarnLimits, semLimDelT, extHkCycCntDiff); + } + + if (nmbWarnLimits > NMB_LIMIT_CHECK_MAX) + { + nmbWarnLimits = NMB_LIMIT_CHECK_MAX; + } + + /* Mantis 2182: we sum recent and older warnings */ + for (i=0; i<nmbWarnLimits; i++) + { + if (HkDef) + { + sum += warnLimitDef[i]; + DEBUGP("warnLimitDef[%d] = %d\n", i, warnLimitDef[i]); + } + else + { + sum += warnLimitExt[i]; + DEBUGP("warnLimitExt[%d] = %d\n", i, warnLimitExt[i]); + } + } + return sum; +} + +unsigned int sumSemAliveStatus(CrFwBool_t HkDef) +{ + int i, nmbWarnLimits; + unsigned int sum = 0; + unsigned short semLimDelT; /* number of cycles */ + + CrIaCopy(SEM_LIM_DEL_T_ID, &semLimDelT); + + if (HkDef) + { + nmbWarnLimits = (unsigned short)(semLimDelT / defHkCycCntDiff) + 1; + DEBUGP("sumSemAliveStatus(): nmbWarnLimits = %d (semLimDelT: %d / defHkCycCntDiff: %d)\n", nmbWarnLimits, semLimDelT, defHkCycCntDiff); + } + else + { + nmbWarnLimits = (unsigned short)(semLimDelT / extHkCycCntDiff) + 1; + DEBUGP("sumSemAliveStatus(): nmbWarnLimits = %d (semLimDelT: %d / extHkCycCntDiff: %d)\n", nmbWarnLimits, semLimDelT, extHkCycCntDiff); + } + + if (nmbWarnLimits > NMB_LIMIT_CHECK_MAX) + { + nmbWarnLimits = NMB_LIMIT_CHECK_MAX; + } + + for (i=0; i<nmbWarnLimits; i++) + { + if (HkDef) + { + sum += semAliveStatusDef[i]; + DEBUGP("semAliveStatusDef[%d] = %d\n", i, semAliveStatusDef[i]); + } + else + { + sum += semAliveStatusExt[i]; + DEBUGP("semAliveStatusExt[%d] = %d\n", i, semAliveStatusExt[i]); + } + } + return sum; +} + + +/** + * @brief Update action of the Service 3 SEM DAT Housekeeping in-coming report + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Copy HK report to data pool + * if forwarding of SEM HK report is enabled: + * - Forward HK report to Ground + * + * @param[in] prDesc procedure descriptor + * @param[out] none + */ +void CrSemServ3DatHkUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + CrFwDiscriminant_t disc; + CrFwTimeStamp_t time; + + fdCheckLimit_t FdCheckLimit; + unsigned short sm_state; + + unsigned short timeStamp_FINE; + unsigned int timeStamp_CRS; + unsigned char semS31flag, semS32flag; + + /* default HK */ + unsigned short hkStatMode, hkStatFlags; +#ifdef PC_TARGET + unsigned short fixVal9; + unsigned char hkStatObtSyncFlag, hkStatWatchDog, hkStatEepromPower, hkStatHkPower, hkStatFpmPower, hkStatDatBufferOverflow, hkStatScuMainRed; +#endif + unsigned short hkStatLastSpwlinkError, hkStatLastErrorId, hkStatLastErrorFrequency; + unsigned short hkStatNumCmdReceived, hkStatNumCmdExecuted, hkStatNumDatSent; + unsigned short hkStatScuProcDutyCycle, hkStatScuNumAhbError, hkStatScuNumAhbCorrectableError, hkStatHkNumLatchupError; + float hkTempSemScu, hkTempSemPcu, hkVoltScuP34, hkVoltScuP5; + + /* extended HK */ + float hkTempFeeCcd, hkTempFeeStrap, hkTempFeeAdc, hkTempFeeBias, hkTempFeeDeb; + float hkVoltFeeVod, hkVoltFeeVrd, hkVoltFeeVog, hkVoltFeeVss, hkVoltFeeCcd, hkVoltFeeClk, hkVoltFeeAnaP5, hkVoltFeeAnaN5, hkVoltFeeDigP33, hkCurrFeeClkBuf; + /* float hkVoltPcuP30, hkVoltPcuP15, hkVoltPcuP5, hkVoltPcuN5, hkVoltPcuP34, hkVoltPcuP7;*/ + float hkVoltScuFpgaP15, hkCurrScuP34; + unsigned char hkStatNumSpwErrCredit, hkStatNumSpwErrEscape, hkStatNumSpwErrDisconnect, hkStatNumSpwErrParity, hkStatNumSpwErrWriteSync; + unsigned char hkStatNumSpwErrInvalidAddress, hkStatNumSpwErrEopeep, hkStatNumSpwErrRxAhb, hkStatNumSpwErrTxAhb, hkStatNumSpwErrTxBlocked; + unsigned char hkStatNumSpwErrTxle, hkStatNumSpwErrRx, hkStatNumSpwErrTx; + unsigned char hkStatHeatPwmFpaCcd, hkStatHeatPwmFeeStrap, hkStatHeatPwmFeeAnach, hkStatHeatPwmSpare; + unsigned char hkStatBits; + unsigned short hkStatOBTimeSyncDelta; + + CRFW_UNUSED(prDesc); /* remove if smDesc is used in this function */ + + /* The Update Action of incoming service 3 reports shall run the SEM HK Update Procedure. */ + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + disc = CrFwPcktGetDiscriminant(inPckt); + DEBUGP("Discriminant: %d\n", disc); + + if (disc == 1) /* default HK */ + { + /* Check, if SEM_SERV3_1_FORWARD is enabled */ + CrIaCopy(SEM_SERV3_1_FORWARD_ID, &semS31flag); + DEBUGP("semS31flag: %d\n", semS31flag); + if (semS31flag == 1) + { + /* SendSemForwardTmService3(inPckt); */ + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + /* used for FdCheck: SEM Alive Check */ + /* get actual IASW cycle counter information when SEM HK was received and set the global variable */ + SemHkIaswStateExecCnt = FwSmGetExecCnt(smDescIasw); + /* reset flag for first delayed SEM HK packet */ + flagDelayedSemHkPacket = 0; + + /* keep old IASW cycle count */ + defHkCycCntOld = defHkCycCntNew; + + /* get current IASW cycle count */ + defHkCycCntNew = FwSmGetExecCnt(smDescIasw); + + /* calculate the cycles between the last received and the current HK packet */ + if (defHkCycCntOld < defHkCycCntNew) + { + defHkCycCntDiff = defHkCycCntNew - defHkCycCntOld; + } + else /* counter reset occured in the meantime ! */ + { + defHkCycCntDiff = 65535 - defHkCycCntOld + defHkCycCntNew; + } + + } + + if (disc == 2) /* extended HK */ + { + /* Check, if SEM_SERV3_2_FORWARD is enabled */ + CrIaCopy(SEM_SERV3_2_FORWARD_ID, &semS32flag); + DEBUGP("semS32flag: %d\n", semS32flag); + if (semS32flag == 1) + { + /* SendSemForwardTmService3(inPckt); */ + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + /* keep old IASW cycle count */ + extHkCycCntOld = extHkCycCntNew; + + /* get current IASW cycle count */ + extHkCycCntNew = FwSmGetExecCnt(smDescIasw); + + /* calculate the cycles between the last received and the current HK packet */ + if (extHkCycCntOld < extHkCycCntNew) + { + extHkCycCntDiff = extHkCycCntNew - extHkCycCntOld; + } + else /* counter reset occured in the meantime ! */ + { + extHkCycCntDiff = 65535 - extHkCycCntOld + extHkCycCntNew; + } + + } + + time = CrFwPcktGetTimeStamp(inPckt); + + timeStamp_CRS = ((((unsigned int) time.t[0]) << 24) | + (((unsigned int) time.t[1]) << 16) | + (((unsigned int) time.t[2]) << 8) | + ((unsigned int) time.t[3])); + + timeStamp_FINE = ((((unsigned short) time.t[4]) << 8) | + ((unsigned short) time.t[5])); + + timeStamp_CRS = be32_to_cpu(timeStamp_CRS); + timeStamp_FINE = be16_to_cpu(timeStamp_FINE); + + DEBUGP("time stamp CRS: %d\n", timeStamp_CRS); + DEBUGP("time stamp FINE: %d\n", timeStamp_FINE); + + if (disc == 1) + { + + /* Set parameters SEM_HK_TIMESTAMP_DEF: SEM_HK_TS_DEF_CRS_ID and SEM_HK_TS_DEF_FINE_ID in data pool */ + /* Copy of coarse part of the time-stamp from SEM HK default packet */ + /* Copy of fine part of the time-stamp from SEM HK default packet */ + + CrIaPaste(SEM_HK_TS_DEF_CRS_ID, &timeStamp_CRS); + CrIaPaste(SEM_HK_TS_DEF_FINE_ID, &timeStamp_FINE); + + } + else if (disc == 2) + { + + /* Set parameters SEM_HK_TIMESTAMP_EXT: SEM_HK_TS_EXT_CRS_ID and SEM_HK_TS_EXT_FINE_ID in data pool */ + /* Copy of coarse part of the time-stamp from SEM HK extended packet */ + /* Copy of fine part of the time-stamp from SEM HK extended packet */ + + CrIaPaste(SEM_HK_TS_EXT_CRS_ID, &timeStamp_CRS); + CrIaPaste(SEM_HK_TS_EXT_FINE_ID, &timeStamp_FINE); + + } + + /* Set other SEM HK parameters in data pool */ + + if (disc == 1) + { + /* FdCheck SEM Limit Check */ + shiftWarnLimits(1); /* shift warn limits one slot further (Default HK) */ + shiftSemAliveStatus(1); /* shift SEM Alive FdCheck status one slot further (Default HK) */ + warnLimitDefCnt = 0; /* reset warn limit counter */ + alarmLimitDefCnt = 0; /* reset alarm limit counter */ + + /* Get FdCheck SEM Alive status */ + sm_state = FwSmGetCurState(smDescFdSemAliveCheck); + if ((sm_state == CrIaFdCheck_DISABLED) || (sm_state == CrIaFdCheck_NOMINAL)) + { + semAliveStatusDef[0] = 0; + } + else + { + semAliveStatusDef[0] = 1; + } + semAliveStatusDefCnt = sumSemAliveStatus(1); + + /* STAT_MODE in SEM HK default packet */ + CrSemServ3OperationDefaultHkParamGetHkStatMode(&hkStatMode, inPckt); + DEBUGP("hkStatMode: %d\n", hkStatMode); + CrIaPaste(STAT_MODE_ID, &hkStatMode); + /* Monitored by FdCheck SEM Limit Check */ + + CrSemServ3OperationDefaultHkParamGetHkStatFlags(&hkStatFlags, inPckt); + DEBUGP("hkStatFlags: %d\n", hkStatFlags); + CrIaPaste(STAT_FLAGS_ID, &hkStatFlags); + +#ifdef PC_TARGET + DEBUGP("hkStatFlags: -----------------------------------\n"); + + CrSemServ3OperationDefaultHkParamGetFixVal9(&fixVal9, inPckt); + DEBUGP("hkStatFlags: fixVal9 = %d\n", fixVal9); + + CrSemServ3OperationDefaultHkParamGetHkStatObtSyncFlag(&hkStatObtSyncFlag, inPckt); + DEBUGP("hkStatFlags: hkStatObtSyncFlag = %d\n", hkStatObtSyncFlag); + /* Monitored by FdCheck SEM Limit Check */ + + CrSemServ3OperationDefaultHkParamGetHkStatWatchDog(&hkStatWatchDog, inPckt); + DEBUGP("hkStatFlags: hkStatWatchDog = %d\n", hkStatWatchDog); + + CrSemServ3OperationDefaultHkParamGetHkStatEepromPower(&hkStatEepromPower, inPckt); + DEBUGP("hkStatFlags: hkStatEepromPower = %d\n", hkStatEepromPower); + + CrSemServ3OperationDefaultHkParamGetHkStatHkPower(&hkStatHkPower, inPckt); + DEBUGP("hkStatFlags: hkStatHkPower = %d\n", hkStatHkPower); + + CrSemServ3OperationDefaultHkParamGetHkStatFpmPower(&hkStatFpmPower, inPckt); + DEBUGP("hkStatFlags: hkStatFpmPower = %d\n", hkStatFpmPower); + + CrSemServ3OperationDefaultHkParamGetHkStatDatBufferOverflow(&hkStatDatBufferOverflow, inPckt); + DEBUGP("hkStatFlags: hkStatDatBufferOverflow = %d\n", hkStatDatBufferOverflow); + + CrSemServ3OperationDefaultHkParamGetHkStatScuMainRed(&hkStatScuMainRed, inPckt); + DEBUGP("hkStatFlags: hkStatScuMainRed = %d\n", hkStatScuMainRed); + + DEBUGP("hkStatFlags: -----------------------------------\n"); +#endif + + /* STAT_LAST_SPW_ERR in SEM HK default packet */ + /* STAT_LAST_ERR_ID in SEM HK default packet */ + /* STAT_LAST_ERR_FREQ in SEM HK default packet */ + + CrSemServ3OperationDefaultHkParamGetHkStatLastSpwlinkError(&hkStatLastSpwlinkError, inPckt); + DEBUGP("hkStatLastSpwlinkError: %d\n", hkStatLastSpwlinkError); + CrIaPaste(STAT_LAST_SPW_ERR_ID, &hkStatLastSpwlinkError); + + CrSemServ3OperationDefaultHkParamGetHkStatLastErrorId(&hkStatLastErrorId, inPckt); + DEBUGP("hkStatLastErrorId: %d\n", hkStatLastErrorId); + CrIaPaste(STAT_LAST_ERR_ID_ID, &hkStatLastErrorId); + + CrSemServ3OperationDefaultHkParamGetHkStatLastErrorFrequency(&hkStatLastErrorFrequency, inPckt); + DEBUGP("hkStatLastErrorFrequency: %d\n", hkStatLastErrorFrequency); + CrIaPaste(STAT_LAST_ERR_FREQ_ID, &hkStatLastErrorFrequency); + + /* STAT_NUM_CMD_RECEIVED in SEM HK default packet */ + /* STAT_NUM_CMD_EXECUTED in SEM HK default packet */ + /* STAT_NUM_DATA_SENT in SEM HK default packet */ + + CrSemServ3OperationDefaultHkParamGetHkStatNumCmdReceived(&hkStatNumCmdReceived, inPckt); + DEBUGP("hkStatNumCmdReceived: %d\n", hkStatNumCmdReceived); + CrIaPaste(STAT_NUM_CMD_RECEIVED_ID, &hkStatNumCmdReceived); + + CrSemServ3OperationDefaultHkParamGetHkStatNumCmdExecuted(&hkStatNumCmdExecuted, inPckt); + DEBUGP("hkStatNumCmdExecuted: %d\n", hkStatNumCmdExecuted); + CrIaPaste(STAT_NUM_CMD_EXECUTED_ID, &hkStatNumCmdExecuted); + + CrSemServ3OperationDefaultHkParamGetHkStatNumDatSent(&hkStatNumDatSent, inPckt); + DEBUGP("hkStatNumDatSent: %d\n", hkStatNumDatSent); + CrIaPaste(STAT_NUM_DATA_SENT_ID, &hkStatNumDatSent); + + /* STAT_SCU_PROC_DUTY_CL in SEM HK default packet */ + /* STAT_SCU_NUM_AHB_ERR in SEM HK default packet */ + /* STAT_SCU_NUM_AHB_CERR in SEM HK default packet */ + /* STAT_SCU_NUM_LUP_ERR in SEM HK default packet */ + + CrSemServ3OperationDefaultHkParamGetHkStatScuProcDutyCycle(&hkStatScuProcDutyCycle, inPckt); + DEBUGP("hkStatScuProcDutyCycle: %d\n", hkStatScuProcDutyCycle); + CrIaPaste(STAT_SCU_PROC_DUTY_CL_ID, &hkStatScuProcDutyCycle); + + CrSemServ3OperationDefaultHkParamGetHkStatScuNumAhbError(&hkStatScuNumAhbError, inPckt); + DEBUGP("hkStatScuNumAhbError: %d\n", hkStatScuNumAhbError); + CrIaPaste(STAT_SCU_NUM_AHB_ERR_ID, &hkStatScuNumAhbError); + + CrSemServ3OperationDefaultHkParamGetHkStatScuNumAhbCorrectableError(&hkStatScuNumAhbCorrectableError, inPckt); + DEBUGP("hkStatScuNumAhbCorrectableError: %d\n", hkStatScuNumAhbCorrectableError); + CrIaPaste(STAT_SCU_NUM_AHB_CERR_ID, &hkStatScuNumAhbCorrectableError); + + CrSemServ3OperationDefaultHkParamGetHkStatHkNumLatchupError(&hkStatHkNumLatchupError, inPckt); + DEBUGP("hkStatHkNumLatchupError: %d\n", hkStatHkNumLatchupError); + CrIaPaste(STAT_SCU_NUM_LUP_ERR_ID, &hkStatHkNumLatchupError); + + /* TEMP_SEM_SCU in SEM HK default packet */ + CrSemServ3OperationDefaultHkParamGetHkTempSemScu(&hkTempSemScu, inPckt); + DEBUGP("hkTempSemScu: %f\n", hkTempSemScu); + CrIaPaste(TEMP_SEM_SCU_ID, &hkTempSemScu); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(TEMP_SEM_SCU_ID, hkTempSemScu); + warnLimitDefCnt += FdCheckLimit.nmbWarn; + alarmLimitDefCnt += FdCheckLimit.nmbAlarm; + + /* TEMP_SEM_PCU in SEM HK default packet */ + CrSemServ3OperationDefaultHkParamGetHkTempSemPcu(&hkTempSemPcu, inPckt); + DEBUGP("hkTempSemPcu: %f\n", hkTempSemPcu); + CrIaPaste(TEMP_SEM_PCU_ID, &hkTempSemPcu); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(TEMP_SEM_PCU_ID, hkTempSemPcu); + warnLimitDefCnt += FdCheckLimit.nmbWarn; + alarmLimitDefCnt += FdCheckLimit.nmbAlarm; + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* VOLT_SCU_P3_4 in SEM HK default packet */ + CrSemServ3OperationDefaultHkParamGetHkVoltScuP34(&hkVoltScuP34, inPckt); + DEBUGP("hkVoltScuP34: %f\n", hkVoltScuP34); + CrIaPaste(VOLT_SCU_P3_4_ID, &hkVoltScuP34); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_SCU_P3_4_ID, hkVoltScuP34); + warnLimitDefCnt += FdCheckLimit.nmbWarn; + alarmLimitDefCnt += FdCheckLimit.nmbAlarm; + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* VOLT_SCU_P5 in SEM HK default packet */ + CrSemServ3OperationDefaultHkParamGetHkVoltScuP5(&hkVoltScuP5, inPckt); + DEBUGP("hkVoltScuP5: %f\n", hkVoltScuP5); + CrIaPaste(VOLT_SCU_P5_ID, &hkVoltScuP5); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_SCU_P5_ID, hkVoltScuP5); + warnLimitDefCnt += FdCheckLimit.nmbWarn; + alarmLimitDefCnt += FdCheckLimit.nmbAlarm; + + /* FdCheck SEM Limit Check */ + if (warnLimitDefCnt > 0) /* Mantis 2182 */ + { + warnLimitDef[0] = 1; + } + else + { + warnLimitDef[0] = 0; + } + + warnLimitDefCnt = sumWarnLimits(1); /* Default HK */ + DEBUGP("CrSemServ3DatHkUpdateAction() DEF HK - warn (%d), alarm (%d), sum = %d\n", warnLimitDef[0], alarmLimitDefCnt, warnLimitDefCnt); + + } + + if (disc == 2) + { + /* FdCheck SEM Limit Check */ + shiftWarnLimits(0); /* shift warn limits one slot further (Extended HK) */ + shiftSemAliveStatus(0); /* shift SEM Alive FdCheck status one slot further (Extended HK) */ + warnLimitExtCnt = 0; /* reset warn limit counter */ + alarmLimitExtCnt = 0; /* reset alarm limit counter */ + + /* Get FdCheck SEM Alive status */ + sm_state = FwSmGetCurState(smDescFdSemAliveCheck); + if ((sm_state == CrIaFdCheck_DISABLED) || (sm_state == CrIaFdCheck_NOMINAL)) + { + semAliveStatusExt[0] = 0; + } + else + { + semAliveStatusExt[0] = 1; + } + semAliveStatusExtCnt = sumSemAliveStatus(0); + + + /* TEMP_FEE_CCD in SEM HK extended packet */ + /* TEMP_FEE_STRAP in SEM HK extended packet */ + /* TEMP_FEE_ADC in SEM HK extended packet */ + /* TEMP_FEE_BIAS in SEM HK extended packet */ + /* TEMP_FEE_DEB in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkTempFeeCcd(&hkTempFeeCcd, inPckt); + DEBUGP("hkTempFeeCcd: %f\n", hkTempFeeCcd); + CrIaPaste(TEMP_FEE_CCD_ID, &hkTempFeeCcd); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(TEMP_FEE_CCD_ID, hkTempFeeCcd); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkTempFeeStrap(&hkTempFeeStrap, inPckt); + DEBUGP("hkTempFeeStrap: %f\n", hkTempFeeStrap); + CrIaPaste(TEMP_FEE_STRAP_ID, &hkTempFeeStrap); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(TEMP_FEE_STRAP_ID, hkTempFeeStrap); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkTempFeeAdc(&hkTempFeeAdc, inPckt); + DEBUGP("hkTempFeeAdc: %f\n", hkTempFeeAdc); + CrIaPaste(TEMP_FEE_ADC_ID, &hkTempFeeAdc); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(TEMP_FEE_ADC_ID, hkTempFeeAdc); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkTempFeeBias(&hkTempFeeBias, inPckt); + DEBUGP("hkTempFeeBias: %f\n", hkTempFeeBias); + CrIaPaste(TEMP_FEE_BIAS_ID, &hkTempFeeBias); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(TEMP_FEE_BIAS_ID, hkTempFeeBias); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkTempFeeDeb(&hkTempFeeDeb, inPckt); + DEBUGP("hkTempFeeDeb: %f\n", hkTempFeeDeb); + CrIaPaste(TEMP_FEE_DEB_ID, &hkTempFeeDeb); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(TEMP_FEE_DEB_ID, hkTempFeeDeb); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + /* VOLT_FEE_VOD in SEM HK extended packet */ + /* VOLT_FEE_VRD in SEM HK extended packet */ + /* VOLT_FEE_VOG in SEM HK extended packet */ + /* VOLT_FEE_VSS in SEM HK extended packet */ + /* VOLT_FEE_CCD in SEM HK extended packet */ + /* VOLT_FEE_CLK in SEM HK extended packet */ + /* VOLT_FEE_ANA_P5 in SEM HK extended packet */ + /* VOLT_FEE_ANA_N5 in SEM HK extended packet */ + /* VOLT_FEE_DIG_P3_3 in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeVod(&hkVoltFeeVod, inPckt); + DEBUGP("hkVoltFeeVod: %f\n", hkVoltFeeVod); + CrIaPaste(VOLT_FEE_VOD_ID, &hkVoltFeeVod); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_VOD_ID, hkVoltFeeVod); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeVrd(&hkVoltFeeVrd, inPckt); + DEBUGP("hkVoltFeeVrd: %f\n", hkVoltFeeVrd); + CrIaPaste(VOLT_FEE_VRD_ID, &hkVoltFeeVrd); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_VRD_ID, hkVoltFeeVrd); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeVog(&hkVoltFeeVog, inPckt); + DEBUGP("hkVoltFeeVog: %f\n", hkVoltFeeVog); + CrIaPaste(VOLT_FEE_VOG_ID, &hkVoltFeeVog); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_VOG_ID, hkVoltFeeVog); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeVss(&hkVoltFeeVss, inPckt); + DEBUGP("hkVoltFeeVss: %f\n", hkVoltFeeVss); + CrIaPaste(VOLT_FEE_VSS_ID, &hkVoltFeeVss); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_VSS_ID, hkVoltFeeVss); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeCcd(&hkVoltFeeCcd, inPckt); + DEBUGP("hkVoltFeeCcd: %f\n", hkVoltFeeCcd); + CrIaPaste(VOLT_FEE_CCD_ID, &hkVoltFeeCcd); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_CCD_ID, hkVoltFeeCcd); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeClk(&hkVoltFeeClk, inPckt); + DEBUGP("hkVoltFeeClk: %f\n", hkVoltFeeClk); + CrIaPaste(VOLT_FEE_CLK_ID, &hkVoltFeeClk); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_CLK_ID, hkVoltFeeClk); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeAnaP5(&hkVoltFeeAnaP5, inPckt); + DEBUGP("hkVoltFeeAnaP5: %f\n", hkVoltFeeAnaP5); + CrIaPaste(VOLT_FEE_ANA_P5_ID, &hkVoltFeeAnaP5); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_ANA_P5_ID, hkVoltFeeAnaP5); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeAnaN5(&hkVoltFeeAnaN5, inPckt); + DEBUGP("hkVoltFeeAnaN5: %f\n", hkVoltFeeAnaN5); + CrIaPaste(VOLT_FEE_ANA_N5_ID, &hkVoltFeeAnaN5); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_ANA_N5_ID, hkVoltFeeAnaN5); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + CrSemServ3OperationExtendedHkParamGetHkVoltFeeDigP33(&hkVoltFeeDigP33, inPckt); + DEBUGP("hkVoltFeeDigP33: %f\n", hkVoltFeeDigP33); + CrIaPaste(VOLT_FEE_ANA_P3_3_ID, &hkVoltFeeDigP33); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_FEE_ANA_P3_3_ID, hkVoltFeeDigP33); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + /* NOTE: CHANGED in ICD DLR-INST-IC-001, issue 2.1 */ + /* CURR_FEE_CLK_BUF in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkCurrFeeClkBuf(&hkCurrFeeClkBuf, inPckt); + DEBUGP("hkCurrFeeClkBuf: %f\n", hkCurrFeeClkBuf); + CrIaPaste(CURR_FEE_CLK_BUF_ID, &hkCurrFeeClkBuf); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(CURR_FEE_CLK_BUF_ID, hkCurrFeeClkBuf); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + /* VOLT_PCU_P30 in SEM HK extended packet */ + /* VOLT_PCU_P15 in SEM HK extended packet */ + /* VOLT_PCU_P5 in SEM HK extended packet */ + /* VOLT_PCU_N5 in SEM HK extended packet */ + /* VOLT_PCU_P3_4 in SEM HK extended packet */ + /* VOLT_PCU_P7 in SEM HK extended packet */ + + /* NOTE: CHANGED in ICD DLR-INST-IC-001, issue 2.1 + CrSemServ3OperationExtendedHkParamGetHkVoltPcuP30(&hkVoltPcuP30, inPckt); + DEBUGP("hkVoltPcuP30: %f\n", hkVoltPcuP30); + CrIaPaste(VOLT_PCU_P30_ID, &hkVoltPcuP30); + + CrSemServ3OperationExtendedHkParamGetHkVoltPcuP15(&hkVoltPcuP15, inPckt); + DEBUGP("hkVoltPcuP15: %f\n", hkVoltPcuP15); + CrIaPaste(VOLT_PCU_P15_ID, &hkVoltPcuP15); + + CrSemServ3OperationExtendedHkParamGetHkVoltPcuP5(&hkVoltPcuP5, inPckt); + DEBUGP("hkVoltPcuP5: %f\n", hkVoltPcuP5); + CrIaPaste(VOLT_PCU_P5_ID, &hkVoltPcuP5); + + CrSemServ3OperationExtendedHkParamGetHkVoltPcuN5(&hkVoltPcuN5, inPckt); + DEBUGP("hkVoltPcuN5: %f\n", hkVoltPcuN5); + CrIaPaste(VOLT_PCU_N5_ID, &hkVoltPcuN5); + + CrSemServ3OperationExtendedHkParamGetHkVoltPcuP34(&hkVoltPcuP34, inPckt); + DEBUGP("hkVoltPcuP34: %f\n", hkVoltPcuP34); + CrIaPaste(VOLT_PCU_P3_4_ID, &hkVoltPcuP34); + + CrSemServ3OperationExtendedHkParamGetHkVoltPcuP7(&hkVoltPcuP7, inPckt); + DEBUGP("hkVoltPcuP7: %f\n", hkVoltPcuP7); + CrIaPaste(VOLT_PCU_P7_ID, &hkVoltPcuP7); + */ + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* VOLT_SCU_FPGA_P1_5 in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkVoltScuFpgaP15(&hkVoltScuFpgaP15, inPckt); + DEBUGP("hkVoltScuFpgaP15: %f\n", hkVoltScuFpgaP15); + CrIaPaste(VOLT_SCU_FPGA_P1_5_ID, &hkVoltScuFpgaP15); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(VOLT_SCU_FPGA_P1_5_ID, hkVoltScuFpgaP15); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* CURR_SCU_P3_4 in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkCurrScuP34(&hkCurrScuP34, inPckt); + DEBUGP("hkCurrScuP34: %f\n", hkCurrScuP34); + CrIaPaste(CURR_SCU_P3_4_ID, &hkCurrScuP34); + /* Monitored by FdCheck SEM Limit Check */ + FdCheckLimit = checkFloatSemLimit(CURR_SCU_P3_4_ID, hkCurrScuP34); + warnLimitExtCnt += FdCheckLimit.nmbWarn; + alarmLimitExtCnt += FdCheckLimit.nmbAlarm; + + /* STAT_NUM_SPW_ERR_CRE in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_ESC in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_DISC in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_PAR in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_WRSY in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_INVA in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_EOP in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_RXAH in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_TXAH in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_TXBL in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrCredit(&hkStatNumSpwErrCredit, inPckt); + DEBUGP("hkStatNumSpwErrCredit: %d\n", hkStatNumSpwErrCredit); + CrIaPaste(STAT_NUM_SPW_ERR_CRE_ID, &hkStatNumSpwErrCredit); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrEscape(&hkStatNumSpwErrEscape, inPckt); + DEBUGP("hkStatNumSpwErrEscape: %d\n", hkStatNumSpwErrEscape); + CrIaPaste(STAT_NUM_SPW_ERR_ESC_ID, &hkStatNumSpwErrEscape); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrDisconnect(&hkStatNumSpwErrDisconnect, inPckt); + DEBUGP("hkStatNumSpwErrDisconnect: %d\n", hkStatNumSpwErrDisconnect); + CrIaPaste(STAT_NUM_SPW_ERR_DISC_ID, &hkStatNumSpwErrDisconnect); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrParity(&hkStatNumSpwErrParity, inPckt); + DEBUGP("hkStatNumSpwErrParity: %d\n", hkStatNumSpwErrParity); + CrIaPaste(STAT_NUM_SPW_ERR_PAR_ID, &hkStatNumSpwErrParity); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrWriteSync(&hkStatNumSpwErrWriteSync, inPckt); + DEBUGP("hkStatNumSpwErrWriteSync: %d\n", hkStatNumSpwErrWriteSync); + CrIaPaste(STAT_NUM_SPW_ERR_WRSY_ID, &hkStatNumSpwErrWriteSync); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrInvalidAddress(&hkStatNumSpwErrInvalidAddress, inPckt); + DEBUGP("hkStatNumSpwErrInvalidAddress: %d\n", hkStatNumSpwErrInvalidAddress); + CrIaPaste(STAT_NUM_SPW_ERR_INVA_ID, &hkStatNumSpwErrInvalidAddress); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrEopeep(&hkStatNumSpwErrEopeep, inPckt); + DEBUGP("hkStatNumSpwErrEopeep: %d\n", hkStatNumSpwErrEopeep); + CrIaPaste(STAT_NUM_SPW_ERR_EOP_ID, &hkStatNumSpwErrEopeep); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrRxAhb(&hkStatNumSpwErrRxAhb, inPckt); + DEBUGP("hkStatNumSpwErrRxAhb: %d\n", hkStatNumSpwErrRxAhb); + CrIaPaste(STAT_NUM_SPW_ERR_RXAH_ID, &hkStatNumSpwErrRxAhb); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxAhb(&hkStatNumSpwErrTxAhb, inPckt); + DEBUGP("hkStatNumSpwErrTxAhb: %d\n", hkStatNumSpwErrTxAhb); + CrIaPaste(STAT_NUM_SPW_ERR_TXAH_ID, &hkStatNumSpwErrTxAhb); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxBlocked(&hkStatNumSpwErrTxBlocked, inPckt); + DEBUGP("hkStatNumSpwErrTxBlocked: %d\n", hkStatNumSpwErrTxBlocked); + CrIaPaste(STAT_NUM_SPW_ERR_TXBL_ID, &hkStatNumSpwErrTxBlocked); + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* STAT_NUM_SPW_ERR_TXLE in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_RX in SEM HK extended packet */ + /* STAT_NUM_SPW_ERR_TX in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxle(&hkStatNumSpwErrTxle, inPckt); + DEBUGP("hkStatNumSpwErrTxle: %d\n", hkStatNumSpwErrTxle); + CrIaPaste(STAT_NUM_SPW_ERR_TXLE_ID, &hkStatNumSpwErrTxle); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrRx(&hkStatNumSpwErrRx, inPckt); + DEBUGP("hkStatNumSpwErrRx: %d\n", hkStatNumSpwErrRx); + CrIaPaste(STAT_NUM_SP_ERR_RX_ID, &hkStatNumSpwErrRx); + + CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTx(&hkStatNumSpwErrTx, inPckt); + DEBUGP("hkStatNumSpwErrTx: %d\n", hkStatNumSpwErrTx); + CrIaPaste(STAT_NUM_SP_ERR_TX_ID, &hkStatNumSpwErrTx); + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* STAT_HEAT_PWM_FPA_CCD in SEM HK extended packet */ + /* STAT_HEAT_PWM_FEE_STRAP in SEM HK extended packet */ + /* STAT_HEAT_PWM_FEE_ANACH in SEM HK extended packet */ + /* STAT_HEAT_PWM_SPARE in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFpaCcd(&hkStatHeatPwmFpaCcd, inPckt); + DEBUGP("hkStatHeatPwmFpaCcd: %d\n", hkStatHeatPwmFpaCcd); + CrIaPaste(STAT_HEAT_PWM_FPA_CCD_ID, &hkStatHeatPwmFpaCcd); + + CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFeeStrap(&hkStatHeatPwmFeeStrap, inPckt); + DEBUGP("hkStatHeatPwmFeeStrap: %d\n", hkStatHeatPwmFeeStrap); + CrIaPaste(STAT_HEAT_PWM_FEE_STR_ID, &hkStatHeatPwmFeeStrap); + + CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFeeAnach(&hkStatHeatPwmFeeAnach, inPckt); + DEBUGP("hkStatHeatPwmFeeAnach: %d\n", hkStatHeatPwmFeeAnach); + CrIaPaste(STAT_HEAT_PWM_FEE_ANA_ID, &hkStatHeatPwmFeeAnach); + + CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmSpare(&hkStatHeatPwmSpare, inPckt); + DEBUGP("hkStatHeatPwmSpare: %d\n", hkStatHeatPwmSpare); + CrIaPaste(STAT_HEAT_PWM_SPARE_ID, &hkStatHeatPwmSpare); + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* STAT_BITS in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkStatBits(&hkStatBits, inPckt); + DEBUGP("hkStatBits: %d\n", hkStatBits); + CrIaPaste(STAT_HEAT_PWM_FLAGS_ID, &hkStatBits); + + /* ### STAT_BITS ### */ + + /* STAT_HEAT_POW_FPA_CCD in SEM HK extended packet */ + /* STAT_HEAT_POW_FEE_STRAP in SEM HK extended packet */ + /* STAT_HEAT_POW_FEE_ANACH in SEM HK extended packet */ + /* STAT_HEAT_POW_SPARE in SEM HK extended packet */ + + /* ####################### */ + + + /* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ + /* STAT_OBTIME_SYNC_DELTA in SEM HK extended packet */ + + CrSemServ3OperationExtendedHkParamGetHkStatOBTimeSyncDelta(&hkStatOBTimeSyncDelta, inPckt); + DEBUGP("hkStatOBTimeSyncDelta: %d\n", hkStatOBTimeSyncDelta); + CrIaPaste(STAT_OBTIME_SYNC_DELTA_ID, &hkStatOBTimeSyncDelta); + + /* FdCheck SEM Limit Check */ + if (warnLimitExtCnt > 0) /* Mantis 2182 */ + { + warnLimitExt[0] = 1; + } + else + { + warnLimitExt[0] = 0; + } + + warnLimitExtCnt = sumWarnLimits(0); /* Extended HK */ + DEBUGP("CrSemServ3DatHkUpdateAction() EXT HK - warn (%d), alarm (%d), sum = %d\n", warnLimitExt[0], alarmLimitExtCnt, warnLimitExtCnt); + + } + + inData->outcome = 1; + + return; + +} + diff --git a/CrIa/src/Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.h b/CrIa/src/Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.h new file mode 100644 index 0000000000000000000000000000000000000000..559db3fb5738412d058629a8c73e1a5ad6425ca7 --- /dev/null +++ b/CrIa/src/Services/CrSemServ3HousekeepingDataReportingService/InRep/CrSemServ3DatHk.h @@ -0,0 +1,38 @@ +/** + * @file CrSemServ3DatHk.h + * + * Declaration of the DAT HK in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV3_DAT_HK_H +#define CRSEM_SERV3_DAT_HK_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + + +void ClearWarnLimit (void); + +void ClearAliveLimit (void); + + +/** + * Validity check of the DAT HK in-coming report packet. + * Compute the CRC for the report and returns true if the CRC is correct and false otherwise. + * @param smDesc the state machine descriptor + * @return the validity check result + */ +CrFwBool_t CrSemServ3DatHkValidityCheck(FwPrDesc_t prDesc); + +/** + * Update action of the DAT HK in-coming report packet. + * The Update Action of incoming service 3 reports shall run the SEM HK Update Procedure. + * @param prDesc the procedure descriptor + */ +void CrSemServ3DatHkUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV3_DAT_HK_H */ + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrHighSev.c b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrHighSev.c new file mode 100644 index 0000000000000000000000000000000000000000..abcadf2f936ace44d7d13d305dffc173ba2d9822 --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrHighSev.c @@ -0,0 +1,103 @@ +/** + * @file CrSemServ5EvtErrHighSev.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Event Error Report - High Severity in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ5EvtErrHighSev.h" + +#include "../../../IfswDebug.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrSemParamGetter.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> + +/* send function in the 5,1 forward */ +#include <OutStream/CrFwOutStream.h> + +#include <CrIaPrSm/CrIaFdCheckCreate.h> /* for CrIaFdCheck_DISABLED */ + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +extern unsigned short SemAnoEvtId; /* used for FdCheck SEM Anomaly Event */ + + +/** + * @brief Update action of the Service 5 SEM DAT Event Error Report - High Severity in-coming report + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Push event report onto SEM Event Store + * if forwarding of SEM event report is enabled: + * - Forward event report to Ground + * + * @param[in] prDesc procedure descriptor + * @param[out] none + */ +void CrSemServ5EvtErrHighSevUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char semS54flag; + unsigned short hkEventProgId; + unsigned int semEvtCnt; + + /* The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. */ + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Get InRep eventId */ + CrSemServ5EvtErrHighSevParamGetHkEventProgId(&hkEventProgId, inPckt); + DEBUGP("Event ID: %d\n", hkEventProgId); + + if (FwSmGetCurState(smDescFdSemAnomalyEventCheck) != CrIaFdCheck_DISABLED) + { + SemAnoEvtId = getSemAnoEvtId(hkEventProgId); + } + + /* Increment the SEM Event Counter (Mantis 1764) */ + CrIaCopy(SEMEVTCOUNTER_ID, &semEvtCnt); + semEvtCnt++; + CrIaPaste(SEMEVTCOUNTER_ID, &semEvtCnt); + + /* Check, if SEM_SERV5_4_FORWARD is enabled */ + CrIaCopy(SEM_SERV5_4_FORWARD_ID, &semS54flag); + DEBUGP("semS54flag: %d\n", semS54flag); + if (semS54flag==1) + { + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + return; +} + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrHighSev.h b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrHighSev.h new file mode 100644 index 0000000000000000000000000000000000000000..a8d0e242df3888f6c09f4be1760302a590d63d98 --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrHighSev.h @@ -0,0 +1,32 @@ +/** + * @file CrSemServ5EvtErrHighSev.h + * + * Declaration of the Error Report - High Severity in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV5_EVT_ERR_HIGH_SEV_H +#define CRSEM_SERV5_EVT_ERR_HIGH_SEV_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + +/** + * Validity check of the Error Report - High Severity in-coming report packet. + * Compute the CRC for the report and returns true if the CRC is correct and false otherwise. + * @param smDesc the state machine descriptor + * @return the validity check result + */ +CrFwBool_t CrSemServ5EvtErrHighSevValidityCheck(FwPrDesc_t prDesc); + +/** + * Update action of the Error Report - High Severity in-coming report packet. + * The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. + * @param prDesc the procedure descriptor + */ +void CrSemServ5EvtErrHighSevUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV5_EVT_ERR_HIGH_SEV_H */ + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrLowSev.c b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrLowSev.c new file mode 100644 index 0000000000000000000000000000000000000000..ea63e9ae21e30732e30d5baaa0b332beb74e8fc8 --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrLowSev.c @@ -0,0 +1,103 @@ +/** + * @file CrSemServ5EvtErrLowSev.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Event Error Report - Low Severity in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ5EvtErrLowSev.h" + +#include "../../../IfswDebug.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrSemParamGetter.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> + +/* send function in the 5,1 forward */ +#include <OutStream/CrFwOutStream.h> + +#include <CrIaPrSm/CrIaFdCheckCreate.h> /* for CrIaFdCheck_DISABLED */ + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +extern unsigned short SemAnoEvtId; /* used for FdCheck SEM Anomaly Event */ + + +/** + * @brief Update action of the Service 5 SEM DAT Event Error Report - Low Severity in-coming report + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Push event report onto SEM Event Store + * if forwarding of SEM event report is enabled: + * - Forward event report to Ground + * + * @param[in] prDesc procedure descriptor + * @param[out] none + */ +void CrSemServ5EvtErrLowSevUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char semS52flag; + unsigned short hkEventProgId; + unsigned int semEvtCnt; + + /* The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. */ + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Get InRep eventId */ + CrSemServ5EvtErrLowSevParamGetHkEventProgId(&hkEventProgId, inPckt); + DEBUGP("Event ID: %d\n", hkEventProgId); + + if (FwSmGetCurState(smDescFdSemAnomalyEventCheck) != CrIaFdCheck_DISABLED) + { + SemAnoEvtId = getSemAnoEvtId(hkEventProgId); + } + + /* Increment the SEM Event Counter (Mantis 1764) */ + CrIaCopy(SEMEVTCOUNTER_ID, &semEvtCnt); + semEvtCnt++; + CrIaPaste(SEMEVTCOUNTER_ID, &semEvtCnt); + + /* Check, if SEM_SERV5_2_FORWARD is enabled */ + CrIaCopy(SEM_SERV5_2_FORWARD_ID, &semS52flag); + DEBUGP("semS52flag: %d\n", semS52flag); + if (semS52flag==1) + { + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + return; +} + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrLowSev.h b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrLowSev.h new file mode 100644 index 0000000000000000000000000000000000000000..a70a82a839b9afe1028bff5038fe857c42f70949 --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrLowSev.h @@ -0,0 +1,32 @@ +/** + * @file CrSemServ5EvtErrLowSev.h + * + * Declaration of the Error Report - Low Severity in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV5_EVT_ERR_LOW_SEV_H +#define CRSEM_SERV5_EVT_ERR_LOW_SEV_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + +/** + * Validity check of the Error Report - Low Severity in-coming report packet. + * Compute the CRC for the report and returns true if the CRC is correct and false otherwise. + * @param smDesc the state machine descriptor + * @return the validity check result + */ +CrFwBool_t CrSemServ5EvtErrLowSevValidityCheck(FwPrDesc_t prDesc); + +/** + * Update action of the Error Report - Low Severity in-coming report packet. + * The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. + * @param prDesc the procedure descriptor + */ +void CrSemServ5EvtErrLowSevUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV5_EVT_ERR_LOW_SEV_H */ + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrMedSev.c b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrMedSev.c new file mode 100644 index 0000000000000000000000000000000000000000..47d0f88488668b891409e23628a6bf810cfeba6a --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrMedSev.c @@ -0,0 +1,103 @@ +/** + * @file CrSemServ5EvtErrMedSev.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM DAT Event Error Report - Medium Severity in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ5EvtErrMedSev.h" + +#include "../../../IfswDebug.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrSemParamGetter.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> + +/* send function in the 5,1 forward */ +#include <OutStream/CrFwOutStream.h> + +#include <CrIaPrSm/CrIaFdCheckCreate.h> /* for CrIaFdCheck_DISABLED */ + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +extern unsigned short SemAnoEvtId; /* used for FdCheck SEM Anomaly Event */ + + +/** + * @brief Update action of the Service 5 SEM DAT Event Error Report - Medium Severity in-coming report + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Push event report onto SEM Event Store + * if forwarding of SEM event report is enabled: + * - Forward event report to Ground + * + * @param[in] prDesc procedure descriptor + * @param[out] none + */ +void CrSemServ5EvtErrMedSevUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char semS53flag; + unsigned short hkEventProgId; + unsigned int semEvtCnt; + + /* The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. */ + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Get InRep eventId */ + CrSemServ5EvtErrMedSevParamGetHkEventProgId(&hkEventProgId, inPckt); + DEBUGP("Event ID: %d\n", hkEventProgId); + + if (FwSmGetCurState(smDescFdSemAnomalyEventCheck) != CrIaFdCheck_DISABLED) + { + SemAnoEvtId = getSemAnoEvtId(hkEventProgId); + } + + /* Increment the SEM Event Counter (Mantis 1764) */ + CrIaCopy(SEMEVTCOUNTER_ID, &semEvtCnt); + semEvtCnt++; + CrIaPaste(SEMEVTCOUNTER_ID, &semEvtCnt); + + /* Check, if SEM_SERV5_3_FORWARD is enabled */ + CrIaCopy(SEM_SERV5_3_FORWARD_ID, &semS53flag); + DEBUGP("semS53flag: %d\n", semS53flag); + if (semS53flag==1) + { + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + return; +} + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrMedSev.h b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrMedSev.h new file mode 100644 index 0000000000000000000000000000000000000000..1fb4f14007d153af636e4f9111d3cbc6a09d1de7 --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtErrMedSev.h @@ -0,0 +1,32 @@ +/** + * @file CrSemServ5EvtErrMedSev.h + * + * Declaration of the Error Report - Medium Severity in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV5_EVT_ERR_MED_SEV_H +#define CRSEM_SERV5_EVT_ERR_MED_SEV_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + +/** + * Validity check of the Error Report - Medium Severity in-coming report packet. + * Compute the CRC for the report and returns true if the CRC is correct and false otherwise. + * @param smDesc the state machine descriptor + * @return the validity check result + */ +CrFwBool_t CrSemServ5EvtErrMedSevValidityCheck(FwPrDesc_t prDesc); + +/** + * Update action of the Error Report - Medium Severity in-coming report packet. + * The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. + * @param prDesc the procedure descriptor + */ +void CrSemServ5EvtErrMedSevUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV5_EVT_ERR_MED_SEV_H */ + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtNorm.c b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtNorm.c new file mode 100644 index 0000000000000000000000000000000000000000..a900b30f521823ba1df642e23caf64489b002772 --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtNorm.c @@ -0,0 +1,228 @@ +/** + * @file CrSemServ5EvtNorm.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM Event Normal/Progress Report in-coming report packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ5EvtNorm.h" + +#include "../../../IfswDebug.h" + +#include <FwProfile/FwPrConfig.h> +#include <FwProfile/FwSmConfig.h> +#include <Services/General/CrIaParamSetter.h> +#include <Services/General/CrIaParamGetter.h> +#include <Services/General/CrSemParamGetter.h> +#include <Services/General/CrSemConstants.h> + +#include <CrIaIasw.h> +#include <CrIaInCmp.h> +/*#include <CrIaPrSm/CrIaSemCreate.h> */ +#include <CrFwCmpData.h> +#include <IfswUtilities.h> +#include <CrIaPckt.h> +#include <byteorder.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <CrIaSemEvents.h> + +/* send function in the 5,1 forward */ +#include <OutStream/CrFwOutStream.h> + +/* imported globals */ +extern unsigned short SemTransition; +extern CrFwBool_t signalSemStateStandby; +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_SET; /* needed for FdCheck SAFE Mode */ +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_FD_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STAB_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDWIN_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDFULL_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_DIAG_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_INIT_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_FD_SET; /* needed for FdCheck SEM Mode Time-Out */ +unsigned char CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_FD_SET; /* needed for FdCheck SEM Mode Time-Out */ + + +/** + * @brief Update action of the Service 5 SEM Event Normal/Progress Report in-coming report + * + * @note The implementation is not realized using the described framework procedure in the specification document CHEOPS-PNP-INST-RS-001. + * + * Following steps are executed: + * - Push event report onto SEM Event Store + * - Set event flag according to event ProgID + * if forwarding of SEM event report is enabled: + * - Forward event report to Ground + * + * @param[in] prDesc procedure descriptor + * @param[out] none + */ +void CrSemServ5EvtNormUpdateAction(FwPrDesc_t prDesc) +{ + CrFwCmpData_t* inData; + CrFwInRepData_t* inSpecificData; + CrFwPckt_t inPckt; + unsigned char semS51flag; + unsigned short hkEventProgId; + unsigned int semEvtCnt; + + /* The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. */ + + /* Get in packet */ + inData = (CrFwCmpData_t*)FwPrGetData(prDesc); + inSpecificData = (CrFwInRepData_t*)(inData->cmpSpecificData); + inPckt = inSpecificData->pckt; + + /* Get InRep eventId */ + CrSemServ5EvtNormParamGetHkEventProgId(&hkEventProgId, inPckt); + DEBUGP("Event ID: %d\n", hkEventProgId); + + /* Set event flag according to ID */ + if (hkEventProgId == CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY) + CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY) + CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION) + { + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_SET = 1; + /* NOTE: there can only be up to a single pending mode transition at any given time */ + CrSemServ5EventPrgModeTransitionParamGetHkStatCurrentMode(&SemTransition, inPckt); + /* set flag, if SEM signals entry in SAFE mode; used for FdCheck SEM Mode Time-Out and FdCheck SAFE Mode */ + if (SemTransition == SEM_STATE_SAFE) + { + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_SET = 1; + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_SAFE_FD_SET = 1; + } + /* set flag, if SEM signals entry in STABILIZE mode; used for FdCheck SEM Mode Time-Out */ + if (SemTransition == SEM_STATE_STABILIZE) + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STAB_SET = 1; + /* set flag, if SEM signals entry in CCD WINDOW mode; used for FdCheck SEM Mode Time-Out */ + if ((SemTransition == SEM_STATE_SC_STAR_FAINT) || (SemTransition == SEM_STATE_SC_STAR_BRIGHT) || (SemTransition == SEM_STATE_SC_STAR_ULTBRT)) + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDWIN_SET = 1; + /* set flag, if SEM signals entry in CCD FULL mode; used for FdCheck SEM Mode Time-Out */ + if (SemTransition == SEM_STATE_CCD_FULL) + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_CCDFULL_SET = 1; + /* set flag, if SEM signals entry in DIAGNOSTIC mode; used for FdCheck SEM Mode Time-Out */ + if (SemTransition == SEM_STATE_DIAGNOSTIC) + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_DIAG_SET = 1; + /* set flag, if SEM signals entry in STANDBY mode; used for FdCheck SEM Mode Time-Out */ + if (SemTransition == SEM_STATE_STANDBY && signalSemStateStandby) + { + CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_TO_STANDBY_SET = 1; + } + else + { + signalSemStateStandby = 1; + } + } + if (hkEventProgId == CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED) + CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY) + { + CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_SET = 1; + /* set flag, if DAT_Event_Progress(TempStable) from SEM is received; used for FdCheck SEM Mode Time-Out */ + CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_FD_SET = 1; + } + if (hkEventProgId == CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY) + { + CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_SET = 1; + /* set flag, if DAT_Event_Progress(CFGLoadReady) from SEM is received; used for FdCheck SEM Mode Time-Out */ + CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_FD_SET = 1; + } + if (hkEventProgId == CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL) + CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT) + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE) + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG) + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG) + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG) + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG) + CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY) + CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH) + CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME) + CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD) + CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_WAR_PATTER) + CRSEM_SERV5_EVENT_WAR_FPM_OFF_ONLY_PATTERN_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_WAR_PACKWR) + CRSEM_SERV5_EVENT_WAR_PACK_ENCODE_FAILURE_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR) + CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE) + CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT) + CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE) + CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR) + CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT) + CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG) + CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG) + CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED) + CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL) + CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL) + CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_ERR_DAT_DMA) + CRSEM_SERV5_EVENT_ERR_DMA_DATA_TRANSF_FAIL_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_ERR_BIAS_SET) + CRSEM_SERV5_EVENT_ERR_DATA_BIAS_VOLT_WRONG_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_ERR_SYNC) + CRSEM_SERV5_EVENT_ERR_FEESCU_SYNC_FAIL_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_ERR_SCRIPT) + CRSEM_SERV5_EVENT_ERR_FEE_SCRIPT_ERROR_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_ERR_PWR) + CRSEM_SERV5_EVENT_ERR_SCU_POWER_SWITCH_FAIL_SET = 1; + if (hkEventProgId == CRSEM_SERV5_EVT_ERR_SPW_TC) + CRSEM_SERV5_EVENT_ERR_SPW_TIME_CODE_MISS_SET = 1; + + /* Increment the SEM Event Counter (Mantis 1764) */ + CrIaCopy(SEMEVTCOUNTER_ID, &semEvtCnt); + semEvtCnt++; + CrIaPaste(SEMEVTCOUNTER_ID, &semEvtCnt); + + /* Check SEM_SERV5_1_FORWARD */ + CrIaCopy(SEM_SERV5_1_FORWARD_ID, &semS51flag); + DEBUGP("semS51flag: %d\n", semS51flag); + + if (semS51flag==1) + { + CrFwOutStreamSend (outStreamGrd, inPckt); + } + else + { + DEBUGP("No packet sent!\n"); + } + + return; +} + diff --git a/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtNorm.h b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtNorm.h new file mode 100644 index 0000000000000000000000000000000000000000..3cdcc60518a77c259c38c9b9f725326d7bacdb1b --- /dev/null +++ b/CrIa/src/Services/CrSemServ5EventReportingService/InRep/CrSemServ5EvtNorm.h @@ -0,0 +1,32 @@ +/** + * @file CrSemServ5EvtNorm.h + * + * Declaration of the Normal/Progress Report in-coming report packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV5_EVT_NORM_H +#define CRSEM_SERV5_EVT_NORM_H + +#include "FwProfile/FwSmCore.h" +#include "CrFwConstants.h" + +/** + * Validity check of the Normal/Progress Report in-coming report packet. + * Compute the CRC for the report and returns true if the CRC is correct and false otherwise. + * @param smDesc the state machine descriptor + * @return the validity check result + */ +CrFwBool_t CrSemServ5EvtNormValidityCheck(FwPrDesc_t prDesc); + +/** + * Update action of the Normal/Progress Report in-coming report packet. + * The Update Action of incoming service 5 reports shall run the SEM Event Update Procedure. + * @param prDesc the procedure descriptor + */ +void CrSemServ5EvtNormUpdateAction(FwPrDesc_t prDesc); + +#endif /* CRSEM_SERV5_EVT_NORM_H */ + diff --git a/CrIa/src/Services/CrSemServ9HousekeepingDataReportingService/OutCmd/CrSemServ9CmdTimeUpdate.c b/CrIa/src/Services/CrSemServ9HousekeepingDataReportingService/OutCmd/CrSemServ9CmdTimeUpdate.c new file mode 100644 index 0000000000000000000000000000000000000000..e84f43875b6a796a5e530517fff789df605957e1 --- /dev/null +++ b/CrIa/src/Services/CrSemServ9HousekeepingDataReportingService/OutCmd/CrSemServ9CmdTimeUpdate.c @@ -0,0 +1,97 @@ +/** + * @file CrSemServ9CmdTimeUpdate.c + * @ingroup CrIaServicesSem + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the SEM CMD Time Update out-going command packet. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemServ9CmdTimeUpdate.h" + +#include <Services/General/CrSemParamSetter.h> + +#include <CrIaPrSm/CrIaSemCreate.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include "../../../IfswDebug.h" + +#if(__sparc__) +#include <ibsw_interface.h> +#else +#include <CrIaIasw.h> +#endif + + +CrFwBool_t CrSemServ9CmdTimeUpdateEnableCheck(FwSmDesc_t smDesc) +{ + unsigned short smState; + + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + + /* isEnabled is true if the SEM Unit State Machine is in state OPER or in state SAFE */ + + smState = FwSmGetCurState(smDescSem); + + if ((smState != CrIaSem_OPER) && (smState != CrIaSem_SAFE)) + { + return 0; + } + else + { + return 1; + } +} + +CrFwBool_t CrSemServ9CmdTimeUpdateReadyCheck(FwSmDesc_t smDesc) +{ + unsigned int cnt; + + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + + /* Query Basic Software to check if it is ready to accept a request to generate a TimeCode to the SEM and set isReady to TRUE when readiness is confirmed */ + + cnt = CrIbGetNotifyCnt(); + + if (cnt != 1) + { + return 0; + } + else + { + return 1; + } +} + +CrFwBool_t CrSemServ9CmdTimeUpdateRepeatCheck(FwSmDesc_t smDesc) +{ + CRFW_UNUSED(smDesc); /* remove if smDesc is used in this function */ + + return 1; +} + +void CrSemServ9CmdTimeUpdateUpdateAction(FwSmDesc_t smDesc) +{ + CrFwTimeStamp_t time; + + /* Collect from the Basic Software the time at which the TimeCode will be generated */ + + /* Here we send the time command and enable the SpW time code signal */ + time = CrIbGetNextTime(); + + CrSemServ9CmdTimeUpdateParamSetParObtSyncTime(smDesc, (const unsigned char *) time.t); + + return; +} + diff --git a/CrIa/src/Services/CrSemServ9HousekeepingDataReportingService/OutCmd/CrSemServ9CmdTimeUpdate.h b/CrIa/src/Services/CrSemServ9HousekeepingDataReportingService/OutCmd/CrSemServ9CmdTimeUpdate.h new file mode 100644 index 0000000000000000000000000000000000000000..2dfe15a94a8a6498fbbd76920b6cd5061f77fb04 --- /dev/null +++ b/CrIa/src/Services/CrSemServ9HousekeepingDataReportingService/OutCmd/CrSemServ9CmdTimeUpdate.h @@ -0,0 +1,48 @@ +/** + * @file CrSemServ9CmdTimeUpdate.h + * + * Declaration of the CMD Time Update out-going command packet. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_SERV9_CMD_TIME_UPDATE_H +#define CRSEM_SERV9_CMD_TIME_UPDATE_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Enable check of the CMD Time Update telemetry packet. + * isEnabled is true if the SEM Unit State Machine is in state OPER or in state SAFE + * @param smDesc the state machine descriptor + * @return the enable check result + */ +CrFwBool_t CrSemServ9CmdTimeUpdateEnableCheck(FwSmDesc_t smDesc); + +/** + * Ready check of the CMD Time Update telemetry packet. + * Query Basic Software to check if it is ready to accept a request to generate a TimeCode to the SEM and set isReady to TRUE when readiness is confirmed + * @param smDesc the state machine descriptor + * @return the ready check result + */ +CrFwBool_t CrSemServ9CmdTimeUpdateReadyCheck(FwSmDesc_t smDesc); + +/** + * Repeat check of the CMD Time Update telemetry packet. + * Set isRepeat to TRUE for as long as the IBSW is not ready to accept a request to generate TimeCode + * @param smDesc the state machine descriptor + * @return the repeat check result + */ +CrFwBool_t CrSemServ9CmdTimeUpdateRepeatCheck(FwSmDesc_t smDesc); + +/** + * Update action of the CMD Time Update telemetry packet. + * Collect from the Basic Software the time at which the TimeCode will be generated + * @param smDesc the state machine descriptor + */ +void CrSemServ9CmdTimeUpdateUpdateAction(FwSmDesc_t smDesc); + +#endif /* CRSEM_SERV9_CMD_TIME_UPDATE_H */ + diff --git a/CrIa/src/Services/General/CrIaConstants.h b/CrIa/src/Services/General/CrIaConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..8c5b712c5e1b00bd45442c5a28fa186efc1ad4d3 --- /dev/null +++ b/CrIa/src/Services/General/CrIaConstants.h @@ -0,0 +1,1581 @@ +/** + * @file CrIaConstants.h + * @ingroup CrIaServicesGeneral + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Header file to define all service and packet identifiers, and packet length. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef CRIA_CONSTANTS_H +#define CRIA_CONSTANTS_H + +#define PR_STOPPED 0 +#define PR_STARTED 1 + +#define PR_SUCCESS 1 +#define PR_FAILURE 0 + +#define FULL_SIZE_X 1076 +#define FULL_SIZE_Y 1033 + +/* Selection of Centroidings */ +#define NO_CENT 1 +#define DEF_CENT 2 +#define DUM_CENT 3 + +/* AlgoId */ +#define SAA_EVAL_ALGO 1 +#define CLCT_ALGO 3 +#define ACQ1_ALGO 4 +#define CNT1_ALGO 5 +#define SDS_EVAL_ALGO 6 +#define TTC1_ALGO 8 +#define TTC2_ALGO 9 +#define CENT0_ALGO 11 + +/* FdCheckId */ +#define FDC_TS_TEMP 1 +#define FDC_ILL_CNT 2 +#define FDC_SEM_COMM 3 +#define FDC_SEM_TO 4 +#define FDC_SEM_SM 5 +#define FDC_SEM_ALIVE 6 +#define FDC_EVT1 7 +#define FDC_EVT2 8 +#define FDC_SEM_OOL 9 +#define FDC_PSDU_OOL 10 +#define FDC_CENT_CONS 11 +#define FDC_RES 12 +#define FDC_SEM_CONS 13 + +/* Recovery Procedure Identifier */ +#define REP_SEM_OFF 1 +#define REP_TERM_SCI 3 +#define REP_STOP_HB 4 +#define REP_SEM_AE 5 + +/* Response Type for FdCheck SEM Anomaly Check */ +#define SEMANOEVT_NO_ACT 1 +#define SEMANOEVT_SEM_OFF 2 +#define SEMANOEVT_SCI_OFF 3 + +/* AcqAlgoId */ +#define ACQALGOID_NOMINAL 100 +#define ACQALGOID_CROWDED_FAINT 101 +#define ACQALGOID_CROWDED_BRIGHT 102 +#define ACQALGOID_SPARSE_FAINT 103 +#define ACQALGOID_SPARSE_BRIGHT 104 +#define ACQALGOID_PATTERN 105 +#define ACQALGOID_ROBUST 106 +#define ACQALGOID_SINGLE 107 +#define ACQALGOID_DOUBLE 108 +#define ACQALGOID_DUMMY 109 + +/* SaveImages pSaveTarget */ +#define SAVETARGET_GROUND 0 +#define SAVETARGET_FLASH 1 + +/* Service 13 constants */ +#define S13_MAX_BLOCK_SIZE 1001 +#define S13_MIN_BLOCK_SIZE 200 +#define S13_OVERHEAD 23 /* 16 + 5 + 2 Bytes overhead for the S13 packet */ + + +/** + * The maximal packet length. + */ +#define CR_MAX_SIZE_PCKT_LARGE 1024 + +/** + * The length offset for the out-going report. + */ +#define OFFSET_PAR_LENGTH_OUT_REP_PCKT 16 + +/** + * The length offset for the in-coming command. + */ +#define OFFSET_PAR_LENGTH_IN_CMD_PCKT 10 + +/** + * The length of CRC. + */ +#define CRC_LENGTH 2 + +/** + * Type identifier of the Command Verification Service. + */ +#define CRIA_SERV1 1 + +/** + * Type identifier of the Housekeeping Data Reporting Service. + */ +#define CRIA_SERV3 3 + +/** + * Type identifier of the Event Reporting Service. + */ +#define CRIA_SERV5 5 + +/** + * Type identifier of the Memory Management Service. + */ +#define CRIA_SERV6 6 + +/** + * Type identifier of the Large Data Transfer Service. + */ +#define CRIA_SERV13 13 + +/** + * Type identifier of the Test Service. + */ +#define CRIA_SERV17 17 + +/** + * Type identifier of the FDIR Service. + */ +#define CRIA_SERV191 191 + +/** + * Type identifier of the SEM Management Service. + */ +#define CRIA_SERV192 192 + +/** + * Type identifier of the IASW Mode Control Service. + */ +#define CRIA_SERV193 193 + +/** + * Type identifier of the Algorithm Control Service. + */ +#define CRIA_SERV194 194 + +/** + * Type identifier of the Heartbeat Service. + */ +#define CRIA_SERV195 195 + +/** + * Type identifier of the AOCS Service. + */ +#define CRIA_SERV196 196 + +/** + * Type identifier of the Boot Report Service. + */ +#define CRIA_SERV197 197 + +/** + * Type identifier of the Procedure Control Service. + */ +#define CRIA_SERV198 198 + +/** + * Type identifier of the Boot Management Service. + */ +#define CRIA_SERV210 210 + +/** + * Type identifier of the Parameter Update Service. + */ +#define CRIA_SERV211 211 + +/** + * Subtype identifier of the Telecommand Acceptance Report – Success out-going report packet. + */ +#define CRIA_SERV1_ACC_SUCC 1 + +/** + * Subtype identifier of the Telecommand Acceptance Report – Failure out-going report packet. + */ +#define CRIA_SERV1_ACC_FAIL 2 + +/** + * Subtype identifier of the Telecommand Start Report – Success out-going report packet. + */ +#define CRIA_SERV1_START_SUCC 3 + +/** + * Subtype identifier of the Telecommand Start Report – Failure out-going report packet. + */ +#define CRIA_SERV1_START_FAIL 4 + +/** + * Subtype identifier of the Telecommand Termination Report – Success out-going report packet. + */ +#define CRIA_SERV1_TERM_SUCC 7 + +/** + * Subtype identifier of the Telecommand Termination Report – Failure out-going report packet. + */ +#define CRIA_SERV1_TERM_FAIL 8 + +/** + * Subtype identifier of the Define New Housekeeping Data Report in-coming command packet. + */ +#define CRIA_SERV3_DEFINE_HK_DR 1 + +/** + * Subtype identifier of the Clear Housekeeping Data Report in-coming command packet. + */ +#define CRIA_SERV3_CLR_HK_DR 3 + +/** + * Subtype identifier of the Enable Housekeeping Data Report Generation in-coming command packet. + */ +#define CRIA_SERV3_ENB_HK_DR_GEN 5 + +/** + * Subtype identifier of the Disable Housekeeping Data Report Generation in-coming command packet. + */ +#define CRIA_SERV3_DIS_HK_DR_GEN 6 + +/** + * Subtype identifier of the Housekeeping Data Report out-going report packet. + */ +#define CRIA_SERV3_HK_DR 25 + +/** + * Subtype identifier of the Set Housekeeping Reporting Frequency in-coming command packet. + */ +#define CRIA_SERV3_SET_HK_REP_FREQ 131 + +/** + * Subtype identifier of the Normal/Progress Report out-going report packet. + */ +#define CRIA_SERV5_EVT_NORM 1 + +/** + * Subtype identifier of the Error Report - Low Severity out-going report packet. + */ +#define CRIA_SERV5_EVT_ERR_LOW_SEV 2 + +/** + * Subtype identifier of the Error Report - Medium Severity out-going report packet. + */ +#define CRIA_SERV5_EVT_ERR_MED_SEV 3 + +/** + * Subtype identifier of the Error Report - High Severity out-going report packet. + */ +#define CRIA_SERV5_EVT_ERR_HIGH_SEV 4 + +/** + * Subtype identifier of the Enable Event Report Generation in-coming command packet. + */ +#define CRIA_SERV5_ENB_EVT_REP_GEN 5 + +/** + * Subtype identifier of the Disable Event Report Generation in-coming command packet. + */ +#define CRIA_SERV5_DIS_EVT_REP_GEN 6 + +/** + * Subtype identifier of the Load Memory using Absolute Addresses in-coming command packet. + */ +#define CRIA_SERV6_LOAD_MEM 2 + +/** + * Subtype identifier of the Dump Memory using Absolute Addresses in-coming command packet. + */ +#define CRIA_SERV6_DUMP_MEM 5 + +/** + * Subtype identifier of the Memory Dump using Absolute Addresses Report out-going report packet. + */ +#define CRIA_SERV6_MEM_DUMP 6 + +/** + * Subtype identifier of the First Downlink Part Report out-going report packet. + */ +#define CRIA_SERV13_FST_DWLK 1 + +/** + * Subtype identifier of the Intermediate Downlink Part Report out-going report packet. + */ +#define CRIA_SERV13_INTM_DWLK 2 + +/** + * Subtype identifier of the Last Downlink Part Report out-going report packet. + */ +#define CRIA_SERV13_LAST_DWLK 3 + +/** + * Subtype identifier of the Downlink Abort Report out-going report packet. + */ +#define CRIA_SERV13_DWLK_ABRT 4 + +/** + * Subtype identifier of the Abort Downlink in-coming command packet. + */ +#define CRIA_SERV13_ABRT_DWLK 8 + +/** + * Subtype identifier of the Trigger Large Data Transfer in-coming command packet. + */ +#define CRIA_SERV13_TRG_LRG_DATA_TSFR 129 + +/** + * Subtype identifier of the Perform Connection Test in-coming command packet. + */ +#define CRIA_SERV17_PERF_CONN_TEST 1 + +/** + * Subtype identifier of the Link Connection Report out-going report packet. + */ +#define CRIA_SERV17_LINK_CONN_REP 2 + +/** + * Subtype identifier of the Globally Enable FdChecks in-coming command packet. + */ +#define CRIA_SERV191_GLOB_ENB_FD_CHK 1 + +/** + * Subtype identifier of the Globally Disable FdChecks in-coming command packet. + */ +#define CRIA_SERV191_GLOB_DIS_FD_CHK 2 + +/** + * Subtype identifier of the Enable FdCheck in-coming command packet. + */ +#define CRIA_SERV191_ENB_FD_CHK 3 + +/** + * Subtype identifier of the Disable FdCheck in-coming command packet. + */ +#define CRIA_SERV191_DIS_FD_CHK 4 + +/** + * Subtype identifier of the Globally Enable Recovery Procedures in-coming command packet. + */ +#define CRIA_SERV191_GLOB_ENB_RECOV_PROC 5 + +/** + * Subtype identifier of the Globally Disable Recovery Procedures in-coming command packet. + */ +#define CRIA_SERV191_GLOB_DIS_RECOV_PROC 6 + +/** + * Subtype identifier of the Enable Recovery Procedure in-coming command packet. + */ +#define CRIA_SERV191_ENB_RECOV_PROC 7 + +/** + * Subtype identifier of the Disable Recovery Procedure in-coming command packet. + */ +#define CRIA_SERV191_DIS_RECOV_PROC 8 + +/** + * Subtype identifier of the Switch On SEM in-coming command packet. + */ +#define CRIA_SERV192_SWCH_ON_SEM 1 + +/** + * Subtype identifier of the Switch Off SEM in-coming command packet. + */ +#define CRIA_SERV192_SWCH_OFF_SEM 2 + +/** + * Subtype identifier of the Go to STABILIZE in-coming command packet. + */ +#define CRIA_SERV192_GO_STAB 3 + +/** + * Subtype identifier of the Go to STANDBY in-coming command packet. + */ +#define CRIA_SERV192_GO_STBY 4 + +/** + * Subtype identifier of the Go to CCD WINDOW in-coming command packet. + */ +#define CRIA_SERV192_GO_CCD_WIN 5 + +/** + * Subtype identifier of the Go to CCD FULL in-coming command packet. + */ +#define CRIA_SERV192_GO_CCD_FULL 6 + +/** + * Subtype identifier of the Go to DIAGNOSTICS in-coming command packet. + */ +#define CRIA_SERV192_GO_DIAG 7 + +/** + * Subtype identifier of the Abort DIAGNOSTICS in-coming command packet. + */ +#define CRIA_SERV192_ABORT_DIAG 8 + +/** + * Subtype identifier of the Go to SAFE in-coming command packet. + */ +#define CRIA_SERV192_GO_SAFE 10 + +/** + * Subtype identifier of the Prepare Science in-coming command packet. + */ +#define CRIA_SERV193_PREPARE_SCI 1 + +/** + * Subtype identifier of the Start Science in-coming command packet. + */ +#define CRIA_SERV193_START_SCI 2 + +/** + * Subtype identifier of the Stop Science in-coming command packet. + */ +#define CRIA_SERV193_STOP_SCIENCE 3 + +/** + * Subtype identifier of the Stop SEM in-coming command packet. + */ +#define CRIA_SERV193_STOP_SEM 4 + +/** + * Subtype identifier of the Start Offline Operation in-coming command packet. + */ +#define CRIA_SERV193_START_OFFLINE_OPER 5 + +/** + * Subtype identifier of the Controlled Switch-Off IASW in-coming command packet. + */ +#define CRIA_SERV193_SWITCH_OFF_IASW 6 + +/** + * Subtype identifier of the Start Algorithm in-coming command packet. + */ +#define CRIA_SERV194_START_ALGO 1 + +/** + * Subtype identifier of the Stop Algorithm in-coming command packet. + */ +#define CRIA_SERV194_STOP_ALGO 2 + +/** + * Subtype identifier of the Suspend Algorithm in-coming command packet. + */ +#define CRIA_SERV194_SUS_ALGO 3 + +/** + * Subtype identifier of the Resume Algorithm in-coming command packet. + */ +#define CRIA_SERV194_RES_ALGO 4 + +/** + * Subtype identifier of the Heartbeat Report out-going report packet. + */ +#define CRIA_SERV195_HB_REP 1 + +/** + * Subtype identifier of the AOCS Report out-going report packet. + */ +#define CRIA_SERV196_AOCS_REP 1 + +/** + * Subtype identifier of the Star Map Command in-coming command packet. + */ +#define CRIA_SERV196_STAR_MAP_CMD 2 + +/** + * Subtype identifier of the Boot Report out-going report packet. + */ +#define CRIA_SERV197_BOOT_REP 1 + +/** + * Subtype identifier of the Generate Boot Report in-coming command packet. + */ +#define CRIA_SERV197_REP_BOOT 2 + +/** + * Subtype identifier of the Start Procedure in-coming command packet. + */ +#define CRIA_SERV198_PROC_START 1 + +/** + * Subtype identifier of the Stop Procedure in-coming command packet. + */ +#define CRIA_SERV198_PROC_STOP 2 + +/** + * Subtype identifier of the Enable Watchdog in-coming command packet. + */ +#define CRIA_SERV210_ENB_WDOG 3 + +/** + * Subtype identifier of the Disable Watchdog in-coming command packet. + */ +#define CRIA_SERV210_DIS_WDOG 4 + +/** + * Subtype identifier of the Reset DPU in-coming command packet. + */ +#define CRIA_SERV210_RESET_DPU 5 + +/** + * Subtype identifier of the Update Parameter in-coming command packet. + */ +#define CRIA_SERV211_UPDATE_PAR 1 + +/** + * Length of the Telecommand Acceptance Report – Success out-going report packet. + */ +#define CRIA_SERV1_ACC_SUCC_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Telecommand Acceptance Report – Failure out-going report packet. + */ +#define CRIA_SERV1_ACC_FAIL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 16 + CRC_LENGTH) + +/** + * Length of the Telecommand Start Report – Success out-going report packet. + */ +#define CRIA_SERV1_START_SUCC_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Telecommand Start Report – Failure out-going report packet. + */ +#define CRIA_SERV1_START_FAIL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12 + CRC_LENGTH) + +/** + * Length of the Telecommand Termination Report – Success out-going report packet. + */ +#define CRIA_SERV1_TERM_SUCC_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Telecommand Termination Report – Failure out-going report packet. + */ +#define CRIA_SERV1_TERM_FAIL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12 + CRC_LENGTH) + +/** + * Length of the Define New Housekeeping Data Report in-coming command packet. + */ +#define CRIA_SERV3_DEFINE_HK_DR_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Clear Housekeeping Data Report in-coming command packet. + */ +#define CRIA_SERV3_CLR_HK_DR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 1 + CRC_LENGTH) + +/** + * Length of the Enable Housekeeping Data Report Generation in-coming command packet. + */ +#define CRIA_SERV3_ENB_HK_DR_GEN_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 1 + CRC_LENGTH) + +/** + * Length of the Disable Housekeeping Data Report Generation in-coming command packet. + */ +#define CRIA_SERV3_DIS_HK_DR_GEN_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 1 + CRC_LENGTH) + +/** + * Length of the Housekeeping Data Report out-going report packet. + */ +#define CRIA_SERV3_HK_DR_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Set Housekeeping Reporting Frequency in-coming command packet. + */ +#define CRIA_SERV3_SET_HK_REP_FREQ_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Normal/Progress Report out-going report packet. + */ +#define CRIA_SERV5_EVT_NORM_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Error Report - Low Severity out-going report packet. + */ +#define CRIA_SERV5_EVT_ERR_LOW_SEV_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Error Report - Medium Severity out-going report packet. + */ +#define CRIA_SERV5_EVT_ERR_MED_SEV_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Error Report - High Severity out-going report packet. + */ +#define CRIA_SERV5_EVT_ERR_HIGH_SEV_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Enable Event Report Generation in-coming command packet. + */ +#define CRIA_SERV5_ENB_EVT_REP_GEN_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Disable Event Report Generation in-coming command packet. + */ +#define CRIA_SERV5_DIS_EVT_REP_GEN_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Event Sequence Counter Error. + */ +#define CRIA_SERV5_EVT_SEQ_CNT_ERR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event In Rep Cr Fail. + */ +#define CRIA_SERV5_EVT_INREP_CR_FAIL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event Pcrl2 Full. + */ +#define CRIA_SERV5_EVT_PCRL2_FULL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event Failure Detection Failed. + */ +#define CRIA_SERV5_EVT_FD_FAILED_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event Recovery Procedure Started. + */ +#define CRIA_SERV5_EVT_RP_STARTED_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event SEM State Machine Transition. + */ +#define CRIA_SERV5_EVT_SEM_TR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event IASW State Machine Transition. + */ +#define CRIA_SERV5_EVT_IASW_TR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event SDSC Illegal. + */ +#define CRIA_SERV5_EVT_SDSC_ILL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event SDSC Out-of-sequence. + */ +#define CRIA_SERV5_EVT_SDSC_OOS_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event Collection Algorithm out of Space. + */ +#define CRIA_SERV5_EVT_CLCT_SIZE_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event Science Image Buffer size. + */ +#define CRIA_SERV5_EVT_SIB_SIZE_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Centroid Validity Forced Invalid. + */ +#define CRIA_SERV5_EVT_INV_CENT_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Parameter Out-Of-Limits. + */ +#define CRIA_SERV5_EVT_OOL_PARAM_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event Invalid Destination. + */ +#define CRIA_SERV5_EVT_INV_DEST_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event FBF Load Risk. + */ +#define CRIA_SERV5_EVT_FBF_LOAD_RISK_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event FBF Save Denied. + */ +#define CRIA_SERV5_EVT_FBF_SAVE_DENIED_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event FBF Save Abort. + */ +#define CRIA_SERV5_EVT_FBF_SAVE_ABRT_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event SDB Configuration Failed. + */ +#define CRIA_SERV5_EVT_SDB_CNF_FAIL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 22 + CRC_LENGTH) + +/** + * Length of the Event Compression Algorithm out of Space. + */ +#define CRIA_SERV5_EVT_CMPR_SIZE_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event SEM OP State Machine Transition. + */ +#define CRIA_SERV5_EVT_SEMOP_TR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event Science Procedure Starts Execution. + */ +#define CRIA_SERV5_EVT_SC_PR_STRT_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event Science Procedure Terminates Execution. + */ +#define CRIA_SERV5_EVT_SC_PR_END_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event InStream Packet Queue Full. + */ +#define CRIA_SERV5_EVT_INSTRM_PQF_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Event OutComponent Invalid Destination. + */ +#define CRIA_SERV5_EVT_OCMP_INVD_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Event OutComponent Illegal Group Identifier. + */ +#define CRIA_SERV5_EVT_OCMP_ILLGR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5 + CRC_LENGTH) + +/** + * Length of the Event InStream Illegal Group Identifier. + */ +#define CRIA_SERV5_EVT_IN_ILLGR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5 + CRC_LENGTH) + +/** + * Length of the Illegal SEM State at Entry in PRE_SCIENCE. + */ +#define CRIA_SERV5_EVT_SEM_ILL_ST_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Successful IASW Initializationr. + */ +#define CRIA_SERV5_EVT_INIT_SUCC_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the IASW Initialization Failed. + */ +#define CRIA_SERV5_EVT_INIT_FAIL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Thread Overrun. + */ +#define CRIA_SERV5_EVT_THRD_OR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Notification Error. + */ +#define CRIA_SERV5_EVT_NOTIF_ERR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Low-severity 1553 Error. + */ +#define CRIA_SERV5_EVT_1553_ERR_L_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Medium-severity 1553 Error. + */ +#define CRIA_SERV5_EVT_1553_ERR_M_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the High-severity 1553 Error. + */ +#define CRIA_SERV5_EVT_1553_ERR_H_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Low-severity SpaceWire Error. + */ +#define CRIA_SERV5_EVT_SPW_ERR_L_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Medium-severity SpaceWire Error. + */ +#define CRIA_SERV5_EVT_SPW_ERR_M_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the High-severity SpaceWire Error. + */ +#define CRIA_SERV5_EVT_SPW_ERR_H_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Flash-Based Error Log Error. + */ +#define CRIA_SERV5_EVT_FL_EL_ERR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8 + CRC_LENGTH) + +/** + * Length of the Flash-Based File Error. + */ +#define CRIA_SERV5_EVT_FL_FBF_ERR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10 + CRC_LENGTH) + +/** + * Length of the Flash Bad Block Encountered. + */ +#define CRIA_SERV5_EVT_FL_FBF_BB_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Single Bit EDAC Error. + */ +#define CRIA_SERV5_EVT_SBIT_ERR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Double Bit EDAC Error. + */ +#define CRIA_SERV5_EVT_DBIT_ERR_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Synchronization Lost. + */ +#define CRIA_SERV5_EVT_SYNC_LOSS_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the SDP_NOMEM Failure. + */ +#define CRIA_SERV5_EVT_SDP_NOMEM_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Science Buffer Too Small. + */ +#define CRIA_SERV5_EVT_PROCBUF_INSUF_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12 + CRC_LENGTH) + +/** + * Length of the SIB or GIB Cannot Be Incremented. + */ +#define CRIA_SERV5_EVT_XIB_FULL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Image Too Large. + */ +#define CRIA_SERV5_EVT_IMG_INSUF_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 14 + CRC_LENGTH) + +/** + * Length of the Acquisition failure. + */ +#define CRIA_SERV5_EVT_ACQ_FAIL_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Load Memory using Absolute Addresses in-coming command packet. + */ +#define CRIA_SERV6_LOAD_MEM_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Dump Memory using Absolute Addresses in-coming command packet. + */ +#define CRIA_SERV6_DUMP_MEM_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10 + CRC_LENGTH) + +/** + * Length of the Memory Dump using Absolute Addresses Report out-going report packet. + */ +#define CRIA_SERV6_MEM_DUMP_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the First Downlink Part Report out-going report packet. + */ +#define CRIA_SERV13_FST_DWLK_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Intermediate Downlink Part Report out-going report packet. + */ +#define CRIA_SERV13_INTM_DWLK_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Last Downlink Part Report out-going report packet. + */ +#define CRIA_SERV13_LAST_DWLK_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Downlink Abort Report out-going report packet. + */ +#define CRIA_SERV13_DWLK_ABRT_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3 + CRC_LENGTH) + +/** + * Length of the Abort Downlink in-coming command packet. + */ +#define CRIA_SERV13_ABRT_DWLK_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 1 + CRC_LENGTH) + +/** + * Length of the Trigger Large Data Transfer in-coming command packet. + */ +#define CRIA_SERV13_TRG_LRG_DATA_TSFR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 1 + CRC_LENGTH) + +/** + * Length of the Perform Connection Test in-coming command packet. + */ +#define CRIA_SERV17_PERF_CONN_TEST_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Link Connection Report out-going report packet. + */ +#define CRIA_SERV17_LINK_CONN_REP_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Globally Enable FdChecks in-coming command packet. + */ +#define CRIA_SERV191_GLOB_ENB_FD_CHK_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Globally Disable FdChecks in-coming command packet. + */ +#define CRIA_SERV191_GLOB_DIS_FD_CHK_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Enable FdCheck in-coming command packet. + */ +#define CRIA_SERV191_ENB_FD_CHK_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Disable FdCheck in-coming command packet. + */ +#define CRIA_SERV191_DIS_FD_CHK_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Globally Enable Recovery Procedures in-coming command packet. + */ +#define CRIA_SERV191_GLOB_ENB_RECOV_PROC_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Globally Disable Recovery Procedures in-coming command packet. + */ +#define CRIA_SERV191_GLOB_DIS_RECOV_PROC_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Enable Recovery Procedure in-coming command packet. + */ +#define CRIA_SERV191_ENB_RECOV_PROC_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Disable Recovery Procedure in-coming command packet. + */ +#define CRIA_SERV191_DIS_RECOV_PROC_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Switch On SEM in-coming command packet. + */ +#define CRIA_SERV192_SWCH_ON_SEM_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Switch Off SEM in-coming command packet. + */ +#define CRIA_SERV192_SWCH_OFF_SEM_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Go to STABILIZE in-coming command packet. + */ +#define CRIA_SERV192_GO_STAB_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Go to STANDBY in-coming command packet. + */ +#define CRIA_SERV192_GO_STBY_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Go to CCD WINDOW in-coming command packet. + */ +#define CRIA_SERV192_GO_CCD_WIN_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Go to CCD FULL in-coming command packet. + */ +#define CRIA_SERV192_GO_CCD_FULL_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Go to DIAGNOSTICS in-coming command packet. + */ +#define CRIA_SERV192_GO_DIAG_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Abort DIAGNOSTICS in-coming command packet. + */ +#define CRIA_SERV192_ABORT_DIAG_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Go to SAFE in-coming command packet. + */ +#define CRIA_SERV192_GO_SAFE_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Prepare Science in-coming command packet. + */ +#define CRIA_SERV193_PREPARE_SCI_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Start Science in-coming command packet. + */ +#define CRIA_SERV193_START_SCI_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Stop Science in-coming command packet. + */ +#define CRIA_SERV193_STOP_SCIENCE_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Stop SEM in-coming command packet. + */ +#define CRIA_SERV193_STOP_SEM_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Start Offline Operation in-coming command packet. + */ +#define CRIA_SERV193_START_OFFLINE_OPER_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Controlled Switch-Off IASW in-coming command packet. + */ +#define CRIA_SERV193_SWITCH_OFF_IASW_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Start Algorithm in-coming command packet. + */ +#define CRIA_SERV194_START_ALGO_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Stop Algorithm in-coming command packet. + */ +#define CRIA_SERV194_STOP_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Suspend Algorithm in-coming command packet. + */ +#define CRIA_SERV194_SUS_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Resume Algorithm in-coming command packet. + */ +#define CRIA_SERV194_RES_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the SAA Evaluation Algorithm. + */ +#define CRIA_SERV194_SAA_EVAL_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Compression/Collection Algorithm. + */ +#define CRIA_SERV194_CC_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Acquisition Algorithm 1. + */ +#define CRIA_SERV194_ACQ1_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Centroid Algorithm 1. + */ +#define CRIA_SERV194_CNT1_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the SDS Evaluation Algorithm. + */ +#define CRIA_SERV194_SDS_EVAL_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the TTC Algorithm 1. + */ +#define CRIA_SERV194_TTC1_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the TTC Algorithm 2. + */ +#define CRIA_SERV194_TTC2_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Centroid Algorithm 0. + */ +#define CRIA_SERV194_CENT0_ALGO_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Heartbeat Report out-going report packet. + */ +#define CRIA_SERV195_HB_REP_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3 + CRC_LENGTH) + +/** + * Length of the AOCS Report out-going report packet. + */ +#define CRIA_SERV196_AOCS_REP_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 27 + CRC_LENGTH) + +/** + * Length of the Star Map Command in-coming command packet. + */ +#define CRIA_SERV196_STAR_MAP_CMD_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 286 + CRC_LENGTH) + +/** + * Length of the Boot Report out-going report packet. + */ +#define CRIA_SERV197_BOOT_REP_LENGTH (OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1004 + CRC_LENGTH) + +/** + * Length of the Generate Boot Report in-coming command packet. + */ +#define CRIA_SERV197_REP_BOOT_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Start Procedure in-coming command packet. + */ +#define CRIA_SERV198_PROC_START_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Length of the Stop Procedure in-coming command packet. + */ +#define CRIA_SERV198_PROC_STOP_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Save Images Procedure. + */ +#define CRIA_SERV198_SAVE_IMG_PR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the Acquire Full Drop. + */ +#define CRIA_SERV198_ACQ_FULL_DROP_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10 + CRC_LENGTH) + +/** + * Length of the Calibrate Full Snap. + */ +#define CRIA_SERV198_CAL_FULL_SNAP_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 16 + CRC_LENGTH) + +/** + * Length of the FBF Load Procedure. + */ +#define CRIA_SERV198_FBF_LOAD_PR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10 + CRC_LENGTH) + +/** + * Length of the FBF Save Procedure. + */ +#define CRIA_SERV198_FBF_SAVE_PR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10 + CRC_LENGTH) + +/** + * Length of the Science Window Stack/Snap. + */ +#define CRIA_SERV198_SCI_STACK_PR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 26 + CRC_LENGTH) + +/** + * Length of the Transfer FBFs To Ground. + */ +#define CRIA_SERV198_FBF_TO_GND_PR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 5 + CRC_LENGTH) + +/** + * Length of the Nominal Science. + */ +#define CRIA_SERV198_NOM_SCI_PR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 94 + CRC_LENGTH) + +/** + * Length of the Configure SDB. + */ +#define CRIA_SERV198_CONFIG_SDB_PR_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 22 + CRC_LENGTH) + +/** + * Length of the Enable Watchdog in-coming command packet. + */ +#define CRIA_SERV210_ENB_WDOG_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Disable Watchdog in-coming command packet. + */ +#define CRIA_SERV210_DIS_WDOG_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Reset DPU in-coming command packet. + */ +#define CRIA_SERV210_RESET_DPU_LENGTH (OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the Update Parameter in-coming command packet. + */ +#define CRIA_SERV211_UPDATE_PAR_LENGTH CR_MAX_SIZE_PCKT_LARGE + +/** + * Identifier of the Event Sequence Counter Error. + */ +#define CRIA_SERV5_EVT_SEQ_CNT_ERR 200 + +/** + * Identifier of the Event In Rep Cr Fail. + */ +#define CRIA_SERV5_EVT_INREP_CR_FAIL 201 + +/** + * Identifier of the Event Pcrl2 Full. + */ +#define CRIA_SERV5_EVT_PCRL2_FULL 202 + +/** + * Identifier of the Event Failure Detection Failed. + */ +#define CRIA_SERV5_EVT_FD_FAILED 203 + +/** + * Identifier of the Event Recovery Procedure Started. + */ +#define CRIA_SERV5_EVT_RP_STARTED 204 + +/** + * Identifier of the Event SEM State Machine Transition. + */ +#define CRIA_SERV5_EVT_SEM_TR 205 + +/** + * Identifier of the Event IASW State Machine Transition. + */ +#define CRIA_SERV5_EVT_IASW_TR 206 + +/** + * Identifier of the Event SDSC Illegal. + */ +#define CRIA_SERV5_EVT_SDSC_ILL 208 + +/** + * Identifier of the Event SDSC Out-of-sequence. + */ +#define CRIA_SERV5_EVT_SDSC_OOS 209 + +/** + * Identifier of the Event Collection Algorithm out of Space. + */ +#define CRIA_SERV5_EVT_CLCT_SIZE 210 + +/** + * Identifier of the Event Science Image Buffer size. + */ +#define CRIA_SERV5_EVT_SIB_SIZE 211 + +/** + * Identifier of the Centroid Validity Forced Invalid. + */ +#define CRIA_SERV5_EVT_INV_CENT 230 + +/** + * Identifier of the Parameter Out-Of-Limits. + */ +#define CRIA_SERV5_EVT_OOL_PARAM 231 + +/** + * Identifier of the Event Invalid Destination. + */ +#define CRIA_SERV5_EVT_INV_DEST 101 + +/** + * Identifier of the Event FBF Load Risk. + */ +#define CRIA_SERV5_EVT_FBF_LOAD_RISK 212 + +/** + * Identifier of the Event FBF Save Denied. + */ +#define CRIA_SERV5_EVT_FBF_SAVE_DENIED 213 + +/** + * Identifier of the Event FBF Save Abort. + */ +#define CRIA_SERV5_EVT_FBF_SAVE_ABRT 214 + +/** + * Identifier of the Event SDB Configuration Failed. + */ +#define CRIA_SERV5_EVT_SDB_CNF_FAIL 215 + +/** + * Identifier of the Event Compression Algorithm out of Space. + */ +#define CRIA_SERV5_EVT_CMPR_SIZE 216 + +/** + * Identifier of the Event SEM OP State Machine Transition. + */ +#define CRIA_SERV5_EVT_SEMOP_TR 217 + +/** + * Identifier of the Event Science Procedure Starts Execution. + */ +#define CRIA_SERV5_EVT_SC_PR_STRT 218 + +/** + * Identifier of the Event Science Procedure Terminates Execution. + */ +#define CRIA_SERV5_EVT_SC_PR_END 219 + +/** + * Identifier of the Event InStream Packet Queue Full. + */ +#define CRIA_SERV5_EVT_INSTRM_PQF 220 + +/** + * Identifier of the Event OutComponent Invalid Destination. + */ +#define CRIA_SERV5_EVT_OCMP_INVD 221 + +/** + * Identifier of the Event OutComponent Illegal Group Identifier. + */ +#define CRIA_SERV5_EVT_OCMP_ILLGR 222 + +/** + * Identifier of the Event InStream Illegal Group Identifier. + */ +#define CRIA_SERV5_EVT_IN_ILLGR 223 + +/** + * Identifier of the Illegal SEM State at Entry in PRE_SCIENCE. + */ +#define CRIA_SERV5_EVT_SEM_ILL_ST 1400 + +/** + * Identifier of the Successful IASW Initializationr. + */ +#define CRIA_SERV5_EVT_INIT_SUCC 301 + +/** + * Identifier of the IASW Initialization Failed. + */ +#define CRIA_SERV5_EVT_INIT_FAIL 302 + +/** + * Identifier of the Thread Overrun. + */ +#define CRIA_SERV5_EVT_THRD_OR 303 + +/** + * Identifier of the Notification Error. + */ +#define CRIA_SERV5_EVT_NOTIF_ERR 304 + +/** + * Identifier of the Low-severity 1553 Error. + */ +#define CRIA_SERV5_EVT_1553_ERR_L 311 + +/** + * Identifier of the Medium-severity 1553 Error. + */ +#define CRIA_SERV5_EVT_1553_ERR_M 312 + +/** + * Identifier of the High-severity 1553 Error. + */ +#define CRIA_SERV5_EVT_1553_ERR_H 313 + +/** + * Identifier of the Low-severity SpaceWire Error. + */ +#define CRIA_SERV5_EVT_SPW_ERR_L 315 + +/** + * Identifier of the Medium-severity SpaceWire Error. + */ +#define CRIA_SERV5_EVT_SPW_ERR_M 316 + +/** + * Identifier of the High-severity SpaceWire Error. + */ +#define CRIA_SERV5_EVT_SPW_ERR_H 317 + +/** + * Identifier of the Flash-Based Error Log Error. + */ +#define CRIA_SERV5_EVT_FL_EL_ERR 320 + +/** + * Identifier of the Flash-Based File Error. + */ +#define CRIA_SERV5_EVT_FL_FBF_ERR 325 + +/** + * Identifier of the Flash Bad Block Encountered. + */ +#define CRIA_SERV5_EVT_FL_FBF_BB 326 + +/** + * Identifier of the Single Bit EDAC Error. + */ +#define CRIA_SERV5_EVT_SBIT_ERR 330 + +/** + * Identifier of the Double Bit EDAC Error. + */ +#define CRIA_SERV5_EVT_DBIT_ERR 335 + +/** + * Identifier of the Synchronization Lost. + */ +#define CRIA_SERV5_EVT_SYNC_LOSS 350 + +/** + * Identifier of the SDP Failure. + */ +#define CRIA_SERV5_EVT_SDP_NOMEM 1001 + +/** + * Identifier of the Science Buffer Too Small. + */ +#define CRIA_SERV5_EVT_PROCBUF_INSUF 1501 + +/** + * Identifier of the SIB or GIB Cannot Be Incremented. + */ +#define CRIA_SERV5_EVT_XIB_FULL 1503 + +/** + * Identifier of the Image Too Large. + */ +#define CRIA_SERV5_EVT_IMG_INSUF 1504 + +/** + * Identifier of the Acquisition failure. + */ +#define CRIA_SERV5_EVT_ACQ_FAIL 1450 + +/** + * Identifier of the SAA Evaluation Algorithm. + */ +#define CRIA_SERV194_SAA_EVAL_ALGO 1 + +/** + * Identifier of the Compression/Collection Algorithm. + */ +#define CRIA_SERV194_CC_ALGO 3 + +/** + * Identifier of the Acquisition Algorithm 1. + */ +#define CRIA_SERV194_ACQ1_ALGO 4 + +/** + * Identifier of the Centroid Algorithm 1. + */ +#define CRIA_SERV194_CNT1_ALGO 5 + +/** + * Identifier of the SDS Evaluation Algorithm. + */ +#define CRIA_SERV194_SDS_EVAL_ALGO 6 + +/** + * Identifier of the TTC Algorithm 1. + */ +#define CRIA_SERV194_TTC1_ALGO 8 + +/** + * Identifier of the TTC Algorithm 2. + */ +#define CRIA_SERV194_TTC2_ALGO 9 + +/** + * Identifier of the Centroid Algorithm 0. + */ +#define CRIA_SERV194_CENT0_ALGO 11 + +/** + * Identifier of the Save Images Procedure. + */ +#define CRIA_SERV198_SAVE_IMG_PR 1 + +/** + * Identifier of the Acquire Full Drop. + */ +#define CRIA_SERV198_ACQ_FULL_DROP 2 + +/** + * Identifier of the Calibrate Full Snap. + */ +#define CRIA_SERV198_CAL_FULL_SNAP 3 + +/** + * Identifier of the FBF Load Procedure. + */ +#define CRIA_SERV198_FBF_LOAD_PR 4 + +/** + * Identifier of the FBF Save Procedure. + */ +#define CRIA_SERV198_FBF_SAVE_PR 5 + +/** + * Identifier of the Science Window Stack/Snap. + */ +#define CRIA_SERV198_SCI_STACK_PR 6 + +/** + * Identifier of the Transfer FBFs To Ground. + */ +#define CRIA_SERV198_FBF_TO_GND_PR 7 + +/** + * Identifier of the Nominal Science. + */ +#define CRIA_SERV198_NOM_SCI_PR 8 + +/** + * Identifier of the Configure SDB. + */ +#define CRIA_SERV198_CONFIG_SDB_PR 9 + + +/* Error Log IDs */ +#define ERR_OUTSTREAM_PQ_FULL 102 +#define ERR_POCL_FULL 105 +#define ERR_OUTCMP_NO_MORE_PCKT 108 + +/** + * Acknowledgements (positive and negative) + */ +#define ACK_WRONG_CHKSM 1001 +#define ACK_WRONG_LEN 1002 +#define ACK_ILL_MEM_LEN 1005 +#define ACK_ILL_SID 1006 +#define ACK_ILL_PER 1007 +#define ACK_ILL_MEM_SRC 1008 +#define ACK_ILL_MEM_ID 1010 +#define ACK_ILL_DSIZE 1099 + +#define ACK_CREATE_FAIL 1100 +#define ACK_PCRL1_FULL 1101 +#define ACK_ILL_NDI 1102 +#define ACK_ILL_DID 1103 +#define ACK_RDL_NO_SLOT 1104 +#define ACK_SID_IN_USE 1105 +#define ACK_SID_NOT_USED 1106 +#define ACK_ILL_EID 1107 +#define ACK_EID_ENB 1108 +#define ACK_EID_DIS 1109 +#define ACK_WR_IASW_M 1110 +#define ACK_WR_SEM_M 1111 +#define ACK_ILL_FID 1112 +#define ACK_ILL_RID 1113 +#define ACK_FID_ENB 1114 +#define ACK_FID_DIS 1115 +#define ACK_RID_ENB 1116 +#define ACK_RID_DIS 1117 + +#define ACK_ILL_AID 1123 +#define ACK_ILL_WD_STATUS 1124 +#define ACK_MODE_CHNG_FAILED 1125 +#define ACK_ILL_PAR 1127 + +#define ACK_ILL_SMAP 1140 + +#define ACK_ILL_PR_ID 1200 +#define ACK_ILL_PR_PAR 1201 +#define ACK_PR_BUSY 1202 +#define ACK_PR_IDLE 1203 +#define ACK_WR_SDB_M 1204 +#define ACK_ILL_SDUID 1205 +#define ACK_WR_SDU_M 1206 +#define ACK_WR_ALGO_M 1208 + +#define ACK_ILL_PTYP 1250 +#define ACK_WR_PLEN 1251 +#define ACK_ILL_ELEM 1252 + +#define ACK_MEM_FAIL 1260 + +#define SDU_ID_MAX 4 + +#define SDP_STATUS_IDLE 0 +#define SDP_STATUS_ERROR 1 +#define SDP_STATUS_ACQUISITION 2 +#define SDP_STATUS_SCIENCE 3 + +#endif /* CRIA_CONSTANTS_H */ + diff --git a/CrIa/src/Services/General/CrIaParamGetter.c b/CrIa/src/Services/General/CrIaParamGetter.c new file mode 100644 index 0000000000000000000000000000000000000000..0d0808f09f53bc06b0dc88b2ebc2b820654d4020 --- /dev/null +++ b/CrIa/src/Services/General/CrIaParamGetter.c @@ -0,0 +1,897 @@ +/** + * @file CrIaParamGetter.c + * @ingroup CrIaServicesGeneral + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the getter operations for all parameters of all in-coming packets. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaParamGetter.h" +#include "CrIaConstants.h" +#include "CrIaPckt.h" +#include "CrIaDataPool.h" +#include <string.h> + + +#define GET_UCHAR_FROM_PCKT(from) ((unsigned char)(pckt[from])) + +#define GET_USHORT_FROM_PCKT(from) ( (((unsigned char)(pckt[from])) << 8) | ((unsigned char)(pckt[from+1])) ) + +#define GET_UINT_FROM_PCKT(from) ( (((unsigned char)(pckt[from])) << 24) | (((unsigned char)(pckt[from+1])) << 16) | (((unsigned char)(pckt[from+2])) << 8) | ((unsigned char)(pckt[from+3])) ) + + +void CrIaServ3DefineHkDrParamGetSid(unsigned char * sid, CrFwPckt_t pckt) +{ + *sid = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ3DefineHkDrParamGetPeriod(unsigned short * period, CrFwPckt_t pckt) +{ + *period = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 1); + return; +} + +void CrIaServ3DefineHkDrParamGetNoDataItemId(unsigned short * noDataItemId, CrFwPckt_t pckt) +{ + *noDataItemId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 3); + return; +} + +void CrIaServ3DefineHkDrParamGetDataItemId(unsigned int * dataItemId, unsigned short length, unsigned short offset, CrFwPckt_t pckt) +{ + (void) length; + + *dataItemId = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 5 + offset); + + /* Mantis 1867 is overruled by Mantis 2247, which wants to remove the back-door */ + if (*dataItemId > ADS_PARAM_OFFSET) + { + *dataItemId -= ADS_PARAM_OFFSET; + } + else + { + /* remove back-door */ + *dataItemId = 0; + } + return; +} + +void CrIaServ3ClrHkDrParamGetSid(unsigned char * sid, CrFwPckt_t pckt) +{ + *sid = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ3EnbHkDrGenParamGetSid(unsigned char * sid, CrFwPckt_t pckt) +{ + *sid = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ3DisHkDrGenParamGetSid(unsigned char * sid, CrFwPckt_t pckt) +{ + *sid = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ3SetHkRepFreqParamGetSid(unsigned char * sid, CrFwPckt_t pckt) +{ + *sid = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ3SetHkRepFreqParamGetSpare(unsigned char * spare, CrFwPckt_t pckt) +{ + *spare = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 1); + return; +} + +void CrIaServ3SetHkRepFreqParamGetPeriod(unsigned short * period, CrFwPckt_t pckt) +{ + *period = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ5EnbEvtRepGenParamGetEvtId(unsigned short * evtId, CrFwPckt_t pckt) +{ + *evtId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ5DisEvtRepGenParamGetEvtId(unsigned short * evtId, CrFwPckt_t pckt) +{ + *evtId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ6LoadMemParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt) +{ + *dpuMemoryId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ6LoadMemParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt) +{ + *startAddress = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ6LoadMemParamGetBlockLength(unsigned int * blockLength, CrFwPckt_t pckt) +{ + *blockLength = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ6LoadMemParamGetBlockData(unsigned char * blockData, unsigned short length, CrFwPckt_t pckt) +{ + memcpy(blockData, &pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10], length); + return; +} + +void CrIaServ6DumpMemParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt) +{ + *dpuMemoryId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ6DumpMemParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt) +{ + *startAddress = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ6DumpMemParamGetBlockLength(unsigned int * blockLength, CrFwPckt_t pckt) +{ + *blockLength = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ6DumpRepMemParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt) +{ + *dpuMemoryId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0); + return; +} + +void CrIaServ6DumpRepMemParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt) +{ + *startAddress = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2); + return; +} + +void CrIaServ6DumpRepMemParamGetBlockLength(unsigned int * blockLength, CrFwPckt_t pckt) +{ + *blockLength = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6); + return; +} + +void CrIaServ13FstDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt) +{ + *sduId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0); + return; +} + +void CrIaServ13IntmDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt) +{ + *sduId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0); + return; +} + +void CrIaServ13LastDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt) +{ + *sduId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0); + return; +} + +void CrIaServ13AbrtDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt) +{ + *sduId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ13TrgLrgDataTsfrParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt) +{ + *sduId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ191EnbFdChkParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt) +{ + *fdChkId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ191DisFdChkParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt) +{ + *fdChkId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ191EnbRecovProcParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt) +{ + *fdChkId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ191DisRecovProcParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt) +{ + *fdChkId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ194StartAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt) +{ + *algoId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ194StartAlgoParamGetAlgoParams(unsigned char * algoParams, unsigned short length, CrFwPckt_t pckt) +{ +#if(__sparc__) + memcpy(algoParams, &pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2], length); +#else + /* the parameters should always be 4 in length, so we should never have a problem here */ + if (length == 4) + { + algoParams[0] = pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + 3]; + algoParams[1] = pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + 2]; + algoParams[2] = pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + 1]; + algoParams[3] = pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + 0]; + } +#endif + + return; +} + +void CrIaServ194StopAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt) +{ + *algoId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ194SusAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt) +{ + *algoId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ194ResAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt) +{ + *algoId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ194SaaEvalAlgoParamGetInitSaaCounter(unsigned int * initSaaCounter, CrFwPckt_t pckt) +{ + *initSaaCounter = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ196StarMapCmdParamGetObservationId(unsigned int * observationId, CrFwPckt_t pckt) +{ + *observationId = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ196StarMapCmdParamGetAcqAlgoId(unsigned short * acqAlgoId, CrFwPckt_t pckt) +{ + *acqAlgoId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4); + return; +} + +void CrIaServ196StarMapCmdParamGetSPARE(unsigned int * sPARE, CrFwPckt_t pckt) +{ + *sPARE = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ196StarMapCmdParamGetSkyPattern(unsigned char * skyPattern, CrFwPckt_t pckt) +{ + unsigned int i; + for(i = 0; i < 276; i++) /* NOTE: was 982 = 1004 (StarMap packet) - 2 (CRC) - 10 (PUS hdr) - 10 (StarMap Header) */ + { + skyPattern[i] = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10 + i); + } + return; +} + +void CrIaServ197RepBootParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt) +{ + *dpuMemoryId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ197RepBootParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt) +{ + *startAddress = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198ProcStartParamGetProcId(unsigned short * procId, CrFwPckt_t pckt) +{ + *procId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ198ProcStartParamGetProcParams(unsigned char * procParams, unsigned short length, CrFwPckt_t pckt) +{ + memcpy(procParams, &pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2], length); + return; +} + +void CrIaServ198ProcStopParamGetProcId(unsigned short * procId, CrFwPckt_t pckt) +{ + *procId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ198SaveImgPrParamGetSaveTarget(unsigned short * saveTarget, CrFwPckt_t pckt) +{ + *saveTarget = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198SaveImgPrParamGetFbfInit(unsigned char * fbfInit, CrFwPckt_t pckt) +{ + *fbfInit = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4); + return; +} + +void CrIaServ198SaveImgPrParamGetFbfEnd(unsigned char * fbfEnd, CrFwPckt_t pckt) +{ + *fbfEnd = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 5); + return; +} + +void CrIaServ198AcqFullDropParamGetExpTime(unsigned int * expTime, CrFwPckt_t pckt) +{ + *expTime = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198AcqFullDropParamGetImageRep(unsigned int * imageRep, CrFwPckt_t pckt) +{ + *imageRep = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ198CalFullSnapParamGetExpTime(unsigned int * expTime, CrFwPckt_t pckt) +{ + *expTime = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198CalFullSnapParamGetImageRep(unsigned int * imageRep, CrFwPckt_t pckt) +{ + *imageRep = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ198CalFullSnapParamGetNmbImages(unsigned int * nmbImages, CrFwPckt_t pckt) +{ + *nmbImages = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10); + return; +} + +void CrIaServ198CalFullSnapParamGetCentSel(unsigned short * centSel, CrFwPckt_t pckt) +{ + *centSel = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 14); + return; +} + +void CrIaServ198FbfLoadPrParamGetFbfId(unsigned char * fbfId, CrFwPckt_t pckt) +{ + *fbfId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198FbfLoadPrParamGetFbfNBlocks(unsigned char * fbfNBlocks, CrFwPckt_t pckt) +{ + *fbfNBlocks = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 3); + return; +} + +void CrIaServ198FbfLoadPrParamGetFbfRamAreaId(unsigned short * fbfRamAreaId, CrFwPckt_t pckt) +{ + *fbfRamAreaId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4); + return; +} + +void CrIaServ198FbfLoadPrParamGetFbfRamAddr(unsigned int * fbfRamAddr, CrFwPckt_t pckt) +{ + *fbfRamAddr = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ198FbfSavePrParamGetFbfId(unsigned char * fbfId, CrFwPckt_t pckt) +{ + *fbfId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198FbfSavePrParamGetFbfNBlocks(unsigned char * fbfNBlocks, CrFwPckt_t pckt) +{ + *fbfNBlocks = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 3); + return; +} + +void CrIaServ198FbfSavePrParamGetFbfRamAreaId(unsigned short * fbfRamAreaId, CrFwPckt_t pckt) +{ + *fbfRamAreaId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4); + return; +} + +void CrIaServ198FbfSavePrParamGetFbfRamAddr(unsigned int * fbfRamAddr, CrFwPckt_t pckt) +{ + *fbfRamAddr = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ198SciStackPrParamGetNmbImages(unsigned int * nmbImages, CrFwPckt_t pckt) +{ + *nmbImages = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198SciStackPrParamGetCcdRdMode(unsigned short * ccdRdMode, CrFwPckt_t pckt) +{ + *ccdRdMode = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ198SciStackPrParamGetExpTime(unsigned int * expTime, CrFwPckt_t pckt) +{ + *expTime = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 8); + return; +} + +void CrIaServ198SciStackPrParamGetImageRep(unsigned int * imageRep, CrFwPckt_t pckt) +{ + *imageRep = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 12); + return; +} + +void CrIaServ198SciStackPrParamGetWinPosX(unsigned short * winPosX, CrFwPckt_t pckt) +{ + *winPosX = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 16); + return; +} + +void CrIaServ198SciStackPrParamGetWinPosY(unsigned short * winPosY, CrFwPckt_t pckt) +{ + *winPosY = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 18); + return; +} + +void CrIaServ198SciStackPrParamGetWinSizeX(unsigned short * winSizeX, CrFwPckt_t pckt) +{ + *winSizeX = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 20); + return; +} + +void CrIaServ198SciStackPrParamGetWinSizeY(unsigned short * winSizeY, CrFwPckt_t pckt) +{ + *winSizeY = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 22); /* NOTE: was 23 */ + return; +} + +void CrIaServ198SciStackPrParamGetCentSel(unsigned short * centSel, CrFwPckt_t pckt) +{ + *centSel = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 24); + return; +} + +void CrIaServ198FbfToGndPrParamGetNmbFbf(unsigned char * nmbFbf, CrFwPckt_t pckt) +{ + *nmbFbf = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198FbfToGndPrParamGetFbfInit(unsigned char * fbfInit, CrFwPckt_t pckt) +{ + *fbfInit = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 3); + return; +} + +void CrIaServ198FbfToGndPrParamGetFbfSize(unsigned char * fbfSize, CrFwPckt_t pckt) +{ + *fbfSize = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetAcqFlag(unsigned char * acqFlag, CrFwPckt_t pckt) +{ + *acqFlag = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198NomSciPrParamGetCal1Flag(unsigned char * cal1Flag, CrFwPckt_t pckt) +{ + *cal1Flag = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 3); + return; +} + +void CrIaServ198NomSciPrParamGetSciFlag(unsigned char * sciFlag, CrFwPckt_t pckt) +{ + *sciFlag = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4); + return; +} + +void CrIaServ198NomSciPrParamGetCal2Flag(unsigned char * cal2Flag, CrFwPckt_t pckt) +{ + *cal2Flag = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 5); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetCibNFull(unsigned char * cibNFull, CrFwPckt_t pckt) +{ + *cibNFull = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6); + return; +} + +void CrIaServ198NomSciPrParamGetCibSizeFull(unsigned short * cibSizeFull, CrFwPckt_t pckt) +{ + *cibSizeFull = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 7); + return; +} + +void CrIaServ198NomSciPrParamGetSibNFull(unsigned char * sibNFull, CrFwPckt_t pckt) +{ + *sibNFull = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 9); + return; +} + +void CrIaServ198NomSciPrParamGetSibSizeFull(unsigned short * sibSizeFull, CrFwPckt_t pckt) +{ + *sibSizeFull = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10); + return; +} + +void CrIaServ198NomSciPrParamGetGibNFull(unsigned char * gibNFull, CrFwPckt_t pckt) +{ + *gibNFull = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 12); + return; +} + +void CrIaServ198NomSciPrParamGetGibSizeFull(unsigned short * gibSizeFull, CrFwPckt_t pckt) +{ + *gibSizeFull = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 13); + return; +} + +void CrIaServ198NomSciPrParamGetSibNWin(unsigned char * sibNWin, CrFwPckt_t pckt) +{ + *sibNWin = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 15); + return; +} + +void CrIaServ198NomSciPrParamGetSibSizeWin(unsigned short * sibSizeWin, CrFwPckt_t pckt) +{ + *sibSizeWin = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 16); + return; +} + +void CrIaServ198NomSciPrParamGetCibNWin(unsigned char * cibNWin, CrFwPckt_t pckt) +{ + *cibNWin = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 18); + return; +} + +void CrIaServ198NomSciPrParamGetCibSizeWin(unsigned short * cibSizeWin, CrFwPckt_t pckt) +{ + *cibSizeWin = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 19); + return; +} + +void CrIaServ198NomSciPrParamGetGibNWin(unsigned char * gibNWin, CrFwPckt_t pckt) +{ + *gibNWin = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 21); + return; +} + +void CrIaServ198NomSciPrParamGetGibSizeWin(unsigned short * gibSizeWin, CrFwPckt_t pckt) +{ + *gibSizeWin = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 22); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetExpTimeAcq(unsigned int * expTimeAcq, CrFwPckt_t pckt) +{ + *expTimeAcq = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 24); + return; +} + +void CrIaServ198NomSciPrParamGetImageRepAcq(unsigned int * imageRepAcq, CrFwPckt_t pckt) +{ + *imageRepAcq = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 28); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetExpTimeCal1(unsigned int * expTimeCal1, CrFwPckt_t pckt) +{ + *expTimeCal1 = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 32); + return; +} + +void CrIaServ198NomSciPrParamGetImageRepCal1(unsigned int * imageRepCal1, CrFwPckt_t pckt) +{ + *imageRepCal1 = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 36); + return; +} + +void CrIaServ198NomSciPrParamGetNmbImagesCal1(unsigned int * nmbImagesCal1, CrFwPckt_t pckt) +{ + *nmbImagesCal1 = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 40); + return; +} + +void CrIaServ198NomSciPrParamGetCentSelCal1(unsigned short * centSelCal1, CrFwPckt_t pckt) +{ + *centSelCal1 = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 44); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetNmbImagesSci(unsigned int * nmbImagesSci, CrFwPckt_t pckt) +{ + *nmbImagesSci = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 46); + return; +} + +void CrIaServ198NomSciPrParamGetCcdRdModeSci(unsigned short * ccdRdModeSci, CrFwPckt_t pckt) +{ + *ccdRdModeSci = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 50); + return; +} + +void CrIaServ198NomSciPrParamGetExpTimeSci(unsigned int * expTimeSci, CrFwPckt_t pckt) +{ + *expTimeSci = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 52); + return; +} + +void CrIaServ198NomSciPrParamGetImageRepSci(unsigned int * imageRepSci, CrFwPckt_t pckt) +{ + *imageRepSci = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 56); + return; +} + +void CrIaServ198NomSciPrParamGetWinPosXSci(unsigned short * winPosXSci, CrFwPckt_t pckt) +{ + *winPosXSci = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 60); + return; +} + +void CrIaServ198NomSciPrParamGetWinPosYSci(unsigned short * winPosYSci, CrFwPckt_t pckt) +{ + *winPosYSci = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 62); + return; +} + +void CrIaServ198NomSciPrParamGetWinSizeXSci(unsigned short * winSizeXSci, CrFwPckt_t pckt) +{ + *winSizeXSci = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 64); + return; +} + +void CrIaServ198NomSciPrParamGetWinSizeYSci(unsigned short * winSizeYSci, CrFwPckt_t pckt) +{ + *winSizeYSci = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 66); + return; +} + +void CrIaServ198NomSciPrParamGetCentSelSci(unsigned short * centSelSci, CrFwPckt_t pckt) +{ + *centSelSci = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 68); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetExpTimeCal2(unsigned int * expTimeCal2, CrFwPckt_t pckt) +{ + *expTimeCal2 = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 70); + return; +} + +void CrIaServ198NomSciPrParamGetImageRepCal2(unsigned int * imageRepCal2, CrFwPckt_t pckt) +{ + *imageRepCal2 = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 74); + return; +} + +void CrIaServ198NomSciPrParamGetNmbImagesCal2(unsigned int * nmbImagesCal2, CrFwPckt_t pckt) +{ + *nmbImagesCal2 = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 78); + return; +} + +void CrIaServ198NomSciPrParamGetCentSelCal2(unsigned short * centSelCal2, CrFwPckt_t pckt) +{ + *centSelCal2 = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 82); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetSaveTarget(unsigned short * saveTarget, CrFwPckt_t pckt) +{ + *saveTarget = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 84); + return; +} + +void CrIaServ198NomSciPrParamGetFbfInit(unsigned char * fbfInit, CrFwPckt_t pckt) +{ + *fbfInit = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 86); + return; +} + +void CrIaServ198NomSciPrParamGetFbfEnd(unsigned char * fbfEnd, CrFwPckt_t pckt) +{ + *fbfEnd = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 87); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +void CrIaServ198NomSciPrParamGetStckOrderCal1(unsigned short * stckOrderCal1, CrFwPckt_t pckt) +{ + *stckOrderCal1 = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 88); + return; +} + +void CrIaServ198NomSciPrParamGetStckOrderSci(unsigned short * stckOrderSci, CrFwPckt_t pckt) +{ + *stckOrderSci = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 90); + return; +} + +void CrIaServ198NomSciPrParamGetStckOrderCal2(unsigned short * stckOrderCal2, CrFwPckt_t pckt) +{ + *stckOrderCal2 = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 92); + return; +} + +/* --- Nominal Science ----------------------------------------------------------------------- */ + +/* NOTE: 0 1 are procedure ID, 2 3 are the sdb cmd */ +void CrIaServ198ConfigSdbPrParamGetSdbCmd(unsigned short * sdbCmd, CrFwPckt_t pckt) +{ + *sdbCmd = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2); + return; +} + +void CrIaServ198ConfigSdbPrParamGetCibNFull(unsigned char * cibNFull, CrFwPckt_t pckt) +{ + *cibNFull = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 4); + return; +} + +void CrIaServ198ConfigSdbPrParamGetCibSizeFull(unsigned short * cibSizeFull, CrFwPckt_t pckt) +{ + *cibSizeFull = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 5); + return; +} + +void CrIaServ198ConfigSdbPrParamGetSibNFull(unsigned char * sibNFull, CrFwPckt_t pckt) +{ + *sibNFull = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 7); + return; +} + +void CrIaServ198ConfigSdbPrParamGetSibSizeFull(unsigned short * sibSizeFull, CrFwPckt_t pckt) +{ + *sibSizeFull = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 8); + return; +} + +void CrIaServ198ConfigSdbPrParamGetGibNFull(unsigned char * gibNFull, CrFwPckt_t pckt) +{ + *gibNFull = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 10); + return; +} + +void CrIaServ198ConfigSdbPrParamGetGibSizeFull(unsigned short * gibSizeFull, CrFwPckt_t pckt) +{ + *gibSizeFull = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 11); + return; +} + +void CrIaServ198ConfigSdbPrParamGetSibNWin(unsigned char * sibNWin, CrFwPckt_t pckt) +{ + *sibNWin = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 13); + return; +} + +void CrIaServ198ConfigSdbPrParamGetSibSizeWin(unsigned short * sibSizeWin, CrFwPckt_t pckt) +{ + *sibSizeWin = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 14); + return; +} + +void CrIaServ198ConfigSdbPrParamGetCibNWin(unsigned char * cibNWin, CrFwPckt_t pckt) +{ + *cibNWin = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 16); + return; +} + +void CrIaServ198ConfigSdbPrParamGetCibSizeWin(unsigned short * cibSizeWin, CrFwPckt_t pckt) +{ + *cibSizeWin = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 17); + return; +} + +void CrIaServ198ConfigSdbPrParamGetGibNWin(unsigned char * gibNWin, CrFwPckt_t pckt) +{ + *gibNWin = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 19); + return; +} + +void CrIaServ198ConfigSdbPrParamGetGibSizeWin(unsigned short * gibSizeWin, CrFwPckt_t pckt) +{ + *gibSizeWin = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 20); + return; +} + +void CrIaServ211UpdateParParamGetNoParams(unsigned short * noParams, CrFwPckt_t pckt) +{ + *noParams = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 0); + return; +} + +void CrIaServ211UpdateParParamGetParamId(unsigned int * paramId, unsigned short offset, CrFwPckt_t pckt) +{ + *paramId = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 2 + offset); + + /* Mantis 1867 is overruled by Mantis 2247, which wants to remove the back-door */ + if (*paramId > ADS_PARAM_OFFSET) + { + *paramId -= ADS_PARAM_OFFSET; + } + else + { + /* remove back-door */ + *paramId = 0; + } + + return; +} + +void CrIaServ211UpdateParParamGetParamType(unsigned char * paramType, unsigned short offset, CrFwPckt_t pckt) +{ + *paramType = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 6 + offset); + return; +} + +void CrIaServ211UpdateParParamGetArrayElemId(unsigned short * arrayElemId, unsigned short offset, CrFwPckt_t pckt) +{ + + *arrayElemId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_CMD_PCKT + 7 + offset); + return; +} + +void CrIaServ211UpdateParParamGetParamValue(unsigned char * paramValue, unsigned short offset, unsigned short length, CrFwPckt_t pckt) +{ + memcpy(paramValue, &pckt[OFFSET_PAR_LENGTH_IN_CMD_PCKT + 9 + offset], length); + return; +} + diff --git a/CrIa/src/Services/General/CrIaParamGetter.h b/CrIa/src/Services/General/CrIaParamGetter.h new file mode 100644 index 0000000000000000000000000000000000000000..77e0268d58d0012531f957213f2b82641681657e --- /dev/null +++ b/CrIa/src/Services/General/CrIaParamGetter.h @@ -0,0 +1,948 @@ +/** + * @file CrIaParamGetter.h + * + * Declaration of the getter operations for all parameters of all in-coming packets. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_PARAM_GETTER_H +#define CRIA_PARAM_GETTER_H + +#include <Pckt/CrFwPckt.h> +#include <CrFwConstants.h> + +/** + * Gets the value of the parameter Sid of the Define New Housekeeping Data Report packet. + * @param sid Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3DefineHkDrParamGetSid(unsigned char * sid, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Period of the Define New Housekeeping Data Report packet. + * @param period Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3DefineHkDrParamGetPeriod(unsigned short * period, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NoDataItemId of the Define New Housekeeping Data Report packet. + * @param noDataItemId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3DefineHkDrParamGetNoDataItemId(unsigned short * noDataItemId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter DataItemId of the Define New Housekeeping Data Report packet. + * @param dataItemId Pointer to the parameter that will be filled with data from the packet. + * @param length Length of dataItemId. + * @param pckt Pointer to the packet. + */ +void CrIaServ3DefineHkDrParamGetDataItemId(unsigned int * dataItemId, unsigned short length, unsigned short offset, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Sid of the Clear Housekeeping Data Report packet. + * @param sid Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3ClrHkDrParamGetSid(unsigned char * sid, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Sid of the Enable Housekeeping Data Report Generation packet. + * @param sid Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3EnbHkDrGenParamGetSid(unsigned char * sid, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Sid of the Disable Housekeeping Data Report Generation packet. + * @param sid Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3DisHkDrGenParamGetSid(unsigned char * sid, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Sid of the Set Housekeeping Reporting Destination packet. + * @param sid Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3SetHkRepDestParamGetSid(unsigned char * sid, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Dest of the Set Housekeeping Reporting Destination packet. + * @param dest Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3SetHkRepDestParamGetDest(unsigned short * dest, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Sid of the Set Housekeeping Reporting Frequency packet. + * @param sid Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3SetHkRepFreqParamGetSid(unsigned char * sid, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Spare of the Set Housekeeping Reporting Frequency packet. + * @param spare Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3SetHkRepFreqParamGetSpare(unsigned char * spare, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Period of the Set Housekeeping Reporting Frequency packet. + * @param period Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ3SetHkRepFreqParamGetPeriod(unsigned short * period, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter EvtId of the Enable Event Report Generation packet. + * @param evtId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ5EnbEvtRepGenParamGetEvtId(unsigned short * evtId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter EvtId of the Disable Event Report Generation packet. + * @param evtId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ5DisEvtRepGenParamGetEvtId(unsigned short * evtId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter DpuMemoryId of the Load Memory using Absolute Addresses packet. + * @param dpuMemoryId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ6LoadMemParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter StartAddress of the Load Memory using Absolute Addresses packet. + * @param startAddress Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ6LoadMemParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter BlockLength of the Load Memory using Absolute Addresses packet. + * @param blockLength Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ6LoadMemParamGetBlockLength(unsigned int * blockLength, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter BlockData of the Load Memory using Absolute Addresses packet. + * @param blockData Pointer to the parameter that will be filled with data from the packet. + * @param length Length of blockData. + * @param pckt Pointer to the packet. + */ +void CrIaServ6LoadMemParamGetBlockData(unsigned char * blockData, unsigned short length, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter DpuMemoryId of the Dump Memory using Absolute Addresses packet. + * @param dpuMemoryId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ6DumpMemParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter StartAddress of the Dump Memory using Absolute Addresses packet. + * @param startAddress Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ6DumpMemParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter BlockLength of the Dump Memory using Absolute Addresses packet. + * @param blockLength Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ6DumpMemParamGetBlockLength(unsigned int * blockLength, CrFwPckt_t pckt); + +void CrIaServ6DumpRepMemParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt); + +void CrIaServ6DumpRepMemParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt); + +void CrIaServ6DumpRepMemParamGetBlockLength(unsigned int * blockLength, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SduId of the Abort Downlink packet. + * @param sduId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ13AbrtDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt); + +void CrIaServ13FstDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt); + +void CrIaServ13IntmDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt); + +void CrIaServ13LastDwlkParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SduId of the Trigger Large Data Transfer packet. + * @param sduId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ13TrgLrgDataTsfrParamGetSduId(unsigned char * sduId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FdChkId of the Enable FdCheck packet. + * @param fdChkId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ191EnbFdChkParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FdChkId of the Disable FdCheck packet. + * @param fdChkId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ191DisFdChkParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FdChkId of the Enable Recovery Procedure packet. + * @param fdChkId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ191EnbRecovProcParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FdChkId of the Disable Recovery Procedure packet. + * @param fdChkId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ191DisRecovProcParamGetFdChkId(unsigned short * fdChkId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter AlgoId of the Start Algorithm packet. + * @param algoId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ194StartAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter AlgoParams of the Start Algorithm packet. + * @param algoParams Pointer to the parameter that will be filled with data from the packet. + * @param length Length of algoParams. + * @param pckt Pointer to the packet. + */ +void CrIaServ194StartAlgoParamGetAlgoParams(unsigned char * algoParams, unsigned short length, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter AlgoId of the Stop Algorithm packet. + * @param algoId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ194StopAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter AlgoId of the Suspend Algorithm packet. + * @param algoId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ194SusAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter AlgoId of the Resume Algorithm packet. + * @param algoId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ194ResAlgoParamGetAlgoId(unsigned short * algoId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter InitSaaCounter of the SAA Evaluation Algorithm packet. + * @param initSaaCounter Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ194SaaEvalAlgoParamGetInitSaaCounter(unsigned int * initSaaCounter, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ObservationId of the Star Map Command packet. + * @param observationId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ196StarMapCmdParamGetObservationId(unsigned int * observationId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter AcqAlgoId of the Star Map Command packet. + * @param acqAlgoId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ196StarMapCmdParamGetAcqAlgoId(unsigned short * acqAlgoId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SPARE of the Star Map Command packet. + * @param SPARE Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ196StarMapCmdParamGetSPARE(unsigned int * sPARE, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SkyPattern of the Star Map Command packet. + * @param skyPattern Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ196StarMapCmdParamGetSkyPattern(unsigned char * skyPattern, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter DpuMemoryId of the Generate Boot Report packet. + * @param dpuMemoryId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ197RepBootParamGetDpuMemoryId(unsigned short * dpuMemoryId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter StartAddress of the Generate Boot Report packet. + * @param startAddress Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ197RepBootParamGetStartAddress(unsigned int * startAddress, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ProcId of the Start Procedure packet. + * @param procId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ProcStartParamGetProcId(unsigned short * procId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ProcParams of the Start Procedure packet. + * @param procParams Pointer to the parameter that will be filled with data from the packet. + * @param length Length of procParams. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ProcStartParamGetProcParams(unsigned char * procParams, unsigned short length, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ProcId of the Stop Procedure packet. + * @param procId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ProcStopParamGetProcId(unsigned short * procId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SaveTarget of the Save Images Procedure packet. + * @param saveTarget Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SaveImgPrParamGetSaveTarget(unsigned short * saveTarget, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfInit of the Save Images Procedure packet. + * @param fbfInit Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SaveImgPrParamGetFbfInit(unsigned char * fbfInit, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfEnd of the Save Images Procedure packet. + * @param fbfEnd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SaveImgPrParamGetFbfEnd(unsigned char * fbfEnd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ExpTime of the Acquire Full Drop packet. + * @param expTime Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198AcqFullDropParamGetExpTime(unsigned int * expTime, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ImageRep of the Acquire Full Drop packet. + * @param imageRep Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198AcqFullDropParamGetImageRep(unsigned int * imageRep, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ExpTime of the Calibrate Full Snap packet. + * @param expTime Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198CalFullSnapParamGetExpTime(unsigned int * expTime, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ImageRep of the Calibrate Full Snap packet. + * @param imageRep Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198CalFullSnapParamGetImageRep(unsigned int * imageRep, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NmbImages of the Calibrate Full Snap packet. + * @param nmbImages Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198CalFullSnapParamGetNmbImages(unsigned int * nmbImages, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CentSel of the Calibrate Full Snap packet. + * @param centSel Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198CalFullSnapParamGetCentSel(unsigned short * centSel, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfId of the FBF Load Procedure packet. + * @param fbfId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfLoadPrParamGetFbfId(unsigned char * fbfId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfNBlocks of the FBF Load Procedure packet. + * @param fbfNBlocks Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfLoadPrParamGetFbfNBlocks(unsigned char * fbfNBlocks, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfRamAreaId of the FBF Load Procedure packet. + * @param fbfRamAreaId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfLoadPrParamGetFbfRamAreaId(unsigned short * fbfRamAreaId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfRamAddr of the FBF Load Procedure packet. + * @param fbfRamAddr Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfLoadPrParamGetFbfRamAddr(unsigned int * fbfRamAddr, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfId of the FBF Save Procedure packet. + * @param fbfId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfSavePrParamGetFbfId(unsigned char * fbfId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfNBlocks of the FBF Save Procedure packet. + * @param fbfNBlocks Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfSavePrParamGetFbfNBlocks(unsigned char * fbfNBlocks, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfRamAreaId of the FBF Save Procedure packet. + * @param fbfRamAreaId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfSavePrParamGetFbfRamAreaId(unsigned short * fbfRamAreaId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfRamAddr of the FBF Save Procedure packet. + * @param fbfRamAddr Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfSavePrParamGetFbfRamAddr(unsigned int * fbfRamAddr, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NmbImages of the Science Window Stack/Snap packet. + * @param nmbImages Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetNmbImages(unsigned int * nmbImages, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CcdRdMode of the Science Window Stack/Snap packet. + * @param ccdRdMode Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetCcdRdMode(unsigned short * ccdRdMode, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ExpTime of the Science Window Stack/Snap packet. + * @param expTime Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetExpTime(unsigned int * expTime, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ImageRep of the Science Window Stack/Snap packet. + * @param imageRep Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetImageRep(unsigned int * imageRep, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinPosX of the Science Window Stack/Snap packet. + * @param winPosX Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetWinPosX(unsigned short * winPosX, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinPosY of the Science Window Stack/Snap packet. + * @param winPosY Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetWinPosY(unsigned short * winPosY, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinSizeX of the Science Window Stack/Snap packet. + * @param winSizeX Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetWinSizeX(unsigned short * winSizeX, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinSizeY of the Science Window Stack/Snap packet. + * @param winSizeY Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetWinSizeY(unsigned short * winSizeY, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CentSel of the Science Window Stack/Snap packet. + * @param centSel Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198SciStackPrParamGetCentSel(unsigned short * centSel, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NmbFbf of the Transfer FBFs To Ground packet. + * @param nmbFbf Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfToGndPrParamGetNmbFbf(unsigned char * nmbFbf, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfInit of the Transfer FBFs To Ground packet. + * @param fbfInit Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfToGndPrParamGetFbfInit(unsigned char * fbfInit, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfSize of the Transfer FBFs To Ground packet. + * @param fbfSize Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198FbfToGndPrParamGetFbfSize(unsigned char * fbfSize, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter AcqFlag of the Nominal Science packet. + * @param acqFlag Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetAcqFlag(unsigned char * acqFlag, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Cal1Flag of the Nominal Science packet. + * @param cal1Flag Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCal1Flag(unsigned char * cal1Flag, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SciFlag of the Nominal Science packet. + * @param sciFlag Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetSciFlag(unsigned char * sciFlag, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter Cal2Flag of the Nominal Science packet. + * @param cal2Flag Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCal2Flag(unsigned char * cal2Flag, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibNFull of the Nominal Science packet. + * @param cibNFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCibNFull(unsigned char * cibNFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibSizeFull of the Nominal Science packet. + * @param cibSizeFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCibSizeFull(unsigned short * cibSizeFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibNFull of the Nominal Science packet. + * @param sibNFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetSibNFull(unsigned char * sibNFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibSizeFull of the Nominal Science packet. + * @param sibSizeFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetSibSizeFull(unsigned short * sibSizeFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibNFull of the Nominal Science packet. + * @param gibNFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetGibNFull(unsigned char * gibNFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibSizeFull of the Nominal Science packet. + * @param gibSizeFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetGibSizeFull(unsigned short * gibSizeFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibNWin of the Nominal Science packet. + * @param sibNWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetSibNWin(unsigned char * sibNWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibSizeWin of the Nominal Science packet. + * @param sibSizeWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetSibSizeWin(unsigned short * sibSizeWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibNWin of the Nominal Science packet. + * @param cibNWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCibNWin(unsigned char * cibNWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibSizeWin of the Nominal Science packet. + * @param cibSizeWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCibSizeWin(unsigned short * cibSizeWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibNWin of the Nominal Science packet. + * @param gibNWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetGibNWin(unsigned char * gibNWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibSizeWin of the Nominal Science packet. + * @param gibSizeWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetGibSizeWin(unsigned short * gibSizeWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ExpTimeAcq of the Nominal Science packet. + * @param expTimeAcq Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetExpTimeAcq(unsigned int * expTimeAcq, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ImageRepAcq of the Nominal Science packet. + * @param imageRepAcq Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetImageRepAcq(unsigned int * imageRepAcq, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ExpTimeCal1 of the Nominal Science packet. + * @param expTimeCal1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetExpTimeCal1(unsigned int * expTimeCal1, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ImageRepCal1 of the Nominal Science packet. + * @param imageRepCal1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetImageRepCal1(unsigned int * imageRepCal1, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NmbImagesCal1 of the Nominal Science packet. + * @param nmbImagesCal1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetNmbImagesCal1(unsigned int * nmbImagesCal1, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CentSelCal1 of the Nominal Science packet. + * @param centSelCal1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCentSelCal1(unsigned short * centSelCal1, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NmbImagesSci of the Nominal Science packet. + * @param nmbImagesSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetNmbImagesSci(unsigned int * nmbImagesSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CcdRdModeSci of the Nominal Science packet. + * @param ccdRdModeSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCcdRdModeSci(unsigned short * ccdRdModeSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ExpTimeSci of the Nominal Science packet. + * @param expTimeSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetExpTimeSci(unsigned int * expTimeSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ImageRepSci of the Nominal Science packet. + * @param imageRepSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetImageRepSci(unsigned int * imageRepSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinPosXSci of the Nominal Science packet. + * @param winPosXSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetWinPosXSci(unsigned short * winPosXSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinPosYSci of the Nominal Science packet. + * @param winPosYSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetWinPosYSci(unsigned short * winPosYSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinSizeXSci of the Nominal Science packet. + * @param winSizeXSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetWinSizeXSci(unsigned short * winSizeXSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter WinSizeYSci of the Nominal Science packet. + * @param winSizeYSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetWinSizeYSci(unsigned short * winSizeYSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CentSelSci of the Nominal Science packet. + * @param centSelSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCentSelSci(unsigned short * centSelSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ExpTimeCal2 of the Nominal Science packet. + * @param expTimeCal2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetExpTimeCal2(unsigned int * expTimeCal2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ImageRepCal2 of the Nominal Science packet. + * @param imageRepCal2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetImageRepCal2(unsigned int * imageRepCal2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NmbImagesCal2 of the Nominal Science packet. + * @param nmbImagesCal2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetNmbImagesCal2(unsigned int * nmbImagesCal2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CentSelCal2 of the Nominal Science packet. + * @param centSelCal2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetCentSelCal2(unsigned short * centSelCal2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SaveTarget of the Nominal Science packet. + * @param saveTarget Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetSaveTarget(unsigned short * saveTarget, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfInit of the Nominal Science packet. + * @param fbfInit Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetFbfInit(unsigned char * fbfInit, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FbfEnd of the Nominal Science packet. + * @param fbfEnd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetFbfEnd(unsigned char * fbfEnd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter StckOrderCal1 of the Nominal Science packet. + * @param stckOrderCal1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetStckOrderCal1(unsigned short * stckOrderCal1, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter StckOrderSci of the Nominal Science packet. + * @param stckOrderSci Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetStckOrderSci(unsigned short * stckOrderSci, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter StckOrderCal2 of the Nominal Science packet. + * @param stckOrderCal2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198NomSciPrParamGetStckOrderCal2(unsigned short * stckOrderCal2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SdbCmd of the Configure SDB packet. + * @param sdbCmd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetSdbCmd(unsigned short * sdbCmd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibNFull of the Configure SDB packet. + * @param cibNFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetCibNFull(unsigned char * cibNFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibSizeFull of the Configure SDB packet. + * @param cibSizeFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetCibSizeFull(unsigned short * cibSizeFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibNFull of the Configure SDB packet. + * @param sibNFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetSibNFull(unsigned char * sibNFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibSizeFull of the Configure SDB packet. + * @param sibSizeFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetSibSizeFull(unsigned short * sibSizeFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibNFull of the Configure SDB packet. + * @param gibNFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetGibNFull(unsigned char * gibNFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibSizeFull of the Configure SDB packet. + * @param gibSizeFull Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetGibSizeFull(unsigned short * gibSizeFull, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibNWin of the Configure SDB packet. + * @param sibNWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetSibNWin(unsigned char * sibNWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter SibSizeWin of the Configure SDB packet. + * @param sibSizeWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetSibSizeWin(unsigned short * sibSizeWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibNWin of the Configure SDB packet. + * @param cibNWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetCibNWin(unsigned char * cibNWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter CibSizeWin of the Configure SDB packet. + * @param cibSizeWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetCibSizeWin(unsigned short * cibSizeWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibNWin of the Configure SDB packet. + * @param gibNWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetGibNWin(unsigned char * gibNWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter GibSizeWin of the Configure SDB packet. + * @param gibSizeWin Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ198ConfigSdbPrParamGetGibSizeWin(unsigned short * gibSizeWin, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter NoParams of the Update Parameter packet. + * @param noParams Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ211UpdateParParamGetNoParams(unsigned short * noParams, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ParamId of the Update Parameter packet. + * @param paramId Pointer to the parameter that will be filled with data from the packet. + * @param offset Offset in bytes represents the parameter position in the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ211UpdateParParamGetParamId(unsigned int * paramId, unsigned short offset, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ParamType of the Update Parameter packet. + * @param paramType Pointer to the parameter that will be filled with data from the packet. + * @param offset Offset in bytes represents the parameter position in the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ211UpdateParParamGetParamType(unsigned char * paramType, unsigned short offset, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ArrayElemId of the Update Parameter packet. + * @param arrayElemId Pointer to the parameter that will be filled with data from the packet. + * @param offset Offset in bytes represents the parameter position in the packet. + * @param pckt Pointer to the packet. + */ +void CrIaServ211UpdateParParamGetArrayElemId(unsigned short * arrayElemId, unsigned short offset, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ParamValue of the Update Parameter packet. + * @param paramValue Pointer to the parameter that will be filled with data from the packet. + * @param offset Offset in bytes represents the parameter position in the packet. + * @param length Length of paramValue. + * @param pckt Pointer to the packet. + */ +void CrIaServ211UpdateParParamGetParamValue(unsigned char * paramValue, unsigned short offset, unsigned short length, CrFwPckt_t pckt); + +#endif /* CRIA_PARAM_GETTER_H */ + diff --git a/CrIa/src/Services/General/CrIaParamSetter.c b/CrIa/src/Services/General/CrIaParamSetter.c new file mode 100644 index 0000000000000000000000000000000000000000..c2e334b51deb28e89af256a92e75c57b49e48a03 --- /dev/null +++ b/CrIa/src/Services/General/CrIaParamSetter.c @@ -0,0 +1,1888 @@ +/** + * @file CrIaParamSetter.c + * @ingroup CrIaServicesGeneral + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the setter operations for all parameters of all out-going packets. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrIaParamSetter.h" +#include "CrIaConstants.h" +#include "CrFwCmpData.h" +#include "CrIaPckt.h" +#include "IfswUtilities.h" +#include "FwSmConfig.h" +#include <string.h> + + + +void CrIaServ1AccSuccParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (tcPacketId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (tcPacketId & 0xFF); + return; +} + +void CrIaServ1AccSuccParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (tcPacketSeqCtrl >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (tcPacketSeqCtrl & 0xFF); + return; +} + +void CrIaServ1AccFailParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (tcPacketId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (tcPacketId & 0xFF); + return; +} + +void CrIaServ1AccFailParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (tcPacketSeqCtrl >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (tcPacketSeqCtrl & 0xFF); + return; +} + +void CrIaServ1AccFailParamSetTcFailureCode(FwSmDesc_t smDesc, unsigned short tcFailureCode) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (tcFailureCode >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (tcFailureCode & 0xFF); + return; +} + +void CrIaServ1AccFailParamSetTcType(FwSmDesc_t smDesc, unsigned char tcType) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = tcType; + return; +} + +void CrIaServ1AccFailParamSetTcSubtype(FwSmDesc_t smDesc, unsigned char tcSubtype) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = tcSubtype; + return; +} + +void CrIaServ1AccFailParamSetTcLength(FwSmDesc_t smDesc, unsigned short tcLength) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = (tcLength >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = (tcLength & 0xFF); + return; +} + +void CrIaServ1AccFailParamSetTcReceivedBytes(FwSmDesc_t smDesc, unsigned short tcReceivedBytes) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = (tcReceivedBytes >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = (tcReceivedBytes & 0xFF); + return; +} + +void CrIaServ1AccFailParamSetTcReceivedCrc(FwSmDesc_t smDesc, unsigned short tcReceivedCrc) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12] = (tcReceivedCrc >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 13] = (tcReceivedCrc & 0xFF); + return; +} + +void CrIaServ1AccFailParamSetTcCalculatedCrc(FwSmDesc_t smDesc, unsigned short tcCalculatedCrc) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 14] = (tcCalculatedCrc >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 15] = (tcCalculatedCrc & 0xFF); + return; +} + +void CrIaServ1StartSuccParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (tcPacketId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (tcPacketId & 0xFF); + return; +} + +void CrIaServ1StartSuccParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (tcPacketSeqCtrl >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (tcPacketSeqCtrl & 0xFF); + return; +} + +void CrIaServ1StartFailParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (tcPacketId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (tcPacketId & 0xFF); + return; +} + +void CrIaServ1StartFailParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (tcPacketSeqCtrl >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (tcPacketSeqCtrl & 0xFF); + return; +} + +void CrIaServ1StartFailParamSetTcFailureCode(FwSmDesc_t smDesc, unsigned short tcFailureCode) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (tcFailureCode >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (char)(tcFailureCode & 0xFF); + return; +} + +void CrIaServ1StartFailParamSetTcType(FwSmDesc_t smDesc, unsigned char tcType) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = tcType; + return; +} + +void CrIaServ1StartFailParamSetTcSubtype(FwSmDesc_t smDesc, unsigned char tcSubtype) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = tcSubtype; + return; +} + +void CrIaServ1StartFailParamSetWrongParamPosition(FwSmDesc_t smDesc, unsigned short wrongParamPosition) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = (wrongParamPosition >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = (wrongParamPosition & 0xFF); + return; +} + +void CrIaServ1StartFailParamSetWrongParamValue(FwSmDesc_t smDesc, unsigned short wrongParamValue) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = (wrongParamValue >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = (wrongParamValue & 0xFF); + return; +} + +void CrIaServ1TermSuccParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (tcPacketId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (tcPacketId & 0xFF); + return; +} + +void CrIaServ1TermSuccParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (tcPacketSeqCtrl >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (tcPacketSeqCtrl & 0xFF); + return; +} + +void CrIaServ1TermFailParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (tcPacketId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (tcPacketId & 0xFF); + return; +} + +void CrIaServ1TermFailParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (tcPacketSeqCtrl >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (tcPacketSeqCtrl & 0xFF); + return; +} + +void CrIaServ1TermFailParamSetTcFailureCode(FwSmDesc_t smDesc, unsigned short tcFailureCode) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (tcFailureCode >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (tcFailureCode & 0xFF); + return; +} + +void CrIaServ1TermFailParamSetTcType(FwSmDesc_t smDesc, unsigned char tcType) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = tcType; + return; +} + +void CrIaServ1TermFailParamSetTcSubtype(FwSmDesc_t smDesc, unsigned char tcSubtype) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = tcSubtype; + return; +} + +void CrIaServ1TermFailParamSetWrongParamPosition(FwSmDesc_t smDesc, unsigned short wrongParamPosition) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = (wrongParamPosition >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = (wrongParamPosition & 0xFF); + return; +} + +void CrIaServ1TermFailParamSetWrongParamValue(FwSmDesc_t smDesc, unsigned short wrongParamValue) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = (wrongParamValue >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = (wrongParamValue & 0xFF); + return; +} + + +/* NOTE: we have inserted the event id here, and the remaining parameters are shifted by 2 bytes */ +void CrIaServ5EvtSetEvtId(FwSmDesc_t smDesc, unsigned short evtId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (evtId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (evtId & 0xFF); + return; +} + + +void CrIaServ5EvtSeqCntErrParamSetExpSeqCnt(FwSmDesc_t smDesc, unsigned short expSeqCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (expSeqCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (expSeqCnt & 0xFF); + return; +} + +void CrIaServ5EvtSeqCntErrParamSetActSeqCnt(FwSmDesc_t smDesc, unsigned short actSeqCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (actSeqCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (actSeqCnt & 0xFF); + return; +} + +void CrIaServ5EvtInrepCrFailParamSetRepSeqCnt(FwSmDesc_t smDesc, unsigned short repSeqCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (repSeqCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (repSeqCnt & 0xFF); + return; +} + +void CrIaServ5EvtPcrl2FullParamSetRepSeqCnt(FwSmDesc_t smDesc, unsigned short repSeqCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (repSeqCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (repSeqCnt & 0xFF); + return; +} + +void CrIaServ5EvtFdFailedParamSetFdCheckId(FwSmDesc_t smDesc, unsigned short fdCheckId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (fdCheckId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (fdCheckId & 0xFF); + return; +} + +void CrIaServ5EvtRpStartedParamSetFdCheckId(FwSmDesc_t smDesc, unsigned short fdCheckId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (fdCheckId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (fdCheckId & 0xFF); + return; +} + +void CrIaServ5EvtRpStartedParamSetRecovProcId(FwSmDesc_t smDesc, unsigned short recovProcId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (recovProcId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (recovProcId & 0xFF); + return; +} + +void CrIaServ5EvtSemTrParamSetSrcSemSt(FwSmDesc_t smDesc, unsigned short srcSemSt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (srcSemSt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (srcSemSt & 0xFF); + return; +} + +void CrIaServ5EvtSemTrParamSetDestSemSt(FwSmDesc_t smDesc, unsigned short destSemSt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (destSemSt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (destSemSt & 0xFF); + return; +} + +void CrIaServ5EvtIaswTrParamSetSrcIaswSt(FwSmDesc_t smDesc, unsigned short srcIaswSt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (srcIaswSt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (srcIaswSt & 0xFF); + return; +} + +void CrIaServ5EvtIaswTrParamSetDestIaswSt(FwSmDesc_t smDesc, unsigned short destIaswSt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (destIaswSt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (destIaswSt & 0xFF); + return; +} + +void CrIaServ5EvtSdscIllParamSetSciSeqCnt(FwSmDesc_t smDesc, unsigned short sciSeqCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (sciSeqCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (sciSeqCnt & 0xFF); + return; +} + +void CrIaServ5EvtSdscOosParamSetExpSciSeqCnt(FwSmDesc_t smDesc, unsigned short expSciSeqCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (expSciSeqCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (expSciSeqCnt & 0xFF); + return; +} + +void CrIaServ5EvtSdscOosParamSetActSciSeqCnt(FwSmDesc_t smDesc, unsigned short actSciSeqCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (actSciSeqCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (actSciSeqCnt & 0xFF); + return; +} + +void CrIaServ5EvtClctSizeParamSetGibSize(FwSmDesc_t smDesc, unsigned short gibSize) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (gibSize >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (gibSize & 0xFF); + return; +} + +void CrIaServ5EvtSibSizeParamSetSibSize(FwSmDesc_t smDesc, unsigned short sibSize) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (sibSize >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (sibSize & 0xFF); + return; +} + +void CrIaServ5EvtOolParamParamSetParamId(FwSmDesc_t smDesc, unsigned int paramId) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = ( paramId >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = ((paramId >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ((paramId >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ( paramId & 0xFF); +} + +void CrIaServ5EvtInvDestParamSetInvDest(FwSmDesc_t smDesc, unsigned short invDest) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (invDest >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (invDest & 0xFF); + return; +} + +void CrIaServ5EvtFbfLoadRiskParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (fbfId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (fbfId & 0xFF); + return; +} + +void CrIaServ5EvtFbfSaveDeniedParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (fbfId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (fbfId & 0xFF); + return; +} + +void CrIaServ5EvtFbfSaveAbrtParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (fbfId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (fbfId & 0xFF); + return; +} + +void CrIaServ5EvtFbfSaveAbrtParamSetFbfNBlocks(FwSmDesc_t smDesc, unsigned short fbfNBlocks) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (fbfNBlocks >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (fbfNBlocks & 0xFF); + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetProcId(FwSmDesc_t smDesc, unsigned short procId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (procId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (procId & 0xFF); + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetCibNFull(FwSmDesc_t smDesc, unsigned char cibNFull) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = cibNFull; + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetCibSizeFull(FwSmDesc_t smDesc, unsigned short cibSizeFull) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ((cibSizeFull >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = ( cibSizeFull & 0xFF); + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetSibNFull(FwSmDesc_t smDesc, unsigned char sibNFull) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = sibNFull; + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetSibSizeFull(FwSmDesc_t smDesc, unsigned short sibSizeFull) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = ((sibSizeFull >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = ( sibSizeFull & 0xFF); + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetGibNFull(FwSmDesc_t smDesc, unsigned char gibNFull) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = gibNFull; + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetGibSizeFull(FwSmDesc_t smDesc, unsigned short gibSizeFull) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = ((gibSizeFull >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12] = ( gibSizeFull & 0xFF); + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetSibNWin(FwSmDesc_t smDesc, unsigned char sibNWin) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 13] = sibNWin; + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetSibSizeWin(FwSmDesc_t smDesc, unsigned short sibSizeWin) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 14] = ((sibSizeWin >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 15] = ( sibSizeWin & 0xFF); + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetCibNWin(FwSmDesc_t smDesc, unsigned char cibNWin) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 16] = cibNWin; + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetCibSizeWin(FwSmDesc_t smDesc, unsigned short cibSizeWin) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 17] = ((cibSizeWin >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 18] = ( cibSizeWin & 0xFF); + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetGibNWin(FwSmDesc_t smDesc, unsigned char gibNWin) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 19] = gibNWin; + return; +} + +void CrIaServ5EvtSdbCnfFailParamSetGibSizeWin(FwSmDesc_t smDesc, unsigned short gibSizeWin) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 20] = ((gibSizeWin >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 21] = ( gibSizeWin & 0xFF); + return; +} + +void CrIaServ5EvtCmprSizeParamSetImgBufferSize(FwSmDesc_t smDesc, unsigned int reqSize) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = ( reqSize >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = ((reqSize >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ((reqSize >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ( reqSize & 0xFF); + return; +} + +void CrIaServ5EvtSemopTrParamSetSrcSemOpSt(FwSmDesc_t smDesc, unsigned short srcSemOpSt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (srcSemOpSt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (srcSemOpSt & 0xFF); + return; +} + +void CrIaServ5EvtSemopTrParamSetDestSemOpSt(FwSmDesc_t smDesc, unsigned short destSemOpSt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (destSemOpSt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (destSemOpSt & 0xFF); + return; +} + +void CrIaServ5EvtScPrStrtParamSetProcId(FwSmDesc_t smDesc, unsigned short procId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (procId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (procId & 0xFF); + return; +} + +void CrIaServ5EvtScPrEndParamSetProcId(FwSmDesc_t smDesc, unsigned short procId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (procId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (procId & 0xFF); + return; +} + +void CrIaServ5EvtScPrEndParamSetProcTermCode(FwSmDesc_t smDesc, unsigned short procTermCode) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (procTermCode >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (procTermCode & 0xFF); + return; +} + +void CrIaServ5EvtInstrmPqfParamSetInStreamId(FwSmDesc_t smDesc, unsigned short inStreamId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (inStreamId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (inStreamId & 0xFF); + return; +} + +void CrIaServ5EvtOcmpInvdParamSetOutCompId(FwSmDesc_t smDesc, unsigned short outCompId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (outCompId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (outCompId & 0xFF); + return; +} + +void CrIaServ5EvtOcmpInvdParamSetInvDest(FwSmDesc_t smDesc, unsigned short invDest) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (invDest >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (invDest & 0xFF); + return; +} + +void CrIaServ5EvtOcmpIllgrParamSetOutStreamId(FwSmDesc_t smDesc, unsigned short outStreamId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (outStreamId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (outStreamId & 0xFF); + return; +} + +void CrIaServ5EvtOcmpIllgrParamSetGroupId(FwSmDesc_t smDesc, unsigned char groupId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = groupId; + return; +} + +void CrIaServ5EvtInIllgrParamSetInStreamId(FwSmDesc_t smDesc, unsigned short inStreamId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (inStreamId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (inStreamId & 0xFF); + return; +} + +void CrIaServ5EvtInIllgrParamSetGroupId(FwSmDesc_t smDesc, unsigned char groupId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = groupId; + return; +} + +void CrIaServ5EvtSemIllStParamSetSemStateId(FwSmDesc_t smDesc, unsigned short semStateId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (semStateId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (semStateId & 0xFF); + return; +} + +void CrIaServ5EvtSemIllStParamSetSemOpStateId(FwSmDesc_t smDesc, unsigned short semOpStateId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (semOpStateId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (semOpStateId & 0xFF); + return; +} + +void CrIaServ5EvtInitFailParamSetNoOfErrors(FwSmDesc_t smDesc, unsigned short noOfErrors) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (noOfErrors >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (noOfErrors & 0xFF); + return; +} + +void CrIaServ5EvtInitFailParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5EvtThrdOrParamSetThrdId(FwSmDesc_t smDesc, unsigned short thrdId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (thrdId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (thrdId & 0xFF); + return; +} + +void CrIaServ5EvtThrdOrParamSetThrdOrSize(FwSmDesc_t smDesc, unsigned short thrdOrSize) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (thrdOrSize >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (thrdOrSize & 0xFF); + return; +} + +void CrIaServ5EvtNotifErrParamSetContdId(FwSmDesc_t smDesc, unsigned short contdId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (contdId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (contdId & 0xFF); + return; +} + +void CrIaServ5EvtNotifErrParamSetNotifCnt(FwSmDesc_t smDesc, unsigned short notifCnt) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (notifCnt >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (notifCnt & 0xFF); + return; +} + +void CrIaServ5Evt1553ErrLParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5Evt1553ErrMParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5Evt1553ErrHParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5EvtSpwErrLParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5EvtSpwErrMParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5EvtSpwErrHParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5EvtFlElErrParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5EvtFlElErrParamSetFlashAdd(FwSmDesc_t smDesc, unsigned int flashAdd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ( flashAdd >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ((flashAdd >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = ((flashAdd >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = ( flashAdd & 0xFF); + return; +} + +void CrIaServ5EvtFlFbfErrParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (ibswErrNo >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (ibswErrNo & 0xFF); + return; +} + +void CrIaServ5EvtFlFbfErrParamSetFlashAdd(FwSmDesc_t smDesc, unsigned int flashAdd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ( flashAdd >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ((flashAdd >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = ((flashAdd >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = ( flashAdd & 0xFF); + return; +} + +void CrIaServ5EvtFlFbfErrParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = (fbfId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = (fbfId & 0xFF); + return; +} + +void CrIaServ5EvtFlFbfBbParamSetChipId(FwSmDesc_t smDesc, unsigned short chipId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (chipId >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (chipId & 0xFF); + return; +} + +void CrIaServ5EvtFlFbfBbParamSetBlck(FwSmDesc_t smDesc, unsigned short blck) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (blck >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (blck & 0xFF); + return; +} + +void CrIaServ5EvtSbitErrParamSetRamAdd(FwSmDesc_t smDesc, unsigned int ramAdd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = ( ramAdd >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = ((ramAdd >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ((ramAdd >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ( ramAdd & 0xFF); + return; +} + +void CrIaServ5EvtDbitErrParamSetRamAdd(FwSmDesc_t smDesc, unsigned int ramAdd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = ( ramAdd >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = ((ramAdd >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ((ramAdd >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ( ramAdd & 0xFF); + return; +} + +/* ### TM(5,3) EVT_SDP ### */ + +void CrIaServ5EvtSdpNomemParamSetStepNmb(FwSmDesc_t smDesc, unsigned short stepNmb) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (stepNmb >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (stepNmb & 0xFF); + return; +} + +void CrIaServ5EvtSdpNomemParamSetDebugVal(FwSmDesc_t smDesc, unsigned short debugVal) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (debugVal >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (debugVal & 0xFF); + return; +} + +void CrIaServ5EvtProcbufInsufParamSetProductID(FwSmDesc_t smDesc, unsigned short productID) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (productID >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (productID & 0xFF); + return; +} + +void CrIaServ5EvtProcbufInsufParamSetReqSize(FwSmDesc_t smDesc, unsigned int reqSize) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ( reqSize >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ((reqSize >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = ((reqSize >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = ( reqSize & 0xFF); + return; +} + +void CrIaServ5EvtProcbufInsufParamSetAvailSize(FwSmDesc_t smDesc, unsigned int availSize) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = ( availSize >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = ((availSize >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = ((availSize >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = ( availSize & 0xFF); + return; +} + +void CrIaServ5EvtXibFullParamSetBufID(FwSmDesc_t smDesc, unsigned short bufID) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (bufID >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (bufID & 0xFF); + return; +} + +void CrIaServ5EvtImgInsufParamSetProductID(FwSmDesc_t smDesc, unsigned short productID) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (productID >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (productID & 0xFF); + return; +} + +void CrIaServ5EvtImgInsufParamSetStepID(FwSmDesc_t smDesc, unsigned short stepID) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (stepID >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = (stepID & 0xFF); + return; +} + +void CrIaServ5EvtImgInsufParamSetReqSize(FwSmDesc_t smDesc, unsigned int reqSize) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = ( reqSize >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = ((reqSize >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = ((reqSize >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = ( reqSize & 0xFF); + return; +} + +void CrIaServ5EvtImgInsufParamSetAvailSize(FwSmDesc_t smDesc, unsigned int availSize) { + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = ( availSize >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = ((availSize >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12] = ((availSize >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 13] = ( availSize & 0xFF); + return; +} + + +/* ### END OF TM(5,3) EVT_SDP ### */ + + +void CrIaServ6MemDumpParamSetDpuMemoryId(FwSmDesc_t smDesc, unsigned short dpuMemoryId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (dpuMemoryId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (dpuMemoryId & 0xFF); + return; +} + +void CrIaServ6MemDumpParamSetStartAddress(FwSmDesc_t smDesc, unsigned int startAddress) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = ( startAddress >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = ((startAddress >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = ((startAddress >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = ( startAddress & 0xFF); + return; +} + +void CrIaServ6MemDumpParamSetBlockLength(FwSmDesc_t smDesc, unsigned int blockLength) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = ( blockLength >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = ((blockLength >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = ((blockLength >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = ( blockLength & 0xFF); + return; +} + +void CrIaServ6MemDumpParamSetBlockData(FwSmDesc_t smDesc, const unsigned char * blockData, unsigned short length) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10], blockData, length); + return; +} + +void CrIaServ13FstDwlkParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = sduId; + return; +} + +void CrIaServ13FstDwlkParamSetSduBlockCount(FwSmDesc_t smDesc, unsigned short sduBlockCount) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (sduBlockCount >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (sduBlockCount & 0xFF); + return; +} + +void CrIaServ13FstDwlkParamSetSduBlockLength(FwSmDesc_t smDesc, unsigned short sduBlockLength) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (sduBlockLength >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (sduBlockLength & 0xFF); + return; +} + +void CrIaServ13FstDwlkParamSetSduBlockData(FwSmDesc_t smDesc, const unsigned char * sduBlockData, unsigned short length) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5], sduBlockData, length); + return; +} + +void CrIaServ13IntmDwlkParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = sduId; + return; +} + +void CrIaServ13IntmDwlkParamSetSduBlockCount(FwSmDesc_t smDesc, unsigned short sduBlockCount) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (sduBlockCount >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (sduBlockCount & 0xFF); + return; +} + +void CrIaServ13IntmDwlkParamSetSduBlockLength(FwSmDesc_t smDesc, unsigned short sduBlockLength) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (sduBlockLength >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (sduBlockLength & 0xFF); + return; +} + +void CrIaServ13IntmDwlkParamSetSduBlockData(FwSmDesc_t smDesc, const unsigned char * sduBlockData, unsigned short length) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5], sduBlockData, length); + return; +} + +void CrIaServ13LastDwlkParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = sduId; + return; +} + +void CrIaServ13LastDwlkParamSetSduBlockCount(FwSmDesc_t smDesc, unsigned short sduBlockCount) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (sduBlockCount >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (sduBlockCount & 0xFF); + return; +} + +void CrIaServ13LastDwlkParamSetSduBlockLength(FwSmDesc_t smDesc, unsigned short sduBlockLength) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (sduBlockLength >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (sduBlockLength & 0xFF); + return; +} + +void CrIaServ13LastDwlkParamSetSduBlockData(FwSmDesc_t smDesc, const unsigned char * sduBlockData, unsigned short length) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5], sduBlockData, length); + return; +} + +void CrIaServ13DwlkAbrtParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = sduId; + return; +} + +void CrIaServ13DwlkAbrtParamSetReasonCode(FwSmDesc_t smDesc, unsigned short reasonCode) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (reasonCode >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = (reasonCode & 0xFF); + return; +} + +void CrIaServ195HbRepParamSetHbData(FwSmDesc_t smDesc, unsigned short hbData) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (hbData >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (hbData & 0xFF); + return; +} + +void CrIaServ195HbRepParamSetHbSEM(FwSmDesc_t smDesc, unsigned char hbSEM) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = hbSEM; + return; +} + +/* endianess safe */ +void CrIaServ196AocsRepParamSetOffsetX(FwSmDesc_t smDesc, int offsetX) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = (offsetX >> 16) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = (offsetX >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = offsetX & 0xff; + /* memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0], offsetX, 3); */ + return; +} + +void CrIaServ196AocsRepParamSetOffsetY(FwSmDesc_t smDesc, int offsetY) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = (offsetY >> 16) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4] = (offsetY >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 5] = offsetY & 0xff; + /* memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3], offsetY, 3); */ + return; +} + +void CrIaServ196AocsRepParamSetTargetLocationX(FwSmDesc_t smDesc, unsigned int targetLocationX) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6] = (targetLocationX >> 16) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 7] = (targetLocationX >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 8] = targetLocationX & 0xff; + /* memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 6], targetLocationX, 3); */ + return; +} + +void CrIaServ196AocsRepParamSetTargetLocationY(FwSmDesc_t smDesc, unsigned int targetLocationY) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9] = (targetLocationY >> 16) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = (targetLocationY >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = targetLocationY & 0xff; + /* memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 9], targetLocationY, 3); */ + return; +} + +/* endianess safe */ +void CrIaServ196AocsRepParamSetIntegStartTimeCrs (FwSmDesc_t smDesc, unsigned int integStartTimeCrs) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12] = (integStartTimeCrs >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 13] = (integStartTimeCrs >> 16) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 14] = (integStartTimeCrs >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 15] = integStartTimeCrs & 0xff; + /* memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12], integStartTime, 6); */ + return; +} + +/* endianess safe */ +void CrIaServ196AocsRepParamSetIntegStartTimeFine (FwSmDesc_t smDesc, unsigned short integStartTimeFine) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 16] = (integStartTimeFine >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 17] = integStartTimeFine & 0xff; + return; +} + +/* endianess safe */ +void CrIaServ196AocsRepParamSetIntegEndTimeCrs (FwSmDesc_t smDesc, unsigned int integEndTimeCrs) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 18] = (integEndTimeCrs >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 19] = (integEndTimeCrs >> 16) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 20] = (integEndTimeCrs >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 21] = integEndTimeCrs & 0xff; + /* memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 18], integEndTimeCrs, 6); */ + return; +} + +/* endianess safe */ +void CrIaServ196AocsRepParamSetIntegEndTimeFine (FwSmDesc_t smDesc, unsigned short integEndTimeFine) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 22] = (integEndTimeFine >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 23] = integEndTimeFine & 0xff; + return; +} + +/* endianess safe */ +void CrIaServ196AocsRepParamSetCentroidDataCadence (FwSmDesc_t smDesc, unsigned short centroidDataCadence) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 24] = (centroidDataCadence >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 25] = (centroidDataCadence & 0xFF); + return; +} + +/* endianess safe */ +void CrIaServ196AocsRepParamSetValidityStatus(FwSmDesc_t smDesc, unsigned char validityStatus) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 26] = validityStatus; + return; +} + + +void CrIaServ197BootRepParamSetResetType(FwSmDesc_t smDesc, unsigned char resetType) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 0] = resetType; + return; +} + +void CrIaServ197BootRepParamSetDpuMode(FwSmDesc_t smDesc, unsigned char dpuMode) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuMode, 0, 4, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = SetBits(tempByte, dpuMode, 0, 4); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuSwActive(FwSmDesc_t smDesc, unsigned char dpuSwActive) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuSwActive, 4, 2, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = SetBits(tempByte, dpuSwActive, 4, 2); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuWatchdogStatus(FwSmDesc_t smDesc, unsigned char dpuWatchdogStatus) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutBit8 (dpuWatchdogStatus, 6, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = SetBits(tempByte, dpuWatchdogStatus, 6, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuUnit(FwSmDesc_t smDesc, unsigned char dpuUnit) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutBit8 (dpuUnit, 7, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 1] = SetBits(tempByte, dpuUnit, 7, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuResetType(FwSmDesc_t smDesc, unsigned char dpuResetType) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuResetType, 0, 3, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = SetBits(tempByte, dpuResetType, 0, 3); + */ + return; +} + +void CrIaServ197BootRepParamSetTimeSyncStatus(FwSmDesc_t smDesc, unsigned char timeSyncStatus) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (timeSyncStatus, 3, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = SetBits(tempByte, timeSyncStatus, 3, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetBootReportSent(FwSmDesc_t smDesc, unsigned char bootReportSent) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (bootReportSent, 4, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = SetBits(tempByte, bootReportSent, 4, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetSpare1(FwSmDesc_t smDesc, unsigned char spare1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (spare1, 5, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = SetBits(tempByte, spare1, 5, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetSemError(FwSmDesc_t smDesc, unsigned char semError) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (semError, 6, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = SetBits(tempByte, semError, 6, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetSemOn(FwSmDesc_t smDesc, unsigned char semOn) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (semOn, 7, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 2] = SetBits(tempByte, semOn, 7, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuScLinkStatus(FwSmDesc_t smDesc, unsigned char dpuScLinkStatus) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuScLinkStatus, 0, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = SetBits(tempByte, dpuScLinkStatus, 0, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuMilbusCoreEx(FwSmDesc_t smDesc, unsigned char dpuMilbusCoreEx) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuMilbusCoreEx, 1, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = SetBits(tempByte, dpuMilbusCoreEx, 1, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuMilbusSyncDw(FwSmDesc_t smDesc, unsigned char dpuMilbusSyncDw) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuMilbusSyncDw, 2, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = SetBits(tempByte, dpuMilbusSyncDw, 2, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuMilbusSyncTo(FwSmDesc_t smDesc, unsigned char dpuMilbusSyncTo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuMilbusSyncTo, 3, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = SetBits(tempByte, dpuMilbusSyncTo, 3, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuSemLinkStatus(FwSmDesc_t smDesc, unsigned char dpuSemLinkStatus) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuSemLinkStatus, 4, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = SetBits(tempByte, dpuSemLinkStatus, 4, 1); + */ + return; +} + +void CrIaServ197BootRepParamSetDpuSemLinkState(FwSmDesc_t smDesc, unsigned char dpuSemLinkState) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + PutNBits8 (dpuSemLinkState, 5, 3, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3])); + /* + unsigned char tempByte = cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3]; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 3] = SetBits(tempByte, dpuSemLinkState, 5, 3); + */ + return; +} + +void CrIaServ197BootRepParamSetResetTime(FwSmDesc_t smDesc, const unsigned char * resetTime) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 4], resetTime, 6); + return; +} + +void CrIaServ197BootRepParamSetTrapCore1(FwSmDesc_t smDesc, unsigned char trapCore1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 10] = trapCore1; + return; +} + +void CrIaServ197BootRepParamSetTrapCore2(FwSmDesc_t smDesc, unsigned char trapCore2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 11] = trapCore2; + return; +} + +void CrIaServ197BootRepParamSetPsrRegCore1(FwSmDesc_t smDesc, unsigned int psrRegCore1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 12] = ( psrRegCore1 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 13] = ((psrRegCore1 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 14] = ((psrRegCore1 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 15] = ( psrRegCore1 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetWimRegCore1(FwSmDesc_t smDesc, unsigned int wimRegCore1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 16] = ( wimRegCore1 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 17] = ((wimRegCore1 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 18] = ((wimRegCore1 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 19] = ( wimRegCore1 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetPcRegCore1(FwSmDesc_t smDesc, unsigned int pcRegCore1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 20] = ( pcRegCore1 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 21] = ((pcRegCore1 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 22] = ((pcRegCore1 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 23] = ( pcRegCore1 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetNpcRegCore1(FwSmDesc_t smDesc, unsigned int npcRegCore1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 24] = ( npcRegCore1 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 25] = ((npcRegCore1 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 26] = ((npcRegCore1 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 27] = ( npcRegCore1 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetFsrRegCore1(FwSmDesc_t smDesc, unsigned int fsrRegCore1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 28] = ( fsrRegCore1 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 29] = ((fsrRegCore1 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 30] = ((fsrRegCore1 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 31] = ( fsrRegCore1 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetPsrRegCore2(FwSmDesc_t smDesc, unsigned int psrRegCore2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 32] = ( psrRegCore2 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 33] = ((psrRegCore2 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 34] = ((psrRegCore2 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 35] = ( psrRegCore2 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetWimRegCore2(FwSmDesc_t smDesc, unsigned int wimRegCore2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 36] = ( wimRegCore2 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 37] = ((wimRegCore2 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 38] = ((wimRegCore2 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 39] = ( wimRegCore2 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetPcRegCore2(FwSmDesc_t smDesc, unsigned int pcRegCore2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 40] = ( pcRegCore2 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 41] = ((pcRegCore2 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 42] = ((pcRegCore2 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 43] = ( pcRegCore2 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetNpcRegCore2(FwSmDesc_t smDesc, unsigned int npcRegCore2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 44] = ( npcRegCore2 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 45] = ((npcRegCore2 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 46] = ((npcRegCore2 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 47] = ( npcRegCore2 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetFsrRegCore2(FwSmDesc_t smDesc, unsigned int fsrRegCore2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 48] = ( fsrRegCore2 >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 49] = ((fsrRegCore2 >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 50] = ((fsrRegCore2 >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 51] = ( fsrRegCore2 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetAhbStatusReg(FwSmDesc_t smDesc, unsigned int ahbStatusReg) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 52] = ( ahbStatusReg >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 53] = ((ahbStatusReg >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 54] = ((ahbStatusReg >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 55] = ( ahbStatusReg & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetAhbFailingAddrReg(FwSmDesc_t smDesc, unsigned int ahbFailingAddrReg) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 56] = ( ahbFailingAddrReg >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 57] = ((ahbFailingAddrReg >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 58] = ((ahbFailingAddrReg >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 59] = ( ahbFailingAddrReg & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetPcHistoryCore1(FwSmDesc_t smDesc, const unsigned char * pcHistoryCore1) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 60], pcHistoryCore1, 28); + return; +} + +void CrIaServ197BootRepParamSetPcHistoryCore2(FwSmDesc_t smDesc, const unsigned char * pcHistoryCore2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 88], pcHistoryCore2, 28); + return; +} + +void CrIaServ197BootRepParamSetSpare2(FwSmDesc_t smDesc, unsigned short spare2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 116] = (spare2 >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 117] = (spare2 & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetDpuMemoryId(FwSmDesc_t smDesc, unsigned short dpuMemoryId) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 118] = (dpuMemoryId >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 119] = (dpuMemoryId & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetStartAddress(FwSmDesc_t smDesc, unsigned int startAddress) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 120] = ( startAddress >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 121] = ((startAddress >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 122] = ((startAddress >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 123] = ( startAddress & 0xFF); + return; +} + +void CrIaServ197BootRepParamSetErrLogInfo(FwSmDesc_t smDesc, const unsigned char * errLogInfo) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + 124], errLogInfo, 880); /* was: + 132, 12 */ + return; +} + +/** + * Set data at specific position in data segment of PUS packet + * Author: Christian + */ + +void CrIaSetUCharValue(FwSmDesc_t smDesc, unsigned char ucharValue, unsigned int pos) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + pos] = ucharValue; + return; +} + +void CrIaSetUShortValue(FwSmDesc_t smDesc, unsigned short ushortValue, unsigned int pos) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + pos] = (ushortValue >> 8) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + pos + 1] = (ushortValue & 0xFF); + return; +} + +void CrIaSetUIntValue(FwSmDesc_t smDesc, unsigned int uintValue, unsigned int pos) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + pos] = ( uintValue >> 24) & 0xff; + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + pos + 1] = ((uintValue >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + pos + 2] = ((uintValue >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_REP_PCKT + pos + 3] = ( uintValue & 0xFF); + + return; +} + diff --git a/CrIa/src/Services/General/CrIaParamSetter.h b/CrIa/src/Services/General/CrIaParamSetter.h new file mode 100644 index 0000000000000000000000000000000000000000..e6020e21aad12ca6116b4dde18274a6f5efa74df --- /dev/null +++ b/CrIa/src/Services/General/CrIaParamSetter.h @@ -0,0 +1,1093 @@ +/** + * @file CrIaParamSetter.h + * + * Declaration of the setter operations for all parameters of all out-going packets. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRIA_PARAM_SETTER_H +#define CRIA_PARAM_SETTER_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +void PutBit8 (unsigned char value, unsigned int bitOffset, unsigned char *dest); + +void PutNBits8 (unsigned int value, unsigned int bitOffset, unsigned int nbits, unsigned char *dest); + + +/** + * Sets the value of the parameter TcPacketId of the out-going packet Telecommand Acceptance Report – Success. + * @param tcPacketId Copy of the PACKET ID fields of the command being reported on. + */ +void CrIaServ1AccSuccParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId); + +/** + * Sets the value of the parameter TcPacketSeqCtrl of the out-going packet Telecommand Acceptance Report – Success. + * @param tcPacketSeqCtrl Copy of the PACKET SEQUENCE CONTROL fields of the received command. + */ +void CrIaServ1AccSuccParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl); + +/** + * Sets the value of the parameter TcPacketId of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcPacketId Copy of the PACKET ID fields of the command being reported on. + */ +void CrIaServ1AccFailParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId); + +/** + * Sets the value of the parameter TcPacketSeqCtrl of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcPacketSeqCtrl Copy of the PACKET SEQUENCE CONTROL fields of the received command. + */ +void CrIaServ1AccFailParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl); + +/** + * Sets the value of the parameter TcFailureCode of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcFailureCode The failure identification code. See table \ref{tab:EFailureCode} for the full overview of the failure identification code. + */ +void CrIaServ1AccFailParamSetTcFailureCode(FwSmDesc_t smDesc, unsigned short tcFailureCode); + +/** + * Sets the value of the parameter TcType of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcType Packet type from the received TC. + */ +void CrIaServ1AccFailParamSetTcType(FwSmDesc_t smDesc, unsigned char tcType); + +/** + * Sets the value of the parameter TcSubtype of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcSubtype Packet sub-type from the received TC. + */ +void CrIaServ1AccFailParamSetTcSubtype(FwSmDesc_t smDesc, unsigned char tcSubtype); + +/** + * Sets the value of the parameter TcLength of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcLength Length of the received TC. + */ +void CrIaServ1AccFailParamSetTcLength(FwSmDesc_t smDesc, unsigned short tcLength); + +/** + * Sets the value of the parameter TcReceivedBytes of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcReceivedBytes Number of received bytes. + */ +void CrIaServ1AccFailParamSetTcReceivedBytes(FwSmDesc_t smDesc, unsigned short tcReceivedBytes); + +/** + * Sets the value of the parameter TcReceivedCrc of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcReceivedCrc CRC received with TC. + */ +void CrIaServ1AccFailParamSetTcReceivedCrc(FwSmDesc_t smDesc, unsigned short tcReceivedCrc); + +/** + * Sets the value of the parameter TcCalculatedCrc of the out-going packet Telecommand Acceptance Report – Failure. + * @param tcCalculatedCrc Calculated CRC. + */ +void CrIaServ1AccFailParamSetTcCalculatedCrc(FwSmDesc_t smDesc, unsigned short tcCalculatedCrc); + +/** + * Sets the value of the parameter TcPacketId of the out-going packet Telecommand Start Report – Success. + * @param tcPacketId Copy of the PACKET ID fields of the command being reported on. + */ +void CrIaServ1StartSuccParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId); + +/** + * Sets the value of the parameter TcPacketSeqCtrl of the out-going packet Telecommand Start Report – Success. + * @param tcPacketSeqCtrl Copy of the PACKET SEQUENCE CONTROL fields of the received command. + */ +void CrIaServ1StartSuccParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl); + +/** + * Sets the value of the parameter TcPacketId of the out-going packet Telecommand Start Report – Failure. + * @param tcPacketId Copy of the PACKET ID fields of the command being reported on. + */ +void CrIaServ1StartFailParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId); + +/** + * Sets the value of the parameter TcPacketSeqCtrl of the out-going packet Telecommand Start Report – Failure. + * @param tcPacketSeqCtrl Copy of the PACKET SEQUENCE CONTROL fields of the received command. + */ +void CrIaServ1StartFailParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl); + +/** + * Sets the value of the parameter TcFailureCode of the out-going packet Telecommand Start Report – Failure. + * @param tcFailureCode Failure identification code. See table \ref{tab:EFailureCode} for the full overview of the failure identification code. + */ +void CrIaServ1StartFailParamSetTcFailureCode(FwSmDesc_t smDesc, unsigned short tcFailureCode); + +/** + * Sets the value of the parameter TcType of the out-going packet Telecommand Start Report – Failure. + * @param tcType Packet type from the received TC. + */ +void CrIaServ1StartFailParamSetTcType(FwSmDesc_t smDesc, unsigned char tcType); + +/** + * Sets the value of the parameter TcSubtype of the out-going packet Telecommand Start Report – Failure. + * @param tcSubtype Packet sub-type from the received TC. + */ +void CrIaServ1StartFailParamSetTcSubtype(FwSmDesc_t smDesc, unsigned char tcSubtype); + +/** + * Sets the value of the parameter WrongParamPosition of the out-going packet Telecommand Start Report – Failure. + * @param wrongParamPosition Position of the parameter with wrong value in the received command, or zero if the failure cannot be linked to a wrong command parameter value. For example, a value of 2 will mean: "second parameter in the report". + */ +void CrIaServ1StartFailParamSetWrongParamPosition(FwSmDesc_t smDesc, unsigned short wrongParamPosition); + +/** + * Sets the value of the parameter WrongParamValue of the out-going packet Telecommand Start Report – Failure. + * @param wrongParamValue Wrong value of the parameter. + */ +void CrIaServ1StartFailParamSetWrongParamValue(FwSmDesc_t smDesc, unsigned short wrongParamValue); + +/** + * Sets the value of the parameter TcPacketId of the out-going packet Telecommand Termination Report – Success. + * @param tcPacketId Copy of the PACKET ID fields of the command being reported on. + */ +void CrIaServ1TermSuccParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId); + +/** + * Sets the value of the parameter TcPacketSeqCtrl of the out-going packet Telecommand Termination Report – Success. + * @param tcPacketSeqCtrl Copy of the PACKET SEQUENCE CONTROL fields of the received command. + */ +void CrIaServ1TermSuccParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl); + +/** + * Sets the value of the parameter TcPacketId of the out-going packet Telecommand Termination Report – Failure. + * @param tcPacketId Copy of the PACKET ID fields of the command being reported on. + */ +void CrIaServ1TermFailParamSetTcPacketId(FwSmDesc_t smDesc, unsigned short tcPacketId); + +/** + * Sets the value of the parameter TcPacketSeqCtrl of the out-going packet Telecommand Termination Report – Failure. + * @param tcPacketSeqCtrl Copy of the PACKET SEQUENCE CONTROL fields of the received command. + */ +void CrIaServ1TermFailParamSetTcPacketSeqCtrl(FwSmDesc_t smDesc, unsigned short tcPacketSeqCtrl); + +/** + * Sets the value of the parameter TcFailureCode of the out-going packet Telecommand Termination Report – Failure. + * @param tcFailureCode Failure identification code. See table \ref{tab:EFailureCode} for the full overview of the failure identification code. + */ +void CrIaServ1TermFailParamSetTcFailureCode(FwSmDesc_t smDesc, unsigned short tcFailureCode); + +/** + * Sets the value of the parameter TcType of the out-going packet Telecommand Termination Report – Failure. + * @param tcType Packet type from the received TC. + */ +void CrIaServ1TermFailParamSetTcType(FwSmDesc_t smDesc, unsigned char tcType); + +/** + * Sets the value of the parameter TcSubtype of the out-going packet Telecommand Termination Report – Failure. + * @param tcSubtype Packet sub-type from the received TC. + */ +void CrIaServ1TermFailParamSetTcSubtype(FwSmDesc_t smDesc, unsigned char tcSubtype); + +/** + * Sets the value of the parameter WrongParamPosition of the out-going packet Telecommand Termination Report – Failure. + * @param wrongParamPosition Position of the parameter with wrong value in the received command, or zero if the failure cannot be linked to a wrong command parameter value. For example, a value of 2 will mean: "second parameter in the report". + */ +void CrIaServ1TermFailParamSetWrongParamPosition(FwSmDesc_t smDesc, unsigned short wrongParamPosition); + +/** + * Sets the value of the parameter WrongParamValue of the out-going packet Telecommand Termination Report – Failure. + * @param wrongParamValue Wrong value of the parameter. + */ +void CrIaServ1TermFailParamSetWrongParamValue(FwSmDesc_t smDesc, unsigned short wrongParamValue); + +void CrIaServ5EvtSetEvtId(FwSmDesc_t smDesc, unsigned short evtId); + +/** + * Sets the value of the parameter ExpSeqCnt of the out-going packet Event Sequence Counter Error. + * @param expSeqCnt The expected value of the sequence counter. + */ +void CrIaServ5EvtSeqCntErrParamSetExpSeqCnt(FwSmDesc_t smDesc, unsigned short expSeqCnt); + +/** + * Sets the value of the parameter ActSeqCnt of the out-going packet Event Sequence Counter Error. + * @param actSeqCnt The actual value of the sequence counter. + */ +void CrIaServ5EvtSeqCntErrParamSetActSeqCnt(FwSmDesc_t smDesc, unsigned short actSeqCnt); + +/** + * Sets the value of the parameter RepSeqCnt of the out-going packet Event In Rep Cr Fail. + * @param repSeqCnt The sequence counter of the report. + */ +void CrIaServ5EvtInrepCrFailParamSetRepSeqCnt(FwSmDesc_t smDesc, unsigned short repSeqCnt); + +/** + * Sets the value of the parameter RepSeqCnt of the out-going packet Event Pcrl2 Full. + * @param repSeqCnt The sequence counter of the report. + */ +void CrIaServ5EvtPcrl2FullParamSetRepSeqCnt(FwSmDesc_t smDesc, unsigned short repSeqCnt); + +/** + * Sets the value of the parameter FdCheckId of the out-going packet Event Failure Detection Failed. + * @param fdCheckId The FdCheck identifier. See table \ref{tab:EFdChkId} for the full overview of the FdCheck identifiers. + */ +void CrIaServ5EvtFdFailedParamSetFdCheckId(FwSmDesc_t smDesc, unsigned short fdCheckId); + +/** + * Sets the value of the parameter FdCheckId of the out-going packet Event Recovery Procedure Started. + * @param fdCheckId The FdCheck identifier. See table \ref{tab:EFdChkId} for the full overview of the FdCheck identifiers. + */ +void CrIaServ5EvtRpStartedParamSetFdCheckId(FwSmDesc_t smDesc, unsigned short fdCheckId); + +/** + * Sets the value of the parameter RecovProcId of the out-going packet Event Recovery Procedure Started. + * @param recovProcId The recovery procedure identifier. See table \ref{tab:ERecovProcId} for the full overview of the recovery procedure identifiers. + */ +void CrIaServ5EvtRpStartedParamSetRecovProcId(FwSmDesc_t smDesc, unsigned short recovProcId); + +/** + * Sets the value of the parameter SrcSemSt of the out-going packet Event SEM State Machine Transition. + * @param srcSemSt The source state identifier. + */ +void CrIaServ5EvtSemTrParamSetSrcSemSt(FwSmDesc_t smDesc, unsigned short srcSemSt); + +/** + * Sets the value of the parameter DestSemSt of the out-going packet Event SEM State Machine Transition. + * @param destSemSt The destination state identifier. + */ +void CrIaServ5EvtSemTrParamSetDestSemSt(FwSmDesc_t smDesc, unsigned short destSemSt); + +/** + * Sets the value of the parameter SrcIaswSt of the out-going packet Event IASW State Machine Transition. + * @param srcIaswSt The source state identifier. + */ +void CrIaServ5EvtIaswTrParamSetSrcIaswSt(FwSmDesc_t smDesc, unsigned short srcIaswSt); + +/** + * Sets the value of the parameter DestIaswSt of the out-going packet Event IASW State Machine Transition. + * @param destIaswSt The destination state identifier. + */ +void CrIaServ5EvtIaswTrParamSetDestIaswSt(FwSmDesc_t smDesc, unsigned short destIaswSt); + +/** + * Sets the value of the parameter SciSeqCnt of the out-going packet Event SDSC Illegal. + * @param sciSeqCnt The science data sequence counter. + */ +void CrIaServ5EvtSdscIllParamSetSciSeqCnt(FwSmDesc_t smDesc, unsigned short sciSeqCnt); + +/** + * Sets the value of the parameter ExpSciSeqCnt of the out-going packet Event SDSC Out-of-sequence. + * @param expSciSeqCnt The expected value of the science data sequence counter. + */ +void CrIaServ5EvtSdscOosParamSetExpSciSeqCnt(FwSmDesc_t smDesc, unsigned short expSciSeqCnt); + +/** + * Sets the value of the parameter ActSciSeqCnt of the out-going packet Event SDSC Out-of-sequence. + * @param actSciSeqCnt The actual value of the science data sequence counter. + */ +void CrIaServ5EvtSdscOosParamSetActSciSeqCnt(FwSmDesc_t smDesc, unsigned short actSciSeqCnt); + +/** + * Sets the value of the parameter GibSize of the out-going packet Event Collection Algorithm out of Space. + * @param gibSize The size of the GIB which caused the violation. + */ +void CrIaServ5EvtClctSizeParamSetGibSize(FwSmDesc_t smDesc, unsigned short gibSize); + +/** + * Sets the value of the parameter SibSize of the out-going packet Event Science Image Buffer size. + * @param sibSize The SIB size in kBytes. + */ +void CrIaServ5EvtSibSizeParamSetSibSize(FwSmDesc_t smDesc, unsigned short sibSize); + +/** + * Sets the value of the parameter ParamId of the out-going packet Parameter Out-Of-Limits. + * @param paramId The identifier of the OOL parameter. + */ +void CrIaServ5EvtOolParamParamSetParamId(FwSmDesc_t smDesc, unsigned int paramId); + +/** + * Sets the value of the parameter InvDest of the out-going packet Event Invalid Destination. + * @param invDest The invalid destination. + */ +void CrIaServ5EvtInvDestParamSetInvDest(FwSmDesc_t smDesc, unsigned short invDest); + +/** + * Sets the value of the parameter FbfId of the out-going packet Event FBF Load Risk. + * @param fbfId The FBF identifier. + */ +void CrIaServ5EvtFbfLoadRiskParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId); + +/** + * Sets the value of the parameter FbfId of the out-going packet Event FBF Save Denied. + * @param fbfId The FBF identifier. + */ +void CrIaServ5EvtFbfSaveDeniedParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId); + +/** + * Sets the value of the parameter FbfId of the out-going packet Event FBF Save Abort. + * @param fbfId The FBF identifier. + */ +void CrIaServ5EvtFbfSaveAbrtParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId); + +/** + * Sets the value of the parameter FbfNBlocks of the out-going packet Event FBF Save Abort. + * @param fbfNBlocks The number of blocks written to flash up to the time when the FBF Save Procedure is aborted. + */ +void CrIaServ5EvtFbfSaveAbrtParamSetFbfNBlocks(FwSmDesc_t smDesc, unsigned short fbfNBlocks); + +/** + * Sets the value of the parameter ProcId of the out-going packet Event SDB Configuration Failed. + * @param procId The identifier of science procedure. + */ +void CrIaServ5EvtSdbCnfFailParamSetProcId(FwSmDesc_t smDesc, unsigned short procId); + +/** + * Sets the value of the parameter CibNFull of the out-going packet Event SDB Configuration Failed. + * @param cibNFull The number of CIBs for Full CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetCibNFull(FwSmDesc_t smDesc, unsigned char cibNFull); + +/** + * Sets the value of the parameter CibSizeFull of the out-going packet Event SDB Configuration Failed. + * @param cibSizeFull The size in kBytes of the CIBs for Full CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetCibSizeFull(FwSmDesc_t smDesc, unsigned short cibSizeFull); + +/** + * Sets the value of the parameter SibNFull of the out-going packet Event SDB Configuration Failed. + * @param sibNFull The number of SIBs for Full CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetSibNFull(FwSmDesc_t smDesc, unsigned char sibNFull); + +/** + * Sets the value of the parameter SibSizeFull of the out-going packet Event SDB Configuration Failed. + * @param sibSizeFull The size in kBytes of the SIBs for Full CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetSibSizeFull(FwSmDesc_t smDesc, unsigned short sibSizeFull); + +/** + * Sets the value of the parameter GibNFull of the out-going packet Event SDB Configuration Failed. + * @param gibNFull The number of GIBs for Full CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetGibNFull(FwSmDesc_t smDesc, unsigned char gibNFull); + +/** + * Sets the value of the parameter GibSizeFull of the out-going packet Event SDB Configuration Failed. + * @param gibSizeFull The size in kBytes of the GIBs for Full CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetGibSizeFull(FwSmDesc_t smDesc, unsigned short gibSizeFull); + +/** + * Sets the value of the parameter SibNWin of the out-going packet Event SDB Configuration Failed. + * @param sibNWin The number of SIBs for Window CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetSibNWin(FwSmDesc_t smDesc, unsigned char sibNWin); + +/** + * Sets the value of the parameter SibSizeWin of the out-going packet Event SDB Configuration Failed. + * @param sibSizeWin The size in kBytes of the SIBs for Window CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetSibSizeWin(FwSmDesc_t smDesc, unsigned short sibSizeWin); + +/** + * Sets the value of the parameter CibNWin of the out-going packet Event SDB Configuration Failed. + * @param cibNWin The number of CIBs for Window CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetCibNWin(FwSmDesc_t smDesc, unsigned char cibNWin); + +/** + * Sets the value of the parameter CibSizeWin of the out-going packet Event SDB Configuration Failed. + * @param cibSizeWin The size in kBytes of the CIBs for Window CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetCibSizeWin(FwSmDesc_t smDesc, unsigned short cibSizeWin); + +/** + * Sets the value of the parameter GibNWin of the out-going packet Event SDB Configuration Failed. + * @param gibNWin The number of GIBs for Window CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetGibNWin(FwSmDesc_t smDesc, unsigned char gibNWin); + +/** + * Sets the value of the parameter GibSizeWin of the out-going packet Event SDB Configuration Failed. + * @param gibSizeWin The size in kBytes of the GIBs for Window CCD Images. + */ +void CrIaServ5EvtSdbCnfFailParamSetGibSizeWin(FwSmDesc_t smDesc, unsigned short gibSizeWin); + +/** + * Sets the value of the parameter ImgBufferSize of the out-going packet Event Compression Algorithm out of Space. + * @param imgBufferSize The size of the CIB which caused the violation. + */ +void CrIaServ5EvtCmprSizeParamSetImgBufferSize(FwSmDesc_t smDesc, unsigned int imgBufferSize); + +/** + * Sets the value of the parameter SrcSemOpSt of the out-going packet Event SEM OP State Machine Transition. + * @param srcSemOpSt The source state identifier. + */ +void CrIaServ5EvtSemopTrParamSetSrcSemOpSt(FwSmDesc_t smDesc, unsigned short srcSemOpSt); + +/** + * Sets the value of the parameter DestSemOpSt of the out-going packet Event SEM OP State Machine Transition. + * @param destSemOpSt The destination state identifier. + */ +void CrIaServ5EvtSemopTrParamSetDestSemOpSt(FwSmDesc_t smDesc, unsigned short destSemOpSt); + +/** + * Sets the value of the parameter ProcId of the out-going packet Event Science Procedure Starts Execution. + * @param procId The procedure identifier. + */ +void CrIaServ5EvtScPrStrtParamSetProcId(FwSmDesc_t smDesc, unsigned short procId); + +/** + * Sets the value of the parameter ProcId of the out-going packet Event Science Procedure Terminates Execution. + * @param procId The procedure identifier. + */ +void CrIaServ5EvtScPrEndParamSetProcId(FwSmDesc_t smDesc, unsigned short procId); + +/** + * Sets the value of the parameter ProcTermCode of the out-going packet Event Science Procedure Terminates Execution. + * @param procTermCode The procedure termination code. + */ +void CrIaServ5EvtScPrEndParamSetProcTermCode(FwSmDesc_t smDesc, unsigned short procTermCode); + +/** + * Sets the value of the parameter InStreamId of the out-going packet Event InStream Packet Queue Full. + * @param inStreamId The InStream identifier. + */ +void CrIaServ5EvtInstrmPqfParamSetInStreamId(FwSmDesc_t smDesc, unsigned short inStreamId); + +/** + * Sets the value of the parameter OutCompId of the out-going packet Event OutComponent Invalid Destination. + * @param outCompId The OutComponent identifier. + */ +void CrIaServ5EvtOcmpInvdParamSetOutCompId(FwSmDesc_t smDesc, unsigned short outCompId); + +/** + * Sets the value of the parameter InvDest of the out-going packet Event OutComponent Invalid Destination. + * @param invDest The invalid destination. + */ +void CrIaServ5EvtOcmpInvdParamSetInvDest(FwSmDesc_t smDesc, unsigned short invDest); + +/** + * Sets the value of the parameter OutStreamId of the out-going packet Event OutComponent Illegal Group Identifier. + * @param outStreamId The OutStream identifier. + */ +void CrIaServ5EvtOcmpIllgrParamSetOutStreamId(FwSmDesc_t smDesc, unsigned short outStreamId); + +/** + * Sets the value of the parameter GroupId of the out-going packet Event OutComponent Illegal Group Identifier. + * @param groupId The illegal group identifier. + */ +void CrIaServ5EvtOcmpIllgrParamSetGroupId(FwSmDesc_t smDesc, unsigned char groupId); + +/** + * Sets the value of the parameter InStreamId of the out-going packet Event InStream Illegal Group Identifier. + * @param inStreamId The InStream identifier. + */ +void CrIaServ5EvtInIllgrParamSetInStreamId(FwSmDesc_t smDesc, unsigned short inStreamId); + +/** + * Sets the value of the parameter GroupId of the out-going packet Event InStream Illegal Group Identifier. + * @param groupId The illegal group identifier. + */ +void CrIaServ5EvtInIllgrParamSetGroupId(FwSmDesc_t smDesc, unsigned char groupId); + +/** + * Sets the value of the parameter SemStateId of the out-going packet Illegal SEM State at Entry in PRE_SCIENCE. + * @param semStateId The SEM State Machine state identifier. + */ +void CrIaServ5EvtSemIllStParamSetSemStateId(FwSmDesc_t smDesc, unsigned short semStateId); + +/** + * Sets the value of the parameter SemOpStateId of the out-going packet Illegal SEM State at Entry in PRE_SCIENCE. + * @param semOpStateId The SEM Operational State Machine state identifier. + */ +void CrIaServ5EvtSemIllStParamSetSemOpStateId(FwSmDesc_t smDesc, unsigned short semOpStateId); + +/** + * Sets the value of the parameter NoOfErrors of the out-going packet IASW Initialization Failed. + * @param noOfErrors The number of errors. + */ +void CrIaServ5EvtInitFailParamSetNoOfErrors(FwSmDesc_t smDesc, unsigned short noOfErrors); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet IASW Initialization Failed. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5EvtInitFailParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter ThrdId of the out-going packet Thread Overrun. + * @param thrdId The thread identifier. + */ +void CrIaServ5EvtThrdOrParamSetThrdId(FwSmDesc_t smDesc, unsigned short thrdId); + +/** + * Sets the value of the parameter ThrdOrSize of the out-going packet Thread Overrun. + * @param thrdOrSize The extent of the thread overrun. + */ +void CrIaServ5EvtThrdOrParamSetThrdOrSize(FwSmDesc_t smDesc, unsigned short thrdOrSize); + +/** + * Sets the value of the parameter ContdId of the out-going packet Notification Error. + * @param contdId The identifier of the RT Container. + */ +void CrIaServ5EvtNotifErrParamSetContdId(FwSmDesc_t smDesc, unsigned short contdId); + +/** + * Sets the value of the parameter NotifCnt of the out-going packet Notification Error. + * @param notifCnt The value of the notification counter. + */ +void CrIaServ5EvtNotifErrParamSetNotifCnt(FwSmDesc_t smDesc, unsigned short notifCnt); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet Low-severity 1553 Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5Evt1553ErrLParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet Medium-severity 1553 Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5Evt1553ErrMParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet High-severity 1553 Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5Evt1553ErrHParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet Low-severity SpaceWire Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5EvtSpwErrLParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet Medium-severity SpaceWire Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5EvtSpwErrMParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet High-severity SpaceWire Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5EvtSpwErrHParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet Flash-Based Error Log Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5EvtFlElErrParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter FlashAdd of the out-going packet Flash-Based Error Log Error. + * @param flashAdd The index of the 32-bit word in flash where the error occurred. + */ +void CrIaServ5EvtFlElErrParamSetFlashAdd(FwSmDesc_t smDesc, unsigned int flashAdd); + +/** + * Sets the value of the parameter IbswErrNo of the out-going packet Flash-Based File Error. + * @param ibswErrNo Error code (see doxygen documentation of errors.h). + */ +void CrIaServ5EvtFlFbfErrParamSetIbswErrNo(FwSmDesc_t smDesc, unsigned short ibswErrNo); + +/** + * Sets the value of the parameter FlashAdd of the out-going packet Flash-Based File Error. + * @param flashAdd The index of the 32-bit word in flash where the error occurred. + */ +void CrIaServ5EvtFlFbfErrParamSetFlashAdd(FwSmDesc_t smDesc, unsigned int flashAdd); + +/** + * Sets the value of the parameter FbfId of the out-going packet Flash-Based File Error. + * @param fbfId The identifier of the FBF where the error occurred. + */ +void CrIaServ5EvtFlFbfErrParamSetFbfId(FwSmDesc_t smDesc, unsigned short fbfId); + +/** + * Sets the value of the parameter ChipId of the out-going packet Flash Bad Block Encountered. + * @param chipId The identifier of the flash chip where the error occurred. + */ +void CrIaServ5EvtFlFbfBbParamSetChipId(FwSmDesc_t smDesc, unsigned short chipId); + +/** + * Sets the value of the parameter Blck of the out-going packet Flash Bad Block Encountered. + * @param blck The block where the error occurred (NB: a block is 1 MB, or 0x100000). + */ +void CrIaServ5EvtFlFbfBbParamSetBlck(FwSmDesc_t smDesc, unsigned short blck); + +/** + * Sets the value of the parameter RamAdd of the out-going packet Single Bit EDAC Error. + * @param ramAdd The RAM address where the error occurred. + */ +void CrIaServ5EvtSbitErrParamSetRamAdd(FwSmDesc_t smDesc, unsigned int ramAdd); + +/** + * Sets the value of the parameter RamAdd of the out-going packet Double Bit EDAC Error. + * @param ramAdd The RAM address where the error occurred. + */ +void CrIaServ5EvtDbitErrParamSetRamAdd(FwSmDesc_t smDesc, unsigned int ramAdd); + +/** + * Sets the value of the parameter StepNmb of the out-going packet SDP Failure. + * @param stepNmb The identifier of the science data processing step where the error occurred. + */ +void CrIaServ5EvtSdpNomemParamSetStepNmb(FwSmDesc_t smDesc, unsigned short stepNmb); + +/** + * Sets the value of the parameter DebugVal of the out-going packet SDP Failure. + * @param debugVal Debug value. + */ +void CrIaServ5EvtSdpNomemParamSetDebugVal(FwSmDesc_t smDesc, unsigned short debugVal); + +/** + * Sets the value of the parameter ProductID of the out-going packet Science Buffer Too Small. + * @param productID The product identifier. + */ +void CrIaServ5EvtProcbufInsufParamSetProductID(FwSmDesc_t smDesc, unsigned short productID); + +/** + * Sets the value of the parameter ReqSize of the out-going packet Science Buffer Too Small. + * @param reqSize The requested size in bytes. + */ +void CrIaServ5EvtProcbufInsufParamSetReqSize(FwSmDesc_t smDesc, unsigned int reqSize); + +/** + * Sets the value of the parameter AvailSize of the out-going packet Science Buffer Too Small. + * @param availSize The available size in bytes. + */ +void CrIaServ5EvtProcbufInsufParamSetAvailSize(FwSmDesc_t smDesc, unsigned int availSize); + +/** + * Sets the value of the parameter BufID of the out-going packet SIB or GIB Cannot Be Incremented. + * @param bufID The buffer identifier. + */ +void CrIaServ5EvtXibFullParamSetBufID(FwSmDesc_t smDesc, unsigned short bufID); + +/** + * Sets the value of the parameter ProductID of the out-going packet Image Too Large. + * @param productID The product identifier. + */ +void CrIaServ5EvtImgInsufParamSetProductID(FwSmDesc_t smDesc, unsigned short productID); + +/** + * Sets the value of the parameter StepID of the out-going packet Image Too Large. + * @param stepID The step identifier. + */ +void CrIaServ5EvtImgInsufParamSetStepID(FwSmDesc_t smDesc, unsigned short stepID); + +/** + * Sets the value of the parameter ReqSize of the out-going packet Image Too Large. + * @param reqSize The requested size in bytes. + */ +void CrIaServ5EvtImgInsufParamSetReqSize(FwSmDesc_t smDesc, unsigned int reqSize); + +/** + * Sets the value of the parameter AvailSize of the out-going packet Image Too Large. + * @param availSize The available size in bytes. + */ +void CrIaServ5EvtImgInsufParamSetAvailSize(FwSmDesc_t smDesc, unsigned int availSize); + +/** + * Sets the value of the parameter DpuMemoryId of the out-going packet Memory Dump using Absolute Addresses Report. + * @param dpuMemoryId The DPU memory identifier. See table \ref{tab:EDpuMemoryId} for the full overview of the DPU memory identifiers. + */ +void CrIaServ6MemDumpParamSetDpuMemoryId(FwSmDesc_t smDesc, unsigned short dpuMemoryId); + +/** + * Sets the value of the parameter StartAddress of the out-going packet Memory Dump using Absolute Addresses Report. + * @param startAddress The start address to be dumped. + */ +void CrIaServ6MemDumpParamSetStartAddress(FwSmDesc_t smDesc, unsigned int startAddress); + +/** + * Sets the value of the parameter BlockLength of the out-going packet Memory Dump using Absolute Addresses Report. + * @param blockLength The length of area to be dumped in number of bytes. + */ +void CrIaServ6MemDumpParamSetBlockLength(FwSmDesc_t smDesc, unsigned int blockLength); + +/** + * Sets the value of the parameter BlockData of the out-going packet Memory Dump using Absolute Addresses Report. + * @param blockData The dumped block data. + * @param length The data length in bytes. + */ +void CrIaServ6MemDumpParamSetBlockData(FwSmDesc_t smDesc, const unsigned char * blockData, unsigned short length); + +/** + * Sets the value of the parameter SduId of the out-going packet First Downlink Part Report. + * @param sduId The identifier of SDU being transferred. + */ +void CrIaServ13FstDwlkParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId); + +/** + * Sets the value of the parameter SduBlockCount of the out-going packet First Downlink Part Report. + * @param sduBlockCount The SDU block counter. + */ +void CrIaServ13FstDwlkParamSetSduBlockCount(FwSmDesc_t smDesc, unsigned short sduBlockCount); + +/** + * Sets the value of the parameter SduBlockLength of the out-going packet First Downlink Part Report. + * @param sduBlockLength The length of the data block being transferred in bytes. + */ +void CrIaServ13FstDwlkParamSetSduBlockLength(FwSmDesc_t smDesc, unsigned short sduBlockLength); + +/** + * Sets the value of the parameter SduBlockData of the out-going packet First Downlink Part Report. + * @param sduBlockData The first data block. + * @param length The data length in bytes. + */ +void CrIaServ13FstDwlkParamSetSduBlockData(FwSmDesc_t smDesc, const unsigned char * sduBlockData, unsigned short length); + +/** + * Sets the value of the parameter SduId of the out-going packet Intermediate Downlink Part Report. + * @param sduId The identifier of SDU being transferred. + */ +void CrIaServ13IntmDwlkParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId); + +/** + * Sets the value of the parameter SduBlockCount of the out-going packet Intermediate Downlink Part Report. + * @param sduBlockCount The SDU block counter. + */ +void CrIaServ13IntmDwlkParamSetSduBlockCount(FwSmDesc_t smDesc, unsigned short sduBlockCount); + +/** + * Sets the value of the parameter SduBlockLength of the out-going packet Intermediate Downlink Part Report. + * @param sduBlockLength The length of the data block being transferred in bytes. + */ +void CrIaServ13IntmDwlkParamSetSduBlockLength(FwSmDesc_t smDesc, unsigned short sduBlockLength); + +/** + * Sets the value of the parameter SduBlockData of the out-going packet Intermediate Downlink Part Report. + * @param sduBlockData The N-th data block. + * @param length The data length in bytes. + */ +void CrIaServ13IntmDwlkParamSetSduBlockData(FwSmDesc_t smDesc, const unsigned char * sduBlockData, unsigned short length); + +/** + * Sets the value of the parameter SduId of the out-going packet Last Downlink Part Report. + * @param sduId The identifier of SDU being transferred. + */ +void CrIaServ13LastDwlkParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId); + +/** + * Sets the value of the parameter SduBlockCount of the out-going packet Last Downlink Part Report. + * @param sduBlockCount The SDU block counter. + */ +void CrIaServ13LastDwlkParamSetSduBlockCount(FwSmDesc_t smDesc, unsigned short sduBlockCount); + +/** + * Sets the value of the parameter SduBlockLength of the out-going packet Last Downlink Part Report. + * @param sduBlockLength The length of the data block being transferred in bytes. + */ +void CrIaServ13LastDwlkParamSetSduBlockLength(FwSmDesc_t smDesc, unsigned short sduBlockLength); + +/** + * Sets the value of the parameter SduBlockData of the out-going packet Last Downlink Part Report. + * @param sduBlockData The last data block. + * @param length The data length in bytes. + */ +void CrIaServ13LastDwlkParamSetSduBlockData(FwSmDesc_t smDesc, const unsigned char * sduBlockData, unsigned short length); + +/** + * Sets the value of the parameter SduId of the out-going packet Downlink Abort Report. + * @param sduId The identifier of SDU being aborted. + */ +void CrIaServ13DwlkAbrtParamSetSduId(FwSmDesc_t smDesc, unsigned char sduId); + +/** + * Sets the value of the parameter ReasonCode of the out-going packet Downlink Abort Report. + * @param reasonCode The reason code of abortion. + */ +void CrIaServ13DwlkAbrtParamSetReasonCode(FwSmDesc_t smDesc, unsigned short reasonCode); + +/** + * Sets the value of the parameter HbData of the out-going packet Heartbeat Report. + * @param hbData The heartbeat data, toggling between HEARTBEAT\_D1 and HEARTBEAT\_D2 values. + */ +void CrIaServ195HbRepParamSetHbData(FwSmDesc_t smDesc, unsigned short hbData); + +/** + * Sets the value of the parameter HbSEM of the out-going packet Heartbeat Report. + * @param hbSEM The SEM thermal control status. + */ +void CrIaServ195HbRepParamSetHbSEM(FwSmDesc_t smDesc, unsigned char hbSEM); + +/** + * Sets the value of the parameter OffsetX of the out-going packet AOCS Report. + * @param offsetX The offset from the target position in X-axis in [centi-arcseconds]. This is the residual in X-axis that should be corrected. + */ +void CrIaServ196AocsRepParamSetOffsetX(FwSmDesc_t smDesc, int offsetX); /* was: const char * offsetX */ + +/** + * Sets the value of the parameter OffsetY of the out-going packet AOCS Report. + * @param offsetY The offset from the target position in Y-axis in [centi-arcseconds]. This is the residual in Y-axis that should be corrected. + */ +void CrIaServ196AocsRepParamSetOffsetY(FwSmDesc_t smDesc, int offsetY); /* was: const char * offsetX */ + +/** + * Sets the value of the parameter TargetLocationX of the out-going packet AOCS Report. + * @param targetLocationX The X position on the CCD where the target shall to be located in [centi-arcseconds]. Origin = bottom left pixel corner (center of bottom left pixel is thus [50/50]), counting in Cartesian coordinates. + */ +void CrIaServ196AocsRepParamSetTargetLocationX(FwSmDesc_t smDesc, unsigned int targetLocationX); /* was: const unsigned char * targetLocationX */ + +/** + * Sets the value of the parameter TargetLocationY of the out-going packet AOCS Report. + * @param targetLocationY The Y position on the CCD where the target shall to be located in [centi-arcseconds]. Origin = bottom left pixel corner (center of bottom left pixel is thus [50/50]), counting in Cartesian coordinates. + */ +void CrIaServ196AocsRepParamSetTargetLocationY(FwSmDesc_t smDesc, unsigned int targetLocationY); /* was: const unsigned char * targetLocationY */ + +/** + * Sets the value of the parameter IntegStartTime of the out-going packet AOCS Report. + * @param integStartTime The time stamp of exposure start used for the centroid calculation. + */ +void CrIaServ196AocsRepParamSetIntegStartTimeCrs(FwSmDesc_t smDesc, unsigned int integStartTimeCrs); +void CrIaServ196AocsRepParamSetIntegStartTimeFine(FwSmDesc_t smDesc, unsigned short integStartTimeFine); /* was: const unsigned char * integStartTime */ + +/** + * Sets the value of the parameter IntegEndTime of the out-going packet AOCS Report. + * @param integEndTime The time stamp of exposure end used for the centroid calculation. + */ +void CrIaServ196AocsRepParamSetIntegEndTimeCrs(FwSmDesc_t smDesc, unsigned int integEndTimeCrs); +void CrIaServ196AocsRepParamSetIntegEndTimeFine(FwSmDesc_t smDesc, unsigned short integEndTimeFine); /* was: const unsigned char * integEndTime */ + +/** + * Sets the value of the parameter CentroidDataCadence of the out-going packet AOCS Report. + * @param centroidDataCadence The centroid data cadence time in centiseconds. CCD Window mode: 1 to 60 seconds. CCD Full mode: nominal 5 seconds (range 1..60 seconds). + */ +void CrIaServ196AocsRepParamSetCentroidDataCadence(FwSmDesc_t smDesc, unsigned short centroidDataCadence); + +/** + * Sets the value of the parameter ValidityStatus of the out-going packet AOCS Report. + * @param validityStatus The outcome of Validity Procedure. + */ +void CrIaServ196AocsRepParamSetValidityStatus(FwSmDesc_t smDesc, unsigned char validityStatus); + +/** + * Sets the value of the parameter ResetType of the out-going packet Boot Report. + * @param resetType The reset trigger type. + */ +void CrIaServ197BootRepParamSetResetType(FwSmDesc_t smDesc, unsigned char resetType); + +/** + * Sets the value of the parameter DpuMode of the out-going packet Boot Report. + * @param dpuMode The DPU mode. + */ +void CrIaServ197BootRepParamSetDpuMode(FwSmDesc_t smDesc, unsigned char dpuMode); + +/** + * Sets the value of the parameter DpuSwActive of the out-going packet Boot Report. + * @param dpuSwActive The active software on DPU. + */ +void CrIaServ197BootRepParamSetDpuSwActive(FwSmDesc_t smDesc, unsigned char dpuSwActive); + +/** + * Sets the value of the parameter DpuWatchdogStatus of the out-going packet Boot Report. + * @param dpuWatchdogStatus The DPU watchdog status. + */ +void CrIaServ197BootRepParamSetDpuWatchdogStatus(FwSmDesc_t smDesc, unsigned char dpuWatchdogStatus); + +/** + * Sets the value of the parameter DpuUnit of the out-going packet Boot Report. + * @param dpuUnit The DPU unit. + */ +void CrIaServ197BootRepParamSetDpuUnit(FwSmDesc_t smDesc, unsigned char dpuUnit); + +/** + * Sets the value of the parameter DpuResetType of the out-going packet Boot Report. + * @param dpuResetType The DPU reset type. + */ +void CrIaServ197BootRepParamSetDpuResetType(FwSmDesc_t smDesc, unsigned char dpuResetType); + +/** + * Sets the value of the parameter TimeSyncStatus of the out-going packet Boot Report. + * @param timeSyncStatus The time synchronization status. + */ +void CrIaServ197BootRepParamSetTimeSyncStatus(FwSmDesc_t smDesc, unsigned char timeSyncStatus); + +/** + * Sets the value of the parameter BootReportSent of the out-going packet Boot Report. + * @param bootReportSent Boot report sent status. + */ +void CrIaServ197BootRepParamSetBootReportSent(FwSmDesc_t smDesc, unsigned char bootReportSent); + +/** + * Sets the value of the parameter Spare1 of the out-going packet Boot Report. + * @param spare1 Spare parameter. + */ +void CrIaServ197BootRepParamSetSpare1(FwSmDesc_t smDesc, unsigned char spare1); + +/** + * Sets the value of the parameter SemError of the out-going packet Boot Report. + * @param semError The SEM error from the SEM status register. + */ +void CrIaServ197BootRepParamSetSemError(FwSmDesc_t smDesc, unsigned char semError); + +/** + * Sets the value of the parameter SemOn of the out-going packet Boot Report. + * @param semOn The SEM on status from the SEM status register. + */ +void CrIaServ197BootRepParamSetSemOn(FwSmDesc_t smDesc, unsigned char semOn); + +/** + * Sets the value of the parameter DpuScLinkStatus of the out-going packet Boot Report. + * @param dpuScLinkStatus The DPU SC link status. + */ +void CrIaServ197BootRepParamSetDpuScLinkStatus(FwSmDesc_t smDesc, unsigned char dpuScLinkStatus); + +/** + * Sets the value of the parameter DpuMilbusCoreEx of the out-going packet Boot Report. + * @param dpuMilbusCoreEx The DPU MilBus execution status. + */ +void CrIaServ197BootRepParamSetDpuMilbusCoreEx(FwSmDesc_t smDesc, unsigned char dpuMilbusCoreEx); + +/** + * Sets the value of the parameter DpuMilbusSyncDw of the out-going packet Boot Report. + * @param dpuMilbusSyncDw The DPU MilBus initial synchronization status. + */ +void CrIaServ197BootRepParamSetDpuMilbusSyncDw(FwSmDesc_t smDesc, unsigned char dpuMilbusSyncDw); + +/** + * Sets the value of the parameter DpuMilbusSyncTo of the out-going packet Boot Report. + * @param dpuMilbusSyncTo The DPU MilBus synchronization status. + */ +void CrIaServ197BootRepParamSetDpuMilbusSyncTo(FwSmDesc_t smDesc, unsigned char dpuMilbusSyncTo); + +/** + * Sets the value of the parameter DpuSemLinkStatus of the out-going packet Boot Report. + * @param dpuSemLinkStatus The DPU SEM link status. + */ +void CrIaServ197BootRepParamSetDpuSemLinkStatus(FwSmDesc_t smDesc, unsigned char dpuSemLinkStatus); + +/** + * Sets the value of the parameter DpuSemLinkState of the out-going packet Boot Report. + * @param dpuSemLinkState The DPU SEM link state. + */ +void CrIaServ197BootRepParamSetDpuSemLinkState(FwSmDesc_t smDesc, unsigned char dpuSemLinkState); + +/** + * Sets the value of the parameter ResetTime of the out-going packet Boot Report. + * @param resetTime The last reset time. + */ +void CrIaServ197BootRepParamSetResetTime(FwSmDesc_t smDesc, const unsigned char * resetTime); + +/** + * Sets the value of the parameter TrapCore1 of the out-going packet Boot Report. + * @param trapCore1 Exception number according to GR712RC user manual, Table 15, [RD-4]. Only valid if RESET\_TYPE = EXCEPTION\_RESET, otherwise = 0. + */ +void CrIaServ197BootRepParamSetTrapCore1(FwSmDesc_t smDesc, unsigned char trapCore1); + +/** + * Sets the value of the parameter TrapCore2 of the out-going packet Boot Report. + * @param trapCore2 Exception number according to GR712RC user manual, Table 15, [RD-4]. Only valid if RESET\_TYPE = EXCEPTION\_RESET, otherwise = 0. + */ +void CrIaServ197BootRepParamSetTrapCore2(FwSmDesc_t smDesc, unsigned char trapCore2); + +/** + * Sets the value of the parameter PsrRegCore1 of the out-going packet Boot Report. + * @param psrRegCore1 PSR CPU register of Core 1. + */ +void CrIaServ197BootRepParamSetPsrRegCore1(FwSmDesc_t smDesc, unsigned int psrRegCore1); + +/** + * Sets the value of the parameter WimRegCore1 of the out-going packet Boot Report. + * @param wimRegCore1 WIM CPU register of Core 1. + */ +void CrIaServ197BootRepParamSetWimRegCore1(FwSmDesc_t smDesc, unsigned int wimRegCore1); + +/** + * Sets the value of the parameter PcRegCore1 of the out-going packet Boot Report. + * @param pcRegCore1 PC CPU register of Core 1. + */ +void CrIaServ197BootRepParamSetPcRegCore1(FwSmDesc_t smDesc, unsigned int pcRegCore1); + +/** + * Sets the value of the parameter NpcRegCore1 of the out-going packet Boot Report. + * @param npcRegCore1 nPC CPU register of Core 1. + */ +void CrIaServ197BootRepParamSetNpcRegCore1(FwSmDesc_t smDesc, unsigned int npcRegCore1); + +/** + * Sets the value of the parameter FsrRegCore1 of the out-going packet Boot Report. + * @param fsrRegCore1 FSR CPU register of Core 1. + */ +void CrIaServ197BootRepParamSetFsrRegCore1(FwSmDesc_t smDesc, unsigned int fsrRegCore1); + +/** + * Sets the value of the parameter PsrRegCore2 of the out-going packet Boot Report. + * @param psrRegCore2 PSR CPU register of Core 2. + */ +void CrIaServ197BootRepParamSetPsrRegCore2(FwSmDesc_t smDesc, unsigned int psrRegCore2); + +/** + * Sets the value of the parameter WimRegCore2 of the out-going packet Boot Report. + * @param wimRegCore2 WIM CPU register of Core 2. + */ +void CrIaServ197BootRepParamSetWimRegCore2(FwSmDesc_t smDesc, unsigned int wimRegCore2); + +/** + * Sets the value of the parameter PcRegCore2 of the out-going packet Boot Report. + * @param pcRegCore2 PC CPU register of Core 2. + */ +void CrIaServ197BootRepParamSetPcRegCore2(FwSmDesc_t smDesc, unsigned int pcRegCore2); + +/** + * Sets the value of the parameter NpcRegCore2 of the out-going packet Boot Report. + * @param npcRegCore2 nPC CPU register of Core 2. + */ +void CrIaServ197BootRepParamSetNpcRegCore2(FwSmDesc_t smDesc, unsigned int npcRegCore2); + +/** + * Sets the value of the parameter FsrRegCore2 of the out-going packet Boot Report. + * @param fsrRegCore2 FSR CPU register of Core 2. + */ +void CrIaServ197BootRepParamSetFsrRegCore2(FwSmDesc_t smDesc, unsigned int fsrRegCore2); + +/** + * Sets the value of the parameter AhbStatusReg of the out-going packet Boot Report. + * @param ahbStatusReg AHB status register. + */ +void CrIaServ197BootRepParamSetAhbStatusReg(FwSmDesc_t smDesc, unsigned int ahbStatusReg); + +/** + * Sets the value of the parameter AhbFailingAddrReg of the out-going packet Boot Report. + * @param ahbFailingAddrReg AHB failing address register. + */ +void CrIaServ197BootRepParamSetAhbFailingAddrReg(FwSmDesc_t smDesc, unsigned int ahbFailingAddrReg); + +/** + * Sets the value of the parameter PcHistoryCore1 of the out-going packet Boot Report. + * @param pcHistoryCore1 Up to 7 values of stored Program Counters in the out register 7 (Core1) using CWP. + */ +void CrIaServ197BootRepParamSetPcHistoryCore1(FwSmDesc_t smDesc, const unsigned char * pcHistoryCore1); + +/** + * Sets the value of the parameter PcHistoryCore2 of the out-going packet Boot Report. + * @param pcHistoryCore2 Up to 7 values of stored Program Counters in the out register 7 (Core2) using CWP. + */ +void CrIaServ197BootRepParamSetPcHistoryCore2(FwSmDesc_t smDesc, const unsigned char * pcHistoryCore2); + +/** + * Sets the value of the parameter Spare2 of the out-going packet Boot Report. + * @param spare2 Spare parameter. + */ +void CrIaServ197BootRepParamSetSpare2(FwSmDesc_t smDesc, unsigned short spare2); + +/** + * Sets the value of the parameter DpuMemoryId of the out-going packet Boot Report. + * @param dpuMemoryId The DPU memory identifier. See table \ref{tab:EDpuMemoryId} for the full overview of the DPU memory identifiers. + */ +void CrIaServ197BootRepParamSetDpuMemoryId(FwSmDesc_t smDesc, unsigned short dpuMemoryId); + +/** + * Sets the value of the parameter StartAddress of the out-going packet Boot Report. + * @param startAddress The start address. + */ +void CrIaServ197BootRepParamSetStartAddress(FwSmDesc_t smDesc, unsigned int startAddress); + +/** + * Sets the value of the parameter ErrLogInfo of the out-going packet Boot Report. + * @param errLogInfo The error log of the most recent error. + */ +void CrIaServ197BootRepParamSetErrLogInfo(FwSmDesc_t smDesc, const unsigned char * errLogInfo); + + +void CrIaSetUCharValue(FwSmDesc_t smDesc, unsigned char ucharValue, unsigned int pos); + +void CrIaSetUShortValue(FwSmDesc_t smDesc, unsigned short ushortValue, unsigned int pos); + +void CrIaSetUIntValue(FwSmDesc_t smDesc, unsigned int uintValue, unsigned int pos); + +#endif /* CRIA_PARAM_SETTER_H */ + diff --git a/CrIa/src/Services/General/CrSemConstants.h b/CrIa/src/Services/General/CrSemConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..8b38326787bc8b791eee04877fe611b15e611dc3 --- /dev/null +++ b/CrIa/src/Services/General/CrSemConstants.h @@ -0,0 +1,739 @@ +/** + * @file CrSemConstants.h + * @ingroup CrIaServicesGeneral + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Header file to define all service and packet identifiers, and packet length. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef CRSEM_CONSTANTS_H +#define CRSEM_CONSTANTS_H + + +/** + * SEM Acquisition Type IDs and max number of packets for that type + */ +#define CCD_WIN_EXPOS_ID 1 /* exposed star window, X*Y, typically 200x200 */ +#define CCD_WIN_LSM_ID 2 /* large side margin, 4*Y overscan, 8*Y blank, 16*Y dark */ +#define CCD_WIN_RSM_ID 3 /* reduced side margin, 8*Y blank, 16*Y dark */ +#define CCD_WIN_TM_ID 4 /* top margin window, X*6 overscan, X*3 dark */ +#define CCD_FULL_ID 5 /* full frame, 1076*1033 */ +#define CCD_FULL_MAX_PCKTS 2331 + +#define MAX_CCD_PACKET_NUM CCD_FULL_MAX_PCKTS + +/** + * SEM states from DLR-INST-IC-001 issue 1.6 + */ +#define SEM_STATE_SAFE 1 +#define SEM_STATE_STANDBY 2 +#define SEM_STATE_STABILIZE 3 +#define SEM_STATE_SC_STAR_FAINT 4 +#define SEM_STATE_SC_STAR_BRIGHT 5 +#define SEM_STATE_SC_STAR_ULTBRT 6 +#define SEM_STATE_CCD_FULL 7 +#define SEM_STATE_DIAGNOSTIC 8 + +/** + * SEM mode configuration + */ +#define SEM_CCD_MODE_FAINT_STAR 0 +#define SEM_CCD_MODE_BRIGHT_STAR 1 +#define SEM_CCD_MODE_ULTRBR_STAR 2 +#define SEM_CCD_MODE_CCD_FULL 3 +#define SEM_CCD_MODE_AUTO_STAR 4 +#define SEM_CCD_MODE_FAINT_STAR_FAST 5 /* new in SEM ICD 2.4 */ + + +/** + * The length offset for the in-coming report. + */ +#define OFFSET_PAR_LENGTH_IN_REP_PCKT 16 + +/** + * The length offset for the out-going command. + */ +#define OFFSET_PAR_LENGTH_OUT_CMD_PCKT 10 + +/** + * The length of CRC. + */ +#define CRC_LENGTH 2 + +/** + * Type identifier of the Service 1. + */ +#define CRSEM_SERV1 1 + +/** + * Type identifier of the Housekeeping Data Reporting Service. + */ +#define CRSEM_SERV3 3 + +/** + * Type identifier of the Event Reporting Service. + */ +#define CRSEM_SERV5 5 + +/** + * Type identifier of the Housekeeping Data Reporting Service. + */ +#define CRSEM_SERV9 9 + +/** + * Type identifier of the Science Data Service. + */ +#define CRSEM_SERV21 21 + +/** + * Type identifier of the Private Service 220. + */ +#define CRSEM_SERV220 220 + +/** + * Type identifier of the Private Service 221. + */ +#define CRSEM_SERV221 221 + +/** + * Type identifier of the Private Service 222. + */ +#define CRSEM_SERV222 222 + +/** + * Subtype identifier of the Service 1. + */ +#define CRSEM_SERV1_ACC_SUCC 1 +#define CRSEM_SERV1_ACC_FAIL 2 +#define CRSEM_SERV1_START_SUCC 3 +#define CRSEM_SERV1_START_FAIL 4 +#define CRSEM_SERV1_TERM_SUCC 7 +#define CRSEM_SERV1_TERM_FAIL 8 + +/** + * Subtype identifier of the CMD Housekeeping Data Enable out-going command packet. + */ +#define CRSEM_SERV3_CMD_HK_ENABLE 5 + +/** + * Subtype identifier of the CMD Housekeeping Data Disable out-going command packet. + */ +#define CRSEM_SERV3_CMD_HK_DISABLE 6 + +/** + * Subtype identifier of the DAT HK in-coming report packet. + */ +#define CRSEM_SERV3_DAT_HK 25 + +/** + * Subtype identifier of the CMD Housekeeping Data Period out-going command packet. + */ +#define CRSEM_SERV3_CMD_HK_PERIOD 129 + +/** + * Subtype identifier of the Normal/Progress Report in-coming report packet. + */ +#define CRSEM_SERV5_EVT_NORM 1 + +/** + * Subtype identifier of the Error Report - Low Severity in-coming report packet. + */ +#define CRSEM_SERV5_EVT_ERR_LOW_SEV 2 + +/** + * Subtype identifier of the Error Report - Medium Severity in-coming report packet. + */ +#define CRSEM_SERV5_EVT_ERR_MED_SEV 3 + +/** + * Subtype identifier of the Error Report - High Severity in-coming report packet. + */ +#define CRSEM_SERV5_EVT_ERR_HIGH_SEV 4 + +/** + * Subtype identifier of the CMD Time Update out-going command packet. + */ +#define CRSEM_SERV9_CMD_TIME_UPDATE 129 + +/** + * Subtype identifier of the CMD CCD Data Enable out-going command packet. + */ +#define CRSEM_SERV21_CMD_CCD_DATA_ENABLE 1 + +/** + * Subtype identifier of the CMD CCD Data Disable out-going command packet. + */ +#define CRSEM_SERV21_CMD_CCD_DATA_DISABLE 2 + +/** + * Subtype identifier of the DAT CCD Window in-coming report packet. + */ +#define CRSEM_SERV21_DAT_CCD_WINDOW 3 + +/** + * Subtype identifier of the CMD Operation Parameter out-going command packet. + */ +#define CRSEM_SERV220_CMD_OPER_PARAM 3 + +/** + * Subtype identifier of the CMD Temperature Control Enable out-going command packet. + */ +#define CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE 4 + +/** + * Subtype identifier of the DAT Operation Parameter in-coming report packet. + */ +#define CRSEM_SERV220_DAT_OPER_PARAM 6 + +/** + * Subtype identifier of the Changes SEM Functional Parameter out-going command packet. + */ +#define CRSEM_SERV220_CMD_FUNCT_PARAM 11 + +/** + * Subtype identifier of the DAT Functional Parameter in-coming report packet. + */ +#define CRSEM_SERV220_DAT_FUNCT_PARAM 12 + +/** + * Subtype identifier of the CMD Safe Enter out-going command packet. + */ +#define CRSEM_SERV221_CMD_SAFE_ENTER 1 + +/** + * Subtype identifier of the CMD Standby Enter out-going command packet. + */ +#define CRSEM_SERV221_CMD_STANDBY_ENTER 2 + +/** + * Subtype identifier of the CMD FPM Power Enable out-going command packet. + */ +#define CRSEM_SERV221_CMD_FPM_POWER_ENABLE 3 + +/** + * Subtype identifier of the CMD FPM Power Disable out-going command packet. + */ +#define CRSEM_SERV221_CMD_FPM_POWER_DISABLE 4 + +/** + * Subtype identifier of the CMD Diagnostic Enable out-going command packet. + */ +#define CRSEM_SERV222_CMD_DIAG_ENABLE 3 + +/** + * Subtype identifier of the CMD Diagnostic Disable out-going command packet. + */ +#define CRSEM_SERV222_CMD_DIAG_DISABLE 4 + +/** + * Subtype identifier of the CMD Test Log in-coming report packet. + */ +#define CRSEM_SERV222_DAT_TEST_LOG 6 + +/** + * Length of the CMD Housekeeping Data Enable out-going command packet. + */ +#define CRSEM_SERV3_CMD_HK_ENABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the CMD Housekeeping Data Disable out-going command packet. + */ +#define CRSEM_SERV3_CMD_HK_DISABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT HK in-coming report packet. + */ +#define CRSEM_SERV3_DAT_HK_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the CMD Housekeeping Data Period out-going command packet. + */ +#define CRSEM_SERV3_CMD_HK_PERIOD_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the Operation Default HK. + */ +#define CRSEM_SERV3_OPERATION_DEFAULT_HK_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 42 + CRC_LENGTH) + +/** + * Length of the Operation Extended HK. + */ +#define CRSEM_SERV3_OPERATION_EXTENDED_HK_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 90 + CRC_LENGTH) + +/** + * Length of the Normal/Progress Report in-coming report packet. + */ +#define CRSEM_SERV5_EVT_NORM_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Error Report - Low Severity in-coming report packet. + */ +#define CRSEM_SERV5_EVT_ERR_LOW_SEV_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Error Report - Medium Severity in-coming report packet. + */ +#define CRSEM_SERV5_EVT_ERR_MED_SEV_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the Error Report - High Severity in-coming report packet. + */ +#define CRSEM_SERV5_EVT_ERR_HIGH_SEV_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Progress(PBSBootReady). + */ +#define CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 38 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Progress(APSBootReady). + */ +#define CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 38 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Progress(ModeTransition). + */ +#define CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Progress(DiagStepFinished). + */ +#define CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Progress(TempStable). + */ +#define CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Progress(CFGLoadReady). + */ +#define CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 38 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Progress(FPATempNominal). + */ +#define CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(EEPROM no segment). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(EEPROM no APS exe). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(EEPROM no APS config). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(EEPROM no PBS config). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(EEPROM no APS exe flag). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(EEPROM no APS config flag). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(TempUnstable). + */ +#define CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 14 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(FPATempTooHigh). + */ +#define CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(WrongExposureTime). + */ +#define CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 8 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(WrongRepetitionPeriod). + */ +#define CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 12 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(FPMoffOnlyPattern). + */ +#define CRSEM_SERV5_EVT_WAR_PATTER_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Warning(PackEncodeFailure). + */ +#define CRSEM_SERV5_EVT_WAR_PACKWR_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(EEPROM write error). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(Auto-boot failure). + */ +#define CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(unexpected re-boot). + */ +#define CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 20 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(watchdog failure). + */ +#define CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 10 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(SpW Error). + */ +#define CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(EEPROM Exe copy abort). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(EEPROM EXE seg CRC wrong). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(PBS CFG size wrong). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(Reg writing wrong). + */ +#define CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 14 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(CMD Buffer1 full). + */ +#define CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(CMD Buffer2 full). + */ +#define CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(DMA data transfer failure). + */ +#define CRSEM_SERV5_EVT_ERR_DAT_DMA_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(BIAS voltage wrong). + */ +#define CRSEM_SERV5_EVT_ERR_BIAS_SET_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 34 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(FEE-SCU sync failure). + */ +#define CRSEM_SERV5_EVT_ERR_SYNC_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(FEE script error). + */ +#define CRSEM_SERV5_EVT_ERR_SCRIPT_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 4 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(PCU power switching failed). + */ +#define CRSEM_SERV5_EVT_ERR_PWR_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the DAT_Event_Error(SpW time code missing). + */ +#define CRSEM_SERV5_EVT_ERR_SPW_TC_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the CMD Time Update out-going command packet. + */ +#define CRSEM_SERV9_CMD_TIME_UPDATE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 6 + CRC_LENGTH) + +/** + * Length of the CMD CCD Data Enable out-going command packet. + */ +#define CRSEM_SERV21_CMD_CCD_DATA_ENABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the CMD CCD Data Disable out-going command packet. + */ +#define CRSEM_SERV21_CMD_CCD_DATA_DISABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the DAT CCD Window in-coming report packet. + */ +#define CRSEM_SERV21_DAT_CCD_WINDOW_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 1006 + CRC_LENGTH) + +/** + * Length of the CMD Operation Parameter out-going command packet. + */ +#define CRSEM_SERV220_CMD_OPER_PARAM_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 14 + CRC_LENGTH) /* NOTE: manual fix */ + +/** + * Length of the CMD Temperature Control Enable out-going command packet. + */ +#define CRSEM_SERV220_CMD_TEMP_CTRL_ENABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the CMD Temperature Control Disable out-going command packet. + */ +#define CRSEM_SERV220_CMD_TEMP_CTRL_DISABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the CMD Functional Parameter out-going command packet. + */ +#define CRSEM_SERV220_CMD_FUNCT_PARAM_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 38 + CRC_LENGTH) + +/** + * Length of the CMD Safe Enter out-going command packet. + */ +#define CRSEM_SERV221_CMD_SAFE_ENTER_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the CMD Standby Enter out-going command packet. + */ +#define CRSEM_SERV221_CMD_STANDBY_ENTER_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the CMD FPM Power Enable out-going command packet. + */ +#define CRSEM_SERV221_CMD_FPM_POWER_ENABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the CMD FPM Power Disable out-going command packet. + */ +#define CRSEM_SERV221_CMD_FPM_POWER_DISABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the CMD Diagnostic Enable out-going command packet. + */ +#define CRSEM_SERV222_CMD_DIAG_ENABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2 + CRC_LENGTH) + +/** + * Length of the CMD Diagnostic Disable out-going command packet. + */ +#define CRSEM_SERV222_CMD_DIAG_DISABLE_LENGTH (OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0 + CRC_LENGTH) + +/** + * Length of the DAT Test Log in-coming report packet. + */ +#define CRSEM_SERV222_DAT_TEST_LOG_LENGTH (OFFSET_PAR_LENGTH_IN_REP_PCKT + 5 + CRC_LENGTH) + +/** + * Identifier of the Operation Default HK. + */ +#define CRSEM_SERV3_OPERATION_DEFAULT_HK 1 + +/** + * Identifier of the Operation Extended HK. + */ +#define CRSEM_SERV3_OPERATION_EXTENDED_HK 2 + +/** + * Identifier of the DAT_Event_Progress(PBSBootReady). + */ +#define CRSEM_SERV5_EVENT_PRG_PBS_BOOT_READY 42001 + +/** + * Identifier of the DAT_Event_Progress(APSBootReady). + */ +#define CRSEM_SERV5_EVENT_PRG_APS_BOOT_READY 42002 + +/** + * Identifier of the DAT_Event_Progress(ModeTransition). + */ +#define CRSEM_SERV5_EVENT_PRG_MODE_TRANSITION 42003 + +/** + * Identifier of the DAT_Event_Progress(DiagStepFinished). + */ +#define CRSEM_SERV5_EVENT_PRG_DIAGNOSE_STEP_FINISHED 42004 + +/** + * Identifier of the DAT_Event_Progress(TempStable). + */ +#define CRSEM_SERV5_EVENT_PRG_THERMAL_STABILITY 42008 + +/** + * Identifier of the DAT_Event_Progress(CFGLoadReady). + */ +#define CRSEM_SERV5_EVENT_PRG_CFG_LOAD_READY 42009 + +/** + * Identifier of the DAT_Event_Progress(FPATempNominal). + */ +#define CRSEM_SERV5_EVENT_PRG_FPA_TEMP_NOMINAL 42010 + +/** + * Identifier of the DAT_Event_Warning(EEPROM no segment). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_SEGMENT 42204 + +/** + * Identifier of the DAT_Event_Warning(EEPROM no APS exe). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE 42205 + +/** + * Identifier of the DAT_Event_Warning(EEPROM no APS config). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG 42206 + +/** + * Identifier of the DAT_Event_Warning(EEPROM no PBS config). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_PBS_CFG 42207 + +/** + * Identifier of the DAT_Event_Warning(EEPROM no APS exe flag). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_EXE_FLAG 42208 + +/** + * Identifier of the DAT_Event_Warning(EEPROM no APS config flag). + */ +#define CRSEM_SERV5_EVENT_WAR_EEPROM_NO_APS_CFG_FLAG 42209 + +/** + * Identifier of the DAT_Event_Warning(TempUnstable). + */ +#define CRSEM_SERV5_EVENT_WAR_NO_THERMAL_STABILITY 42214 + +/** + * Identifier of the DAT_Event_Warning(FPATempTooHigh). + */ +#define CRSEM_SERV5_EVENT_WAR_FPA_TEMP_TOO_HIGH 42215 + +/** + * Identifier of the DAT_Event_Warning(WrongExposureTime). + */ +#define CRSEM_SERV5_EVENT_WAR_WRONG_EXPOSURE_TIME 42216 + +/** + * Identifier of the DAT_Event_Warning(WrongRepetitionPeriod). + */ +#define CRSEM_SERV5_EVENT_WAR_WRONG_REPETITION_PERIOD 42217 + +/** + * Identifier of the DAT_Event_Warning(FPMoffOnlyPattern). + */ +#define CRSEM_SERV5_EVT_WAR_PATTER 42218 + +/** + * Identifier of the DAT_Event_Warning(PackEncodeFailure). + */ +#define CRSEM_SERV5_EVT_WAR_PACKWR 42219 + +/** + * Identifier of the DAT_Event_Error(EEPROM write error). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_WRITE_ERROR 43800 + +/** + * Identifier of the DAT_Event_Error(Auto-boot failure). + */ +#define CRSEM_SERV5_EVENT_ERR_APS_BOOT_FAILURE 43801 + +/** + * Identifier of the DAT_Event_Error(unexpected re-boot). + */ +#define CRSEM_SERV5_EVENT_ERR_UNEXPECTED_REBOOT 43802 + +/** + * Identifier of the DAT_Event_Error(watchdog failure). + */ +#define CRSEM_SERV5_EVENT_ERR_WATCHDOG_FAILURE 43813 + +/** + * Identifier of the DAT_Event_Error(SpW Error). + */ +#define CRSEM_SERV5_EVENT_ERR_CMD_SPW_RX_ERROR 43814 + +/** + * Identifier of the DAT_Event_Error(EEPROM Exe copy abort). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_COPY_ABORT 43815 + +/** + * Identifier of the DAT_Event_Error(EEPROM EXE seg CRC wrong). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_EXE_SEG_CRC_WRONG 43816 + +/** + * Identifier of the DAT_Event_Error(PBS CFG size wrong). + */ +#define CRSEM_SERV5_EVENT_ERR_EEPROM_PBS_CFG_SIZE_WRONG 43817 + +/** + * Identifier of the DAT_Event_Error(Reg writing wrong). + */ +#define CRSEM_SERV5_EVENT_ERR_WRITING_REGISTER_FAILED 43818 + +/** + * Identifier of the DAT_Event_Error(CMD Buffer1 full). + */ +#define CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_1_FULL 43819 + +/** + * Identifier of the DAT_Event_Error(CMD Buffer2 full). + */ +#define CRSEM_SERV5_EVENT_ERR_CMD_BUFFER_2_FULL 43820 + +/** + * Identifier of the DAT_Event_Error(DMA data transfer failure). + */ +#define CRSEM_SERV5_EVT_ERR_DAT_DMA 43821 + +/** + * Identifier of the DAT_Event_Error(BIAS voltage wrong). + */ +#define CRSEM_SERV5_EVT_ERR_BIAS_SET 43822 + +/** + * Identifier of the DAT_Event_Error(FEE-SCU sync failure). + */ +#define CRSEM_SERV5_EVT_ERR_SYNC 43823 + +/** + * Identifier of the DAT_Event_Error(FEE script error). + */ +#define CRSEM_SERV5_EVT_ERR_SCRIPT 43824 + +/** + * Identifier of the DAT_Event_Error(PCU power switching failed). + */ +#define CRSEM_SERV5_EVT_ERR_PWR 43825 + +/** + * Identifier of the DAT_Event_Error(SpW time code missing). + */ +#define CRSEM_SERV5_EVT_ERR_SPW_TC 43826 + +#endif /* CRSEM_CONSTANTS_H */ + diff --git a/CrIa/src/Services/General/CrSemParamGetter.c b/CrIa/src/Services/General/CrSemParamGetter.c new file mode 100644 index 0000000000000000000000000000000000000000..be2036ca9a89eacebc288c1270adf071d04fe9a5 --- /dev/null +++ b/CrIa/src/Services/General/CrSemParamGetter.c @@ -0,0 +1,930 @@ +/** + * @file CrSemParamGetter.c + * @ingroup CrIaServicesGeneral + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the getter operations for all parameters of all in-coming packets. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemParamGetter.h" +#include "CrSemConstants.h" +#include "CrIaPckt.h" +#include <string.h> + +#define GET_UCHAR_FROM_PCKT(from) ((unsigned char)(pckt[from])) + +#define GET_USHORT_FROM_PCKT(from) ( (((unsigned char)(pckt[from])) << 8) | ((unsigned char)(pckt[from+1])) ) + +#define GET_UINT_FROM_PCKT(from) ( (((unsigned char)(pckt[from])) << 24) | (((unsigned char)(pckt[from+1])) << 16) | (((unsigned char)(pckt[from+2])) << 8) | ((unsigned char)(pckt[from+3])) ) + + + +static unsigned char GetBitsFromByte(unsigned char value, unsigned char at, unsigned char numBits) +{ + unsigned char mask = (1 << numBits) -1; + return (value >> at) & mask; +} + +static unsigned short GetBitsFromShort(unsigned short value, unsigned short at, unsigned short numBits) +{ + unsigned short mask = (1 << numBits) -1; + return (value >> at) & mask; +} + +void CrSemServ3DatHkParamGetHkStatSid(unsigned short * hkStatSid, CrFwPckt_t pckt) +{ + *hkStatSid = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +/***************/ +/* Default HK */ +/***************/ +void CrSemServ3OperationDefaultHkParamGetHkStatMode(unsigned short * hkStatMode, CrFwPckt_t pckt) +{ + *hkStatMode = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 2); + return; +} + +/* get HK_STAT_FLAGS including all flags */ +void CrSemServ3OperationDefaultHkParamGetHkStatFlags(unsigned short * hkStatFlags, CrFwPckt_t pckt) +{ + *hkStatFlags = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + return; +} + +void CrSemServ3OperationDefaultHkParamGetFixVal9(unsigned short * fixVal9, CrFwPckt_t pckt) +{ + *fixVal9 = GetBitsFromShort(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 4], 0, 9); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatObtSyncFlag(unsigned char * hkStatObtSyncFlag, CrFwPckt_t pckt) +{ + *hkStatObtSyncFlag = GetBitsFromByte(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5], 2, 1); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatWatchDog(unsigned char * hkStatWatchDog, CrFwPckt_t pckt) +{ + *hkStatWatchDog = GetBitsFromByte(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5], 3, 1); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatEepromPower(unsigned char * hkStatEepromPower, CrFwPckt_t pckt) +{ + *hkStatEepromPower = GetBitsFromByte(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5], 4, 1); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatHkPower(unsigned char * hkStatHkPower, CrFwPckt_t pckt) +{ + *hkStatHkPower = GetBitsFromByte(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5], 5, 1); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatFpmPower(unsigned char * hkStatFpmPower, CrFwPckt_t pckt) +{ + *hkStatFpmPower = GetBitsFromByte(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5], 6, 1); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatDatBufferOverflow(unsigned char * hkStatDatBufferOverflow, CrFwPckt_t pckt) +{ + *hkStatDatBufferOverflow = GetBitsFromByte(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5], 7, 1); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatScuMainRed(unsigned char * hkStatScuMainRed, CrFwPckt_t pckt) +{ + *hkStatScuMainRed = GetBitsFromByte(pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5], 8, 1); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatLastSpwlinkError(unsigned short * hkStatLastSpwlinkError, CrFwPckt_t pckt) +{ + *hkStatLastSpwlinkError = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 6); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatLastErrorId(unsigned short * hkStatLastErrorId, CrFwPckt_t pckt) +{ + *hkStatLastErrorId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 8); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatLastErrorFrequency(unsigned short * hkStatLastErrorFrequency, CrFwPckt_t pckt) +{ + *hkStatLastErrorFrequency = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 10); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatNumCmdReceived(unsigned short * hkStatNumCmdReceived, CrFwPckt_t pckt) +{ + *hkStatNumCmdReceived = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 12); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatNumCmdExecuted(unsigned short * hkStatNumCmdExecuted, CrFwPckt_t pckt) +{ + *hkStatNumCmdExecuted = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 14); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatNumDatSent(unsigned short * hkStatNumDatSent, CrFwPckt_t pckt) +{ + *hkStatNumDatSent = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 16); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatScuProcDutyCycle(unsigned short * hkStatScuProcDutyCycle, CrFwPckt_t pckt) +{ + *hkStatScuProcDutyCycle = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 18); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatScuNumAhbError(unsigned short * hkStatScuNumAhbError, CrFwPckt_t pckt) +{ + *hkStatScuNumAhbError = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 20); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatScuNumAhbCorrectableError(unsigned short * hkStatScuNumAhbCorrectableError, CrFwPckt_t pckt) +{ + *hkStatScuNumAhbCorrectableError = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 22); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkStatHkNumLatchupError(unsigned short * hkStatHkNumLatchupError, CrFwPckt_t pckt) +{ + *hkStatHkNumLatchupError = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 24); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkTempSemScu(float * hkTempSemScu, CrFwPckt_t pckt) +{ + *((unsigned int *)hkTempSemScu) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 26); + return; +} + +void CrSemServ3OperationDefaultHkParamGetHkTempSemPcu(float * hkTempSemPcu, CrFwPckt_t pckt) +{ + *((unsigned int *)hkTempSemPcu) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 30); + return; +} + +/* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ +void CrSemServ3OperationDefaultHkParamGetHkVoltScuP34(float * hkVoltScuP34, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltScuP34) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 34); + return; +} + +/* NOTE: NEW in ICD DLR-INST-IC-001, issue 2.1 */ +void CrSemServ3OperationDefaultHkParamGetHkVoltScuP5(float * hkVoltScuP5, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltScuP5) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 38); + return; +} + +/***************/ +/* Extended HK */ +/***************/ + +/** + * @warning There is one dangerous thing here: the floats which are acquired by + * getters such as @ref CrSemServ3OperationExtendedHkParamGetHkVoltFeeVod + * must be normalized (see App Note on "Handling denormalized numbers with the GRFPU"). + * If they are not (because SEM gives us rubbish data), this leads to a FP exception. + */ + +void CrSemServ3OperationExtendedHkParamGetHkTempFeeCcd(float * hkTempFeeCcd, CrFwPckt_t pckt) +{ + *((unsigned int *)hkTempFeeCcd) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 2); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkTempFeeStrap(float * hkTempFeeStrap, CrFwPckt_t pckt) +{ + *((unsigned int *)hkTempFeeStrap) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 6); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkTempFeeAdc(float * hkTempFeeAdc, CrFwPckt_t pckt) +{ + *((unsigned int *)hkTempFeeAdc) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 10); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkTempFeeBias(float * hkTempFeeBias, CrFwPckt_t pckt) +{ + *((unsigned int *)hkTempFeeBias) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 14); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkTempFeeDeb(float * hkTempFeeDeb, CrFwPckt_t pckt) +{ + *((unsigned int *)hkTempFeeDeb) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 18); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVod(float * hkVoltFeeVod, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeVod) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 22); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVrd(float * hkVoltFeeVrd, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeVrd) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 26); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVog(float * hkVoltFeeVog, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeVog) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 30); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVss(float * hkVoltFeeVss, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeVss) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 34); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeCcd(float * hkVoltFeeCcd, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeCcd) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 38); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeClk(float * hkVoltFeeClk, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeClk) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 42); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeAnaP5(float * hkVoltFeeAnaP5, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeAnaP5) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 46); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeAnaN5(float * hkVoltFeeAnaN5, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltFeeAnaN5) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 50); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeDigP33(float * hkVoltDigP33, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltDigP33) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 54); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkCurrFeeClkBuf(float * hkCurrFeeClkBuf, CrFwPckt_t pckt) +{ + *((unsigned int *)hkCurrFeeClkBuf) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 58); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkVoltScuFpgaP15(float * hkVoltScuFpgaP15, CrFwPckt_t pckt) +{ + *((unsigned int *)hkVoltScuFpgaP15) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 62); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkCurrScuP34(float * hkCurrScuP34, CrFwPckt_t pckt) +{ + *((unsigned int *)hkCurrScuP34) = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 66); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrCredit(unsigned char * hkStatNumSpwErrCredit, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrCredit = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 70); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrEscape(unsigned char * hkStatNumSpwErrEscape, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrEscape = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 71); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrDisconnect(unsigned char * hkStatNumSpwErrDisconnect, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrDisconnect = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 72); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrParity(unsigned char * hkStatNumSpwErrParity, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrParity = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 73); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrWriteSync(unsigned char * hkStatNumSpwErrWriteSync, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrWriteSync = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 74); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrInvalidAddress(unsigned char * hkStatNumSpwErrInvalidAddress, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrInvalidAddress = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 75); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrEopeep(unsigned char * hkStatNumSpwErrEopeep, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrEopeep = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 76); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrRxAhb(unsigned char * hkStatNumSpwErrRxAhb, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrRxAhb = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 77); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxAhb(unsigned char * hkStatNumSpwErrTxAhb, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrTxAhb = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 78); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxBlocked(unsigned char * hkStatNumSpwErrTxBlocked, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrTxBlocked = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 79); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxle(unsigned char * hkStatNumSpwErrTxle, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrTxle = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 80); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrRx(unsigned char * hkStatNumSpwErrRx, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrRx = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 81); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTx(unsigned char * hkStatNumSpwErrTx, CrFwPckt_t pckt) +{ + *hkStatNumSpwErrTx = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 82); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFpaCcd(unsigned char * hkStatHeatPwmFpaCcd, CrFwPckt_t pckt) +{ + *hkStatHeatPwmFpaCcd = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 83); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFeeStrap(unsigned char * hkStatHeatPwmFeeStrap, CrFwPckt_t pckt) +{ + *hkStatHeatPwmFeeStrap = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 84); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFeeAnach(unsigned char * hkStatHeatPwmFeeAnach, CrFwPckt_t pckt) +{ + *hkStatHeatPwmFeeAnach = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 85); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmSpare(unsigned char * hkStatHeatPwmSpare, CrFwPckt_t pckt) +{ + *hkStatHeatPwmSpare = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 86); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatBits(unsigned char * hkStatBits, CrFwPckt_t pckt) +{ + *hkStatBits = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 87); + return; +} + +void CrSemServ3OperationExtendedHkParamGetHkStatOBTimeSyncDelta(unsigned short * hkStatOBTimeSyncDelta, CrFwPckt_t pckt) +{ + *hkStatOBTimeSyncDelta = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 88); + return; +} + +/* End Of HK Getter */ + +void CrSemServ5EvtNormParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt) +{ + *hkEventProgId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EvtErrLowSevParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt) +{ + *hkEventProgId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EvtErrMedSevParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt) +{ + *hkEventProgId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EvtErrHighSevParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt) +{ + *hkEventProgId = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatSwVersion(unsigned char * hkStatSwVersion, CrFwPckt_t pckt) +{ + unsigned int i; + for(i = 0; i < 30; i++) + { + hkStatSwVersion[i] = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + i); + } + return; +} + +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatBootReason(unsigned short * hkStatBootReason, CrFwPckt_t pckt) +{ + *hkStatBootReason = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 30); + return; +} + +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatScuFpgaVersion(unsigned char * hkStatScuFpgaVersion, CrFwPckt_t pckt) +{ + *hkStatScuFpgaVersion = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 32); + return; +} + +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatScuMainRedundant(unsigned char * hkStatScuMainRedundant, CrFwPckt_t pckt) +{ + *hkStatScuMainRedundant = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 33); + return; +} + +void CrSemServ5EventPrgApsBootReadyParamGetHkStatSwVersion(unsigned char * hkStatSwVersion, CrFwPckt_t pckt) +{ + unsigned int i; + for(i = 0; i < 30; i++) + { + hkStatSwVersion[i] = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + i); + } + return; +} + +void CrSemServ5EventPrgApsBootReadyParamGetHkStatBootReason(unsigned short * hkStatBootReason, CrFwPckt_t pckt) +{ + *hkStatBootReason = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 30); + return; +} + +void CrSemServ5EventPrgApsBootReadyParamGetHkStatScuFpgaVersion(unsigned char * hkStatScuFpgaVersion, CrFwPckt_t pckt) +{ + *hkStatScuFpgaVersion = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 32); + return; +} + +void CrSemServ5EventPrgApsBootReadyParamGetHkStatScuMainRedundant(unsigned char * hkStatScuMainRedundant, CrFwPckt_t pckt) +{ + *hkStatScuMainRedundant = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 33); + return; +} + +void CrSemServ5EventPrgModeTransitionParamGetHkStatPreviousMode(unsigned short * hkStatPreviousMode, CrFwPckt_t pckt) +{ + *hkStatPreviousMode = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 2); + return; +} + +void CrSemServ5EventPrgModeTransitionParamGetHkStatCurrentMode(unsigned short * hkStatCurrentMode, CrFwPckt_t pckt) +{ + *hkStatCurrentMode = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + return; +} + +void CrSemServ5EventPrgDiagnoseStepFinishedParamGetHkStatDiagStep(unsigned short * hkStatDiagStep, CrFwPckt_t pckt) +{ + *hkStatDiagStep = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventPrgDiagnoseStepFinishedParamGetHkStatDiagStepResult(unsigned short * hkStatDiagStepResult, CrFwPckt_t pckt) +{ + *hkStatDiagStepResult = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 2); + return; +} + +void CrSemServ5EventPrgCfgLoadReadyParamGetHkStatCfgVersion(unsigned char * hkStatCfgVersion, CrFwPckt_t pckt) +{ + unsigned int i; + for(i = 0; i < 30; i++) + { + hkStatCfgVersion[i] = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + i); + } + return; +} + +void CrSemServ5EventPrgCfgLoadReadyParamGetHkStatCfgNumParamsLoaded(unsigned short * hkStatCfgNumParamsLoaded, CrFwPckt_t pckt) +{ + *hkStatCfgNumParamsLoaded = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 30); + return; +} + +void CrSemServ5EventPrgCfgLoadReadyParamGetHkStatCfgNumParamsUsed(unsigned short * hkStatCfgNumParamsUsed, CrFwPckt_t pckt) +{ + *hkStatCfgNumParamsUsed = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 32); + return; +} + +void CrSemServ5EventWarNoThermalStabilityParamGetHkTempFpaCcd(int * hkTempFpaCcd, CrFwPckt_t pckt) +{ + *hkTempFpaCcd = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventWarNoThermalStabilityParamGetHkTempFpaStrap(int * hkTempFpaStrap, CrFwPckt_t pckt) +{ + *hkTempFpaStrap = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + return; +} + +void CrSemServ5EventWarNoThermalStabilityParamGetHkTempFee1(int * hkTempFee1, CrFwPckt_t pckt) +{ + *hkTempFee1 = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 8); + return; +} + +void CrSemServ5EventWarFpaTempTooHighParamGetHkTempFpaCcd(int * hkTempFpaCcd, CrFwPckt_t pckt) +{ + *hkTempFpaCcd = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventWarWrongExposureTimeParamGetFixVal8(unsigned char * fixVal8, CrFwPckt_t pckt) +{ + *fixVal8 = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventWarWrongExposureTimeParamGetParCcdReadoutMode(unsigned char * parCcdReadoutMode, CrFwPckt_t pckt) +{ + *parCcdReadoutMode = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 1); + return; +} + +void CrSemServ5EventWarWrongExposureTimeParamGetParExposureTime(unsigned int * parExposureTime, CrFwPckt_t pckt) +{ + *parExposureTime = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 2); + return; +} + +void CrSemServ5EventWarWrongRepetitionPeriodParamGetHkStatExposureTime(unsigned int * hkStatExposureTime, CrFwPckt_t pckt) +{ + *hkStatExposureTime = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventWarWrongRepetitionPeriodParamGetParRepetitionPeriod(unsigned int * parRepetitionPeriod, CrFwPckt_t pckt) +{ + *parRepetitionPeriod = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + return; +} + +void CrSemServ5EventWarWrongRepetitionPeriodParamGetHkStatMode(unsigned short * hkStatMode, CrFwPckt_t pckt) +{ + *hkStatMode = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 8); + return; +} + +void CrSemServ5EvtWarPatterParamGetHkStatDatSequCount(unsigned short * hkStatDatSequCount, CrFwPckt_t pckt) +{ + *hkStatDatSequCount = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EvtWarPackwrParamGetHkStatDatSequCount(unsigned short * hkStatDatSequCount, CrFwPckt_t pckt) +{ + *hkStatDatSequCount = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatBootReason(unsigned short * hkStatBootReason, CrFwPckt_t pckt) +{ + *hkStatBootReason = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcStatus(unsigned int * hkStatRegProcStatus, CrFwPckt_t pckt) +{ + *hkStatRegProcStatus = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 2); + return; +} + +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcTrapBase(unsigned int * hkStatRegProcTrapBase, CrFwPckt_t pckt) +{ + *hkStatRegProcTrapBase = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 6); + return; +} + +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcProgrammCount(unsigned int * hkStatRegProcProgrammCount, CrFwPckt_t pckt) +{ + *hkStatRegProcProgrammCount = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 10); + return; +} + +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcProgrammInstruct(unsigned int * hkStatRegProcProgrammInstruct, CrFwPckt_t pckt) +{ + *hkStatRegProcProgrammInstruct = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 14); + return; +} + +void CrSemServ5EventErrWatchdogFailureParamGetHkStatWatchDogTimerValueSet(unsigned int * hkStatWatchDogTimerValueSet, CrFwPckt_t pckt) +{ + *hkStatWatchDogTimerValueSet = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventErrWatchdogFailureParamGetHkStatWatchDogTimerValueRead(unsigned int * hkStatWatchDogTimerValueRead, CrFwPckt_t pckt) +{ + *hkStatWatchDogTimerValueRead = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + return; +} + +void CrSemServ5EventErrCmdSpwRxErrorParamGetHkStatSpwReceiveError(unsigned short * hkStatSpwReceiveError, CrFwPckt_t pckt) +{ + *hkStatSpwReceiveError = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventErrEepromPbsCfgSizeWrongParamGetHkStatPbsCfgSizeExpected(unsigned short * hkStatPbsCfgSizeExpected, CrFwPckt_t pckt) +{ + *hkStatPbsCfgSizeExpected = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventErrEepromPbsCfgSizeWrongParamGetHkStatPbsCfgSizeRead(unsigned short * hkStatPbsCfgSizeRead, CrFwPckt_t pckt) +{ + *hkStatPbsCfgSizeRead = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 2); + return; +} + +void CrSemServ5EventErrWritingRegisterFailedParamGetHkStatRegAddress(unsigned int * hkStatRegAddress, CrFwPckt_t pckt) +{ + *hkStatRegAddress = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ5EventErrWritingRegisterFailedParamGetHkStatRegValueWritten(unsigned int * hkStatRegValueWritten, CrFwPckt_t pckt) +{ + *hkStatRegValueWritten = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + return; +} + +void CrSemServ5EventErrWritingRegisterFailedParamGetHkStatRegValueRead(unsigned int * hkStatRegValueRead, CrFwPckt_t pckt) +{ + *hkStatRegValueRead = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 8); + return; +} + +void CrSemServ5EvtErrDatDmaParamGetHkStatDmaErrType(unsigned short * hkStatDmaErrType, CrFwPckt_t pckt) { + *hkStatDmaErrType = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 1] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 0]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVod(unsigned int * hkParVoltFeeVod, CrFwPckt_t pckt) { + *hkParVoltFeeVod = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 3] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 2] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 1] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 0]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVrd(unsigned int * hkParVoltFeeVrd, CrFwPckt_t pckt) { + *hkParVoltFeeVrd = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 7] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 6] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 5] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 4]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVss(unsigned int * hkParVoltFeeVss, CrFwPckt_t pckt) { + *hkParVoltFeeVss = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 11] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 10] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 9] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 8]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVog(unsigned int * hkParVoltFeeVog, CrFwPckt_t pckt) { + *hkParVoltFeeVog = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 15] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 14] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 13] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 12]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVod2(unsigned int * hkParVoltFeeVod2, CrFwPckt_t pckt) { + *hkParVoltFeeVod2 = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 19] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 18] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 17] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 16]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVrd2(unsigned int * hkParVoltFeeVrd2, CrFwPckt_t pckt) { + *hkParVoltFeeVrd2 = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 23] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 22] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 21] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 20]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVss2(unsigned int * hkParVoltFeeVss2, CrFwPckt_t pckt) { + *hkParVoltFeeVss2 = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 27] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 26] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 25] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 24]); + return; +} + +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVog2(unsigned int * hkParVoltFeeVog2, CrFwPckt_t pckt) { + *hkParVoltFeeVog2 = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 31] << 24) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 30] << 16) | + (pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 29] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 28]); + return; +} + +void CrSemServ5EvtErrSyncParamGetHkStatSynctErrType(unsigned short * hkStatSynctErrType, CrFwPckt_t pckt) { + *hkStatSynctErrType = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 1] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 0]); + return; +} + +void CrSemServ5EvtErrScriptParamGetHkStatScriptErrType(unsigned short * hkStatScriptErrType, CrFwPckt_t pckt) { + *hkStatScriptErrType = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 1] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 0]); + return; +} + +void CrSemServ5EvtErrPwrParamGetHkStatPowErrType(unsigned short * hkStatPowErrType, CrFwPckt_t pckt) { + *hkStatPowErrType = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 1] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 0]); + return; +} + +void CrSemServ5EvtErrPwrParamGetHkStatPcuPowWord(unsigned short * hkStatPcuPowWord, CrFwPckt_t pckt) { + *hkStatPcuPowWord = ((pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 3] << 8) | + pckt[OFFSET_PAR_LENGTH_IN_REP_PCKT + 2]); + return; +} + +/* +void CrSemServ5EventErrDataAcqTimeoutParamGetHkStatDataTimeoutValue(unsigned short * hkStatDataTimeoutValue, CrFwPckt_t pckt) +{ + *hkStatDataTimeoutValue = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} +*/ + + +/* + SEM Serv 21, revised in 0.9+ for ICD 2.1 compatibility +*/ +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqId(unsigned int * hkStatDataAcqId, CrFwPckt_t pckt) +{ + *hkStatDataAcqId = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqType(unsigned char * hkStatDataAcqType, CrFwPckt_t pckt) +{ + *hkStatDataAcqType = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + *hkStatDataAcqType = (*hkStatDataAcqType >> 4) & 0x0f; + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqSrc(unsigned char * hkStatDataAcqSrc, CrFwPckt_t pckt) +{ + *hkStatDataAcqSrc = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + *hkStatDataAcqSrc = *hkStatDataAcqSrc & 0x0f; + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqTypeSrc(unsigned char * hkStatDataAcqTypeSrc, CrFwPckt_t pckt) +{ + *hkStatDataAcqTypeSrc = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 4); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatCcdTimingScriptId(unsigned char * hkStatCcdTimingScriptId, CrFwPckt_t pckt) +{ + *hkStatCcdTimingScriptId = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 5); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqTime(unsigned char * hkStatDataAcqTime, CrFwPckt_t pckt) +{ + unsigned char i; + for(i = 0; i < 6; i++) + { + hkStatDataAcqTime[i] = GET_UCHAR_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 6 + i); + } + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatExposureTime(unsigned int * hkStatExposureTime, CrFwPckt_t pckt) +{ + *hkStatExposureTime = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 12); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatTotalPacketNum(unsigned short * hkStatTotalPacketNum, CrFwPckt_t pckt) +{ + *hkStatTotalPacketNum = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 16); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum(unsigned short * hkStatCurrentPacketNum, CrFwPckt_t pckt) +{ + *hkStatCurrentPacketNum = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 18); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVod(unsigned int * hkVoltFeeVod, CrFwPckt_t pckt) +{ + *hkVoltFeeVod = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 20); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVrd(unsigned int * hkVoltFeeVrd, CrFwPckt_t pckt) +{ + *hkVoltFeeVrd = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 24); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVog(unsigned int * hkVoltFeeVog, CrFwPckt_t pckt) +{ + *hkVoltFeeVog = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 28); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVss(unsigned int * hkVoltFeeVss, CrFwPckt_t pckt) +{ + *hkVoltFeeVss = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 32); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkTempFeeCcd(unsigned int * hkTempFeeCcd, CrFwPckt_t pckt) +{ + *hkTempFeeCcd = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 36); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkTempFeeAdc(unsigned int * hkTempFeeAdc, CrFwPckt_t pckt) +{ + *hkTempFeeAdc = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 40); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkTempFeeBias(unsigned int * hkTempFeeBias, CrFwPckt_t pckt) +{ + *hkTempFeeBias = GET_UINT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 44); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatPixDataOffset(unsigned short * hkStatPixDataOffset, CrFwPckt_t pckt) +{ + *hkStatPixDataOffset = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 48); + return; +} + +void CrSemServ21DatCcdWindowParamGetHkStatNumDataWords(unsigned short * hkStatNumDataWords, CrFwPckt_t pckt) +{ + *hkStatNumDataWords = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 50); + return; +} + +void CrSemServ21DatCcdWindowParamGetDatScienceBlock(unsigned short * datScienceBlock, CrFwPckt_t pckt) +{ + *datScienceBlock = GET_USHORT_FROM_PCKT(OFFSET_PAR_LENGTH_IN_REP_PCKT + 52); + return; +} + diff --git a/CrIa/src/Services/General/CrSemParamGetter.h b/CrIa/src/Services/General/CrSemParamGetter.h new file mode 100644 index 0000000000000000000000000000000000000000..adef2356b7ba81993ece24c3a7b8b9dcb3f43ca6 --- /dev/null +++ b/CrIa/src/Services/General/CrSemParamGetter.h @@ -0,0 +1,983 @@ +/** + * @file CrSemParamGetter.h + * + * Declaration of the getter operations for all parameters of all in-coming packets. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_PARAM_GETTER_H +#define CRSEM_PARAM_GETTER_H + +#include <Pckt/CrFwPckt.h> +#include <CrFwConstants.h> + +/** + * Gets the value of the parameter HkStatSid of the DAT HK packet. + * @param hkStatSid Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3DatHkParamGetHkStatSid(unsigned short * hkStatSid, CrFwPckt_t pckt); + +/****************** + * SEM DEFAULT HK * + ******************/ +/** + * Gets the value of the parameter HkStatMode of the Operation Default HK packet. + * @param hkStatMode Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatMode(unsigned short * hkStatMode, CrFwPckt_t pckt); + +void CrSemServ3OperationDefaultHkParamGetHkStatFlags(unsigned short * hkStatFlags, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FixVal9 of the Operation Default HK packet. + * @param fixVal9 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetFixVal9(unsigned short * fixVal9, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatObtSyncFlag of the Operation Default HK packet. + * @param hkStatObtSyncFlag Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatObtSyncFlag(unsigned char * hkStatObtSyncFlag, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatWatchDog of the Operation Default HK packet. + * @param hkStatWatchDog Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatWatchDog(unsigned char * hkStatWatchDog, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatEepromPower of the Operation Default HK packet. + * @param hkStatEepromPower Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatEepromPower(unsigned char * hkStatEepromPower, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatHkPower of the Operation Default HK packet. + * @param hkStatHkPower Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatHkPower(unsigned char * hkStatHkPower, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatFpmPower of the Operation Default HK packet. + * @param hkStatFpmPower Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatFpmPower(unsigned char * hkStatFpmPower, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDatBufferOverflow of the Operation Default HK packet. + * @param hkStatDatBufferOverflow Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatDatBufferOverflow(unsigned char * hkStatDatBufferOverflow, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuMainRed of the Operation Default HK packet. + * @param hkStatScuMainRed Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatScuMainRed(unsigned char * hkStatScuMainRed, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatLastSpwlinkError of the Operation Default HK packet. + * @param hkStatLastSpwlinkError Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatLastSpwlinkError(unsigned short * hkStatLastSpwlinkError, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatLastErrorId of the Operation Default HK packet. + * @param hkStatLastErrorId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatLastErrorId(unsigned short * hkStatLastErrorId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatLastErrorFrequency of the Operation Default HK packet. + * @param hkStatLastErrorFrequency Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatLastErrorFrequency(unsigned short * hkStatLastErrorFrequency, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumCmdReceived of the Operation Default HK packet. + * @param hkStatNumCmdReceived Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatNumCmdReceived(unsigned short * hkStatNumCmdReceived, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumCmdExecuted of the Operation Default HK packet. + * @param hkStatNumCmdExecuted Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatNumCmdExecuted(unsigned short * hkStatNumCmdExecuted, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumDatSent of the Operation Default HK packet. + * @param hkStatNumDatSent Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatNumDatSent(unsigned short * hkStatNumDatSent, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuProcDutyCycle of the Operation Default HK packet. + * @param hkStatScuProcDutyCycle Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatScuProcDutyCycle(unsigned short * hkStatScuProcDutyCycle, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuNumAhbError of the Operation Default HK packet. + * @param hkStatScuNumAhbError Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatScuNumAhbError(unsigned short * hkStatScuNumAhbError, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuNumAhbCorrectableError of the Operation Default HK packet. + * @param hkStatScuNumAhbCorrectableError Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatScuNumAhbCorrectableError(unsigned short * hkStatScuNumAhbCorrectableError, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatHkNumLatchupError of the Operation Default HK packet. + * @param hkStatHkNumLatchupError Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkStatHkNumLatchupError(unsigned short * hkStatHkNumLatchupError, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempSemScu of the Operation Default HK packet. + * @param hkTempSemScu Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkTempSemScu(float * hkTempSemScu, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempSemPcu of the Operation Default HK packet. + * @param hkTempSemPcu Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkTempSemPcu(float * hkTempSemPcu, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltScuP34 of the Operation Default HK packet. + * @param hkVoltScuP34 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkVoltScuP34(float * hkVoltScuP34, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltScuP5 of the Operation Default HK packet. + * @param hkVoltScuP5 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationDefaultHkParamGetHkVoltScuP5(float * hkVoltScuP5, CrFwPckt_t pckt); + +/******************* + * SEM EXTENDED HK * + *******************/ +/** + * Gets the value of the parameter HkTempFee1 of the Operation Extended HK packet. + * @param hkTempFee1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkTempFeeCcd(float * hkTempFeeCcd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFee2 of the Operation Extended HK packet. + * @param hkTempFee2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkTempFeeStrap(float * hkTempFeeStrap, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFee3 of the Operation Extended HK packet. + * @param hkTempFee3 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkTempFeeAdc(float * hkTempFeeAdc, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFee4 of the Operation Extended HK packet. + * @param hkTempFee4 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkTempFeeBias(float * hkTempFeeBias, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFee5 of the Operation Extended HK packet. + * @param hkTempFee5 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkTempFeeDeb(float * hkTempFeeDeb, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee1 of the Operation Extended HK packet. + * @param hkVoltFee1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVod(float * hkVoltFeeVod, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee2 of the Operation Extended HK packet. + * @param hkVoltFee2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVrd(float * hkVoltFeeVrd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee3 of the Operation Extended HK packet. + * @param hkVoltFee3 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVog(float * hkVoltFeeVog, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee4 of the Operation Extended HK packet. + * @param hkVoltFee4 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeVss(float * hkVoltFeeVss, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee5 of the Operation Extended HK packet. + * @param hkVoltFee5 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeCcd(float * hkVoltFeeCcd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee6 of the Operation Extended HK packet. + * @param hkVoltFee6 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeClk(float * hkVoltFeeClk, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee7 of the Operation Extended HK packet. + * @param hkVoltFee7 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeAnaP5(float * hkVoltFeeAnaP5, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee8 of the Operation Extended HK packet. + * @param hkVoltFee8 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeAnaN5(float * hkVoltFeeAnaN5, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFee9 of the Operation Extended HK packet. + * @param hkVoltFee9 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltFeeDigP33(float * hkVoltFeeDigP33, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkCurrFeeClkBuf of the Operation Extended HK packet. + * @param hkCurrFeeClkBuf Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkCurrFeeClkBuf(float * hkCurrFeeClkBuf, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltScuFpgaP15 of the Operation Extended HK packet. + * @param hkVoltScuFpgaP15 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkVoltScuFpgaP15(float * hkVoltScuFpgaP15, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkCurrScuP34 of the Operation Extended HK packet. + * @param hkCurrScuP34 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkCurrScuP34(float * hkCurrScuP34, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrCredit of the Operation Extended HK packet. + * @param hkStatNumSpwErrCredit Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrCredit(unsigned char * hkStatNumSpwErrCredit, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrEscape of the Operation Extended HK packet. + * @param hkStatNumSpwErrEscape Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrEscape(unsigned char * hkStatNumSpwErrEscape, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrDisconnect of the Operation Extended HK packet. + * @param hkStatNumSpwErrDisconnect Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrDisconnect(unsigned char * hkStatNumSpwErrDisconnect, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrParity of the Operation Extended HK packet. + * @param hkStatNumSpwErrParity Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrParity(unsigned char * hkStatNumSpwErrParity, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrWriteSync of the Operation Extended HK packet. + * @param hkStatNumSpwErrWriteSync Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrWriteSync(unsigned char * hkStatNumSpwErrWriteSync, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrInvalidAddress of the Operation Extended HK packet. + * @param hkStatNumSpwErrInvalidAddress Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrInvalidAddress(unsigned char * hkStatNumSpwErrInvalidAddress, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrEopeep of the Operation Extended HK packet. + * @param hkStatNumSpwErrEopeep Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrEopeep(unsigned char * hkStatNumSpwErrEopeep, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrRxAhb of the Operation Extended HK packet. + * @param hkStatNumSpwErrRxAhb Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrRxAhb(unsigned char * hkStatNumSpwErrRxAhb, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrTxAhb of the Operation Extended HK packet. + * @param hkStatNumSpwErrTxAhb Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxAhb(unsigned char * hkStatNumSpwErrTxAhb, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumSpwErrTxBlocked of the Operation Extended HK packet. + * @param hkStatNumSpwErrTxBlocked Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxBlocked(unsigned char * hkStatNumSpwErrTxBlocked, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkNumSpwErrTxle of the Operation Extended HK packet. + * @param hkNumSpwErrTxle Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTxle(unsigned char * hkStatNumSpwErrTxle, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkNumSpwErrRx of the Operation Extended HK packet. + * @param hkNumSpwErrRx Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrRx(unsigned char * hkStatNumSpwErrRx, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkNumSpwErrTx of the Operation Extended HK packet. + * @param hkNumSpwErrTx Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatNumSpwErrTx(unsigned char * hkStatNumSpwErrTx, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkHeatPwmFpaCcd of the Operation Extended HK packet. + * @param hkHeatPwmFpaCcd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFpaCcd(unsigned char * hkStatHeatPwmFpaCcd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkHeatPwmFeeStrap of the Operation Extended HK packet. + * @param hkHeatPwmFeeStrap Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFeeStrap(unsigned char * hkStatHeatPwmFeeStrap, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkHeatPwmFeeAnach of the Operation Extended HK packet. + * @param hkHeatPwmFeeAnach Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmFeeAnach(unsigned char * hkStatHeatPwmFeeAnach, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkHeatPwmSpare of the Operation Extended HK packet. + * @param hkHeatPwmSpare Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatHeatPwmSpare(unsigned char * hkStatHeatPwmSpare, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatBits of the Operation Extended HK packet. + * @param hkStatBits Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatBits(unsigned char * hkStatBits, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatOBTimeSyncDelta of the Operation Extended HK packet. + * @param hkStatOBTimeSyncDelta Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ3OperationExtendedHkParamGetHkStatOBTimeSyncDelta(unsigned short * hkStatOBTimeSyncDelta, CrFwPckt_t pckt); + + +/************************** + * END OF SEM EXTENDED HK * + **************************/ + + +/** + * Gets the value of the parameter HkEventProgId of the Normal/Progress Report packet. + * @param hkEventProgId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtNormParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkEventProgId of the Error Report - Low Severity packet. + * @param hkEventProgId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrLowSevParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkEventProgId of the Error Report - Medium Severity packet. + * @param hkEventProgId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrMedSevParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkEventProgId of the Error Report - High Severity packet. + * @param hkEventProgId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrHighSevParamGetHkEventProgId(unsigned short * hkEventProgId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatSwVersion of the DAT_Event_Progress(PBSBootReady) packet. + * @param hkStatSwVersion Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatSwVersion(unsigned char * hkStatSwVersion, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatBootReason of the DAT_Event_Progress(PBSBootReady) packet. + * @param hkStatBootReason Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatBootReason(unsigned short * hkStatBootReason, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuFpgaVersion of the DAT_Event_Progress(PBSBootReady) packet. + * @param hkStatScuFpgaVersion Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatScuFpgaVersion(unsigned char * hkStatScuFpgaVersion, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuMainRedundant of the DAT_Event_Progress(PBSBootReady) packet. + * @param hkStatScuMainRedundant Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgPbsBootReadyParamGetHkStatScuMainRedundant(unsigned char * hkStatScuMainRedundant, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatSwVersion of the DAT_Event_Progress(APSBootReady) packet. + * @param hkStatSwVersion Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgApsBootReadyParamGetHkStatSwVersion(unsigned char * hkStatSwVersion, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatBootReason of the DAT_Event_Progress(APSBootReady) packet. + * @param hkStatBootReason Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgApsBootReadyParamGetHkStatBootReason(unsigned short * hkStatBootReason, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuFpgaVersion of the DAT_Event_Progress(APSBootReady) packet. + * @param hkStatScuFpgaVersion Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgApsBootReadyParamGetHkStatScuFpgaVersion(unsigned char * hkStatScuFpgaVersion, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScuMainRedundant of the DAT_Event_Progress(APSBootReady) packet. + * @param hkStatScuMainRedundant Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgApsBootReadyParamGetHkStatScuMainRedundant(unsigned char * hkStatScuMainRedundant, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatPreviousMode of the DAT_Event_Progress(ModeTransition) packet. + * @param hkStatPreviousMode Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgModeTransitionParamGetHkStatPreviousMode(unsigned short * hkStatPreviousMode, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatCurrentMode of the DAT_Event_Progress(ModeTransition) packet. + * @param hkStatCurrentMode Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgModeTransitionParamGetHkStatCurrentMode(unsigned short * hkStatCurrentMode, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDiagStep of the DAT_Event_Progress(DiagStepFinished) packet. + * @param hkStatDiagStep Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgDiagnoseStepFinishedParamGetHkStatDiagStep(unsigned short * hkStatDiagStep, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDiagStepResult of the DAT_Event_Progress(DiagStepFinished) packet. + * @param hkStatDiagStepResult Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgDiagnoseStepFinishedParamGetHkStatDiagStepResult(unsigned short * hkStatDiagStepResult, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatCfgVersion of the DAT_Event_Progress(CFGLoadReady) packet. + * @param hkStatCfgVersion Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgCfgLoadReadyParamGetHkStatCfgVersion(unsigned char * hkStatCfgVersion, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatCfgNumParamsLoaded of the DAT_Event_Progress(CFGLoadReady) packet. + * @param hkStatCfgNumParamsLoaded Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgCfgLoadReadyParamGetHkStatCfgNumParamsLoaded(unsigned short * hkStatCfgNumParamsLoaded, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatCfgNumParamsUsed of the DAT_Event_Progress(CFGLoadReady) packet. + * @param hkStatCfgNumParamsUsed Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventPrgCfgLoadReadyParamGetHkStatCfgNumParamsUsed(unsigned short * hkStatCfgNumParamsUsed, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFpaCcd of the DAT_Event_Warning(TempUnstable) packet. + * @param hkTempFpaCcd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarNoThermalStabilityParamGetHkTempFpaCcd(int * hkTempFpaCcd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFpaStrap of the DAT_Event_Warning(TempUnstable) packet. + * @param hkTempFpaStrap Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarNoThermalStabilityParamGetHkTempFpaStrap(int * hkTempFpaStrap, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFee1 of the DAT_Event_Warning(TempUnstable) packet. + * @param hkTempFee1 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarNoThermalStabilityParamGetHkTempFee1(int * hkTempFee1, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFpaCcd of the DAT_Event_Warning(FPATempTooHigh) packet. + * @param hkTempFpaCcd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarFpaTempTooHighParamGetHkTempFpaCcd(int * hkTempFpaCcd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter FixVal8 of the DAT_Event_Warning(WrongExposureTime) packet. + * @param fixVal8 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarWrongExposureTimeParamGetFixVal8(unsigned char * fixVal8, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ParCcdReadoutMode of the DAT_Event_Warning(WrongExposureTime) packet. + * @param parCcdReadoutMode Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarWrongExposureTimeParamGetParCcdReadoutMode(unsigned char * parCcdReadoutMode, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ParExposureTime of the DAT_Event_Warning(WrongExposureTime) packet. + * @param parExposureTime Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarWrongExposureTimeParamGetParExposureTime(unsigned int * parExposureTime, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatExposureTime of the DAT_Event_Warning(WrongRepetitionPeriod) packet. + * @param hkStatExposureTime Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarWrongRepetitionPeriodParamGetHkStatExposureTime(unsigned int * hkStatExposureTime, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter ParRepetitionPeriod of the DAT_Event_Warning(WrongRepetitionPeriod) packet. + * @param parRepetitionPeriod Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarWrongRepetitionPeriodParamGetParRepetitionPeriod(unsigned int * parRepetitionPeriod, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatMode of the DAT_Event_Warning(WrongRepetitionPeriod) packet. + * @param hkStatMode Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventWarWrongRepetitionPeriodParamGetHkStatMode(unsigned short * hkStatMode, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDatSequCount of the DAT_Event_Warning(FPMoffOnlyPattern) packet. + * @param hkStatDatSequCount Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtWarPatterParamGetHkStatDatSequCount(unsigned short * hkStatDatSequCount, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDatSequCount of the DAT_Event_Warning(PackEncodeFailure) packet. + * @param hkStatDatSequCount Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtWarPackwrParamGetHkStatDatSequCount(unsigned short * hkStatDatSequCount, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatBootReason of the DAT_Event_Error(unexpected re-boot) packet. + * @param hkStatBootReason Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatBootReason(unsigned short * hkStatBootReason, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatRegProcStatus of the DAT_Event_Error(unexpected re-boot) packet. + * @param hkStatRegProcStatus Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcStatus(unsigned int * hkStatRegProcStatus, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatRegProcTrapBase of the DAT_Event_Error(unexpected re-boot) packet. + * @param hkStatRegProcTrapBase Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcTrapBase(unsigned int * hkStatRegProcTrapBase, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatRegProcProgrammCount of the DAT_Event_Error(unexpected re-boot) packet. + * @param hkStatRegProcProgrammCount Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcProgrammCount(unsigned int * hkStatRegProcProgrammCount, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatRegProcProgrammInstruct of the DAT_Event_Error(unexpected re-boot) packet. + * @param hkStatRegProcProgrammInstruct Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrUnexpectedRebootParamGetHkStatRegProcProgrammInstruct(unsigned int * hkStatRegProcProgrammInstruct, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatWatchDogTimerValueSet of the DAT_Event_Error(watchdog failure) packet. + * @param hkStatWatchDogTimerValueSet Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrWatchdogFailureParamGetHkStatWatchDogTimerValueSet(unsigned int * hkStatWatchDogTimerValueSet, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatWatchDogTimerValueRead of the DAT_Event_Error(watchdog failure) packet. + * @param hkStatWatchDogTimerValueRead Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrWatchdogFailureParamGetHkStatWatchDogTimerValueRead(unsigned int * hkStatWatchDogTimerValueRead, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatSpwReceiveError of the DAT_Event_Error(SpW Error) packet. + * @param hkStatSpwReceiveError Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrCmdSpwRxErrorParamGetHkStatSpwReceiveError(unsigned short * hkStatSpwReceiveError, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatPbsCfgSizeExpected of the DAT_Event_Error(PBS CFG size wrong) packet. + * @param hkStatPbsCfgSizeExpected Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrEepromPbsCfgSizeWrongParamGetHkStatPbsCfgSizeExpected(unsigned short * hkStatPbsCfgSizeExpected, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatPbsCfgSizeRead of the DAT_Event_Error(PBS CFG size wrong) packet. + * @param hkStatPbsCfgSizeRead Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrEepromPbsCfgSizeWrongParamGetHkStatPbsCfgSizeRead(unsigned short * hkStatPbsCfgSizeRead, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatRegAddress of the DAT_Event_Error(Reg writing wrong) packet. + * @param hkStatRegAddress Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrWritingRegisterFailedParamGetHkStatRegAddress(unsigned int * hkStatRegAddress, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatRegValueWritten of the DAT_Event_Error(Reg writing wrong) packet. + * @param hkStatRegValueWritten Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrWritingRegisterFailedParamGetHkStatRegValueWritten(unsigned int * hkStatRegValueWritten, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatRegValueRead of the DAT_Event_Error(Reg writing wrong) packet. + * @param hkStatRegValueRead Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EventErrWritingRegisterFailedParamGetHkStatRegValueRead(unsigned int * hkStatRegValueRead, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDmaErrType of the DAT_Event_Error(DMA data transfer failure) packet. + * @param hkStatDmaErrType Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrDatDmaParamGetHkStatDmaErrType(unsigned short * hkStatDmaErrType, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVod of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVod Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVod(unsigned int * hkParVoltFeeVod, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVrd of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVrd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVrd(unsigned int * hkParVoltFeeVrd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVss of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVss Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVss(unsigned int * hkParVoltFeeVss, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVog of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVog Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVog(unsigned int * hkParVoltFeeVog, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVod2 of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVod2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVod2(unsigned int * hkParVoltFeeVod2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVrd2 of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVrd2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVrd2(unsigned int * hkParVoltFeeVrd2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVss2 of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVss2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVss2(unsigned int * hkParVoltFeeVss2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkParVoltFeeVog2 of the DAT_Event_Error(BIAS voltage wrong) packet. + * @param hkParVoltFeeVog2 Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrBiasSetParamGetHkParVoltFeeVog2(unsigned int * hkParVoltFeeVog2, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatSynctErrType of the DAT_Event_Error(FEE-SCU sync failure) packet. + * @param hkStatSynctErrType Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrSyncParamGetHkStatSynctErrType(unsigned short * hkStatSynctErrType, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatScriptErrType of the DAT_Event_Error(FEE script error) packet. + * @param hkStatScriptErrType Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrScriptParamGetHkStatScriptErrType(unsigned short * hkStatScriptErrType, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatPowErrType of the DAT_Event_Error(PCU power switching failed) packet. + * @param hkStatPowErrType Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrPwrParamGetHkStatPowErrType(unsigned short * hkStatPowErrType, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatPcuPowWord of the DAT_Event_Error(PCU power switching failed) packet. + * @param hkStatPcuPowWord Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ5EvtErrPwrParamGetHkStatPcuPowWord(unsigned short * hkStatPcuPowWord, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDataAcqId of the DAT CCD Window packet. + * @param hkStatDataAcqId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqId(unsigned int * hkStatDataAcqId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDataAcqType of the DAT CCD Window packet. + * @param hkStatDataAcqType Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqType(unsigned char * hkStatDataAcqType, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDataAcqSrc of the DAT CCD Window packet. + * @param hkStatDataAcqSrc Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqSrc(unsigned char * hkStatDataAcqSrc, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDataAcqTypeSrc of the DAT CCD Window packet. + * @param hkStatDataAcqTypeSrc Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqTypeSrc(unsigned char * hkStatDataAcqTypeSrc, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatCcdTimingScriptId of the DAT CCD Window packet. + * @param hkStatCcdTimingScriptId Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatCcdTimingScriptId(unsigned char * hkStatCcdTimingScriptId, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatDataAcqTime of the DAT CCD Window packet. + * @param hkStatDataAcqTime Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatDataAcqTime(unsigned char * hkStatDataAcqTime, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatExposureTime of the DAT CCD Window packet. + * @param hkStatExposureTime Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatExposureTime(unsigned int * hkStatExposureTime, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatTotalPacketNum of the DAT CCD Window packet. + * @param hkStatTotalPacketNum Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatTotalPacketNum(unsigned short * hkStatTotalPacketNum, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatCurrentPacketNum of the DAT CCD Window packet. + * @param hkStatCurrentPacketNum Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatCurrentPacketNum(unsigned short * hkStatCurrentPacketNum, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFeeVod of the DAT CCD Window packet. + * @param hkVoltFeeVod Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVod(unsigned int * hkVoltFeeVod, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFeeVrd of the DAT CCD Window packet. + * @param hkVoltFeeVrd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVrd(unsigned int * hkVoltFeeVrd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFeeVog of the DAT CCD Window packet. + * @param hkVoltFeeVog Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVog(unsigned int * hkVoltFeeVog, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkVoltFeeVss of the DAT CCD Window packet. + * @param hkVoltFeeVss Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkVoltFeeVss(unsigned int * hkVoltFeeVss, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFeeCcd of the DAT CCD Window packet. + * @param hkTempFeeCcd Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkTempFeeCcd(unsigned int * hkTempFeeCcd, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFeeAdc of the DAT CCD Window packet. + * @param hkTempFeeAdc Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkTempFeeAdc(unsigned int * hkTempFeeAdc, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkTempFeeBias of the DAT CCD Window packet. + * @param hkTempFeeBias Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkTempFeeBias(unsigned int * hkTempFeeBias, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatPixDataOffset of the DAT CCD Window packet. + * @param hkStatPixDataOffset Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatPixDataOffset(unsigned short * hkStatPixDataOffset, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter HkStatNumDataWords of the DAT CCD Window packet. + * @param hkStatNumDataWords Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetHkStatNumDataWords(unsigned short * hkStatNumDataWords, CrFwPckt_t pckt); + +/** + * Gets the value of the parameter DatScienceBlock of the DAT CCD Window packet. + * @param datScienceBlock Pointer to the parameter that will be filled with data from the packet. + * @param pckt Pointer to the packet. + */ +void CrSemServ21DatCcdWindowParamGetDatScienceBlock(unsigned short * datScienceBlock, CrFwPckt_t pckt); + +#endif /* CRSEM_PARAM_GETTER_H */ + diff --git a/CrIa/src/Services/General/CrSemParamSetter.c b/CrIa/src/Services/General/CrSemParamSetter.c new file mode 100644 index 0000000000000000000000000000000000000000..79d0fa3bfda6526d5847824f9989fa6859f5cecc --- /dev/null +++ b/CrIa/src/Services/General/CrSemParamSetter.c @@ -0,0 +1,344 @@ +/** + * @file CrSemParamSetter.c + * @ingroup CrIaServicesGeneral + * @authors FW Profile code generator, P&P Software GmbH, 2015; Institute for Astrophysics, 2015-2016 + * + * @brief Implementation of the setter operations for all parameters of all out-going packets. + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "CrSemParamSetter.h" +#include "CrSemConstants.h" +#include "CrFwCmpData.h" +#include "CrIaPckt.h" +#include "IfswUtilities.h" +#include "FwSmConfig.h" +#include <string.h> + + + +void CrSemServ3CmdHkEnableParamSetParSidHk(FwSmDesc_t smDesc, unsigned char parSidHk) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0] = parSidHk; +} + +void CrSemServ3CmdHkEnableParamSetPad(FwSmDesc_t smDesc, unsigned char pad) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1] = pad; +} + +void CrSemServ3CmdHkDisableParamSetParSidHk(FwSmDesc_t smDesc, unsigned char parSidHk) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0] = parSidHk; +} + +void CrSemServ3CmdHkDisableParamSetPad(FwSmDesc_t smDesc, unsigned char pad) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1] = pad; +} + +void CrSemServ3CmdHkPeriodParamSetParSidHk(FwSmDesc_t smDesc, unsigned char parSidHk) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0] = parSidHk; +} + +void CrSemServ3CmdHkPeriodParamSetParHkPeriod(FwSmDesc_t smDesc, unsigned short parHkPeriod) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1] = (parHkPeriod >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2] = (parHkPeriod & 0xFF); +} + +void CrSemServ3CmdHkPeriodParamSetPad(FwSmDesc_t smDesc, unsigned char pad) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 3] = pad; +} + +/* this does not work ... */ +void CrSemServ9CmdTimeUpdateParamSetParObtSyncTime(FwSmDesc_t smDesc, const unsigned char * parObtSyncTime) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + memcpy(&cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0], parObtSyncTime, 6); +} + + +/*************************** + * CMD_Operation_Parameter * + ***************************/ + +void CrSemServ220CmdOperParamParamSetParExposureTime(FwSmDesc_t smDesc, unsigned int parExposureTime) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0] = ( parExposureTime >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1] = ((parExposureTime >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2] = ((parExposureTime >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 3] = ( parExposureTime & 0xFF); +} + +void CrSemServ220CmdOperParamParamSetParRepetitionPeriod(FwSmDesc_t smDesc, unsigned int parRepetitionPeriod) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 4] = ( parRepetitionPeriod >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 5] = ((parRepetitionPeriod >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 6] = ((parRepetitionPeriod >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 7] = ( parRepetitionPeriod & 0xFF); +} + +void CrSemServ220CmdOperParamParamSetParAcquisitionNum(FwSmDesc_t smDesc, unsigned int parAcquisitionNum) /* NOTE: manual change to 32 bit */ +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 8] = ( parAcquisitionNum >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 9] = ((parAcquisitionNum >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 10] = ((parAcquisitionNum >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 11] = ( parAcquisitionNum & 0xFF); +} + +void CrSemServ220CmdOperParamParamSetParDataOversampling(FwSmDesc_t smDesc, unsigned char parDataOversampling) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 12] = parDataOversampling; +} + +void CrSemServ220CmdOperParamParamSetParCcdReadoutMode(FwSmDesc_t smDesc, unsigned char parCcdReadoutMode) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 13] = parCcdReadoutMode; +} + +/*************************** + * CMD_Temp_Control_Enable * + ***************************/ + +void CrSemServ220CmdTempCtrlEnableParamSetParTempControlTarget(FwSmDesc_t smDesc, unsigned short parTempControlTarget) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0] = (parTempControlTarget >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1] = (parTempControlTarget & 0xFF); +} + +/**************************** + * CMD_Functional_Parameter * + ****************************/ + +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosX(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosX) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0] = (parCcdWindowStarPosX >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1] = (parCcdWindowStarPosX & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosY(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosY) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 2] = (parCcdWindowStarPosY >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 3] = (parCcdWindowStarPosY & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosX2(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosX2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 4] = (parCcdWindowStarPosX2 >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 5] = (parCcdWindowStarPosX2 & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosY2(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosY2) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 6] = (parCcdWindowStarPosY2 >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 7] = (parCcdWindowStarPosY2 & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParDataAcqSrc(FwSmDesc_t smDesc, unsigned short parDataAcqSrc) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 8] = (parDataAcqSrc >> 8); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 9] = (parDataAcqSrc & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParVoltFeeVod(FwSmDesc_t smDesc, unsigned int parVoltFeeVod) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 10] = ( parVoltFeeVod >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 11] = ((parVoltFeeVod >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 12] = ((parVoltFeeVod >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 13] = ( parVoltFeeVod & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParVoltFeeVrd(FwSmDesc_t smDesc, unsigned int parVoltFeeVrd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 14] = ( parVoltFeeVrd >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 15] = ((parVoltFeeVrd >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 16] = ((parVoltFeeVrd >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 17] = ( parVoltFeeVrd & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParVoltFeeVss(FwSmDesc_t smDesc, unsigned int parVoltFeeVss) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 18] = ( parVoltFeeVss >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 19] = ((parVoltFeeVss >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 20] = ((parVoltFeeVss >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 21] = ( parVoltFeeVss & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParHeatTempFpaCcd(FwSmDesc_t smDesc, unsigned int parHeatTempFpaCcd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 22] = ( parHeatTempFpaCcd >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 23] = ((parHeatTempFpaCcd >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 24] = ((parHeatTempFpaCcd >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 25] = ( parHeatTempFpaCcd & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParHeatTempFeeStrap(FwSmDesc_t smDesc, unsigned int parHeatTempFeeStrap) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 26] = ( parHeatTempFeeStrap >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 27] = ((parHeatTempFeeStrap >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 28] = ((parHeatTempFeeStrap >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 29] = ( parHeatTempFeeStrap & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParHeatTempFeeAnach(FwSmDesc_t smDesc, unsigned int parHeatTempFeeAnach) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 30] = ( parHeatTempFeeAnach >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 31] = ((parHeatTempFeeAnach >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 32] = ((parHeatTempFeeAnach >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 33] = ( parHeatTempFeeAnach & 0xFF); +} + +void CrSemServ220CmdFunctParamParamSetParHeatTempSpare(FwSmDesc_t smDesc, unsigned int parHeatTempSpare) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 34] = ( parHeatTempSpare >> 24); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 35] = ((parHeatTempSpare >> 16) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 36] = ((parHeatTempSpare >> 8 ) & 0xFF); + cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 37] = ( parHeatTempSpare & 0xFF); +} + +/**************************** + * CMD_DIAGNOSTIC_Enable * + ****************************/ + +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagCcd(FwSmDesc_t smDesc, unsigned short parStepEnDiagCcd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepEnDiagCcd, 0, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagFee(FwSmDesc_t smDesc, unsigned short parStepEnDiagFee) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepEnDiagFee, 1, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagTemp(FwSmDesc_t smDesc, unsigned short parStepEnDiagTemp) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepEnDiagTemp, 2, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagAna(FwSmDesc_t smDesc, unsigned short parStepEnDiagAna) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepEnDiagAna, 3, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagExpos(FwSmDesc_t smDesc, unsigned short parStepEnDiagExpos) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepEnDiagExpos, 4, 1, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagCcd(FwSmDesc_t smDesc, unsigned short parStepDebDiagCcd) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepDebDiagCcd, 5, 2, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagFee(FwSmDesc_t smDesc, unsigned short parStepDebDiagFee) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepDebDiagFee, 7, 2, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 0])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagTemp(FwSmDesc_t smDesc, unsigned short parStepDebDiagTemp) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepDebDiagTemp, 1, 2, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagAna(FwSmDesc_t smDesc, unsigned short parStepDebDiagAna) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepDebDiagAna, 3, 2, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1])); + return; +} + +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagExpos(FwSmDesc_t smDesc, unsigned short parStepDebDiagExpos) +{ + CrFwCmpData_t* cmpData = (CrFwCmpData_t*)FwSmGetData(smDesc); + CrFwOutCmpData_t* cmpSpecificData = (CrFwOutCmpData_t*)(cmpData->cmpSpecificData); + PutNBits8 (parStepDebDiagExpos, 5, 3, (unsigned char *)&(cmpSpecificData->pckt[OFFSET_PAR_LENGTH_OUT_CMD_PCKT + 1])); + return; +} diff --git a/CrIa/src/Services/General/CrSemParamSetter.h b/CrIa/src/Services/General/CrSemParamSetter.h new file mode 100644 index 0000000000000000000000000000000000000000..812eb211faa60e839e6d9490852acd6a4933a450 --- /dev/null +++ b/CrIa/src/Services/General/CrSemParamSetter.h @@ -0,0 +1,233 @@ +/** + * @file CrSemParamSetter.h + * + * Declaration of the setter operations for all parameters of all out-going packets. + * + * @author code generator + * @copyright P&P Software GmbH, 2015 + */ + +#ifndef CRSEM_PARAM_SETTER_H +#define CRSEM_PARAM_SETTER_H + +#include <FwSmCore.h> +#include <CrFwConstants.h> + +/** + * Sets the value of the parameter ParSidHk of the out-going packet CMD Housekeeping Data Enable. + * @param parSidHk + */ +void CrSemServ3CmdHkEnableParamSetParSidHk(FwSmDesc_t smDesc, unsigned char parSidHk); + +/** + * Sets the value of the parameter Pad of the out-going packet CMD Housekeeping Data Enable. + * @param pad + */ +void CrSemServ3CmdHkEnableParamSetPad(FwSmDesc_t smDesc, unsigned char pad); + +/** + * Sets the value of the parameter ParSidHk of the out-going packet CMD Housekeeping Data Disable. + * @param parSidHk + */ +void CrSemServ3CmdHkDisableParamSetParSidHk(FwSmDesc_t smDesc, unsigned char parSidHk); + +/** + * Sets the value of the parameter Pad of the out-going packet CMD Housekeeping Data Disable. + * @param pad + */ +void CrSemServ3CmdHkDisableParamSetPad(FwSmDesc_t smDesc, unsigned char pad); + +/** + * Sets the value of the parameter ParSidHk of the out-going packet CMD Housekeeping Data Period. + * @param parSidHk + */ +void CrSemServ3CmdHkPeriodParamSetParSidHk(FwSmDesc_t smDesc, unsigned char parSidHk); + +/** + * Sets the value of the parameter ParHkPeriod of the out-going packet CMD Housekeeping Data Period. + * @param parHkPeriod + */ +void CrSemServ3CmdHkPeriodParamSetParHkPeriod(FwSmDesc_t smDesc, unsigned short parHkPeriod); + +/** + * Sets the value of the parameter Pad of the out-going packet CMD Housekeeping Data Period. + * @param pad + */ +void CrSemServ3CmdHkPeriodParamSetPad(FwSmDesc_t smDesc, unsigned char pad); + +/** + * Sets the value of the parameter ParObtSyncTime of the out-going packet CMD Time Update. + * @param parObtSyncTime On-board time at next synchronization SpaceWire TimeCode + */ +void CrSemServ9CmdTimeUpdateParamSetParObtSyncTime(FwSmDesc_t smDesc, const unsigned char * parObtSyncTime); + +/** + * Sets the value of the parameter ParExposureTime of the out-going packet CMD Operation Parameter. + * @param parExposureTime + */ +void CrSemServ220CmdOperParamParamSetParExposureTime(FwSmDesc_t smDesc, unsigned int parExposureTime); + +/** + * Sets the value of the parameter ParRepetitionPeriod of the out-going packet CMD Operation Parameter. + * @param parRepetitionPeriod + */ +void CrSemServ220CmdOperParamParamSetParRepetitionPeriod(FwSmDesc_t smDesc, unsigned int parRepetitionPeriod); + +/** + * Sets the value of the parameter ParAcquisitionNum of the out-going packet CMD Operation Parameter. + * @param parAcquisitionNum + */ +void CrSemServ220CmdOperParamParamSetParAcquisitionNum(FwSmDesc_t smDesc, unsigned int parAcquisitionNum); /* NOTE: manual change */ + +/** + * Sets the value of the parameter ParDataOversampling of the out-going packet CMD Operation Parameter. + * @param parDataOversampling + */ +void CrSemServ220CmdOperParamParamSetParDataOversampling(FwSmDesc_t smDesc, unsigned char parDataOversampling); + +/** + * Sets the value of the parameter ParCcdReadoutMode of the out-going packet CMD Operation Parameter. + * @param parCcdReadoutMode + */ +void CrSemServ220CmdOperParamParamSetParCcdReadoutMode(FwSmDesc_t smDesc, unsigned char parCcdReadoutMode); + +/** + * Sets the value of the parameter ParTempControlTarget of the out-going packet CMD Temperature Control Enable. + * @param parTempControlTarget Temperature control target (TBC). + */ +void CrSemServ220CmdTempCtrlEnableParamSetParTempControlTarget(FwSmDesc_t smDesc, unsigned short parTempControlTarget); + +/** + * Sets the value of the parameter ParCcdWindowStarPosX of the out-going packet Changes SEM Functional Parameter. + * @param parCcdWindowStarPosX TBD + */ +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosX(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosX); + +/** + * Sets the value of the parameter ParCcdWindowStarPosY of the out-going packet Changes SEM Functional Parameter. + * @param parCcdWindowStarPosY TBD + */ +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosY(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosY); + +/** + * Sets the value of the parameter ParCcdWindowStarPosX2 of the out-going packet Changes SEM Functional Parameter. + * @param parCcdWindowStarPosX2 TBD + */ +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosX2(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosX2); + +/** + * Sets the value of the parameter ParCcdWindowStarPosY2 of the out-going packet Changes SEM Functional Parameter. + * @param parCcdWindowStarPosY2 TBD + */ +void CrSemServ220CmdFunctParamParamSetParCcdWindowStarPosY2(FwSmDesc_t smDesc, unsigned short parCcdWindowStarPosY2); + +/** + * Sets the value of the parameter ParDataAcqSrc of the out-going packet Changes SEM Functional Parameter. + * @param parDataAcqSrc TBD + */ +void CrSemServ220CmdFunctParamParamSetParDataAcqSrc(FwSmDesc_t smDesc, unsigned short parDataAcqSrc); + +/** + * Sets the value of the parameter ParVoltFeeVod of the out-going packet Changes SEM Functional Parameter. + * @param parVoltFeeVod TBD + */ +void CrSemServ220CmdFunctParamParamSetParVoltFeeVod(FwSmDesc_t smDesc, unsigned int parVoltFeeVod); + +/** + * Sets the value of the parameter ParVoltFeeVrd of the out-going packet Changes SEM Functional Parameter. + * @param parVoltFeeVrd TBD + */ +void CrSemServ220CmdFunctParamParamSetParVoltFeeVrd(FwSmDesc_t smDesc, unsigned int parVoltFeeVrd); + +/** + * Sets the value of the parameter ParVoltFeeVss of the out-going packet Changes SEM Functional Parameter. + * @param parVoltFeeVss TBD + */ +void CrSemServ220CmdFunctParamParamSetParVoltFeeVss(FwSmDesc_t smDesc, unsigned int parVoltFeeVss); + +/** + * Sets the value of the parameter ParHeatTempFpaCcd of the out-going packet Changes SEM Functional Parameter. + * @param parHeatTempFpaCcd TBD + */ +void CrSemServ220CmdFunctParamParamSetParHeatTempFpaCcd(FwSmDesc_t smDesc, unsigned int parHeatTempFpaCcd); + +/** + * Sets the value of the parameter ParHeatTempFeeStrap of the out-going packet Changes SEM Functional Parameter. + * @param parHeatTempFeeStrap TBD + */ +void CrSemServ220CmdFunctParamParamSetParHeatTempFeeStrap(FwSmDesc_t smDesc, unsigned int parHeatTempFeeStrap); + +/** + * Sets the value of the parameter ParHeatTempFeeAnach of the out-going packet Changes SEM Functional Parameter. + * @param parHeatTempFeeAnach TBD + */ +void CrSemServ220CmdFunctParamParamSetParHeatTempFeeAnach(FwSmDesc_t smDesc, unsigned int parHeatTempFeeAnach); + +/** + * Sets the value of the parameter ParHeatTempSpare of the out-going packet Changes SEM Functional Parameter. + * @param parHeatTempSpare TBD + */ +void CrSemServ220CmdFunctParamParamSetParHeatTempSpare(FwSmDesc_t smDesc, unsigned int parHeatTempSpare); + +/** + * Sets the value of the parameter ParStepEnDiagCcd of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagCcd(FwSmDesc_t smDesc, unsigned short parStepEnDiagCcd); + +/** + * Sets the value of the parameter ParStepEnDiagFee of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagFee(FwSmDesc_t smDesc, unsigned short parStepEnDiagFee); + +/** + * Sets the value of the parameter ParStepEnDiagTemp of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagTemp(FwSmDesc_t smDesc, unsigned short parStepEnDiagTemp); + +/** + * Sets the value of the parameter ParStepEnDiagAna of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagAna(FwSmDesc_t smDesc, unsigned short parStepEnDiagAna); + +/** + * Sets the value of the parameter ParStepEnDiagExpos of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepEnDiagExpos(FwSmDesc_t smDesc, unsigned short parStepEnDiagExpos); + +/** + * Sets the value of the parameter ParStepDebDiagCcd of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagCcd(FwSmDesc_t smDesc, unsigned short parStepDebDiagCcd); + +/** + * Sets the value of the parameter ParStepDebDiagFee of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagFee(FwSmDesc_t smDesc, unsigned short parStepDebDiagFee); + +/** + * Sets the value of the parameter ParStepDebDiagTemp of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagTemp(FwSmDesc_t smDesc, unsigned short parStepDebDiagTemp); + +/** + * Sets the value of the parameter ParStepDebDiagAna of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagAna(FwSmDesc_t smDesc, unsigned short parStepDebDiagAna); + +/** + * Sets the value of the parameter ParStepDebDiagExpos of the out-going packet CMD_DIAGNOSTIC_Enable. + * @param parStepEnDiagCcd TBD + */ +void CrSemServ222CmdDiagEnableParamSetParStepDebDiagExpos(FwSmDesc_t smDesc, unsigned short parStepDebDiagExpos); + +#endif /* CRSEM_PARAM_SETTER_H */ + diff --git a/CrIa/src/Ta/AngleMethod.c b/CrIa/src/Ta/AngleMethod.c new file mode 120000 index 0000000000000000000000000000000000000000..39a68c8b7272ed81027442dd2a7eadbd513b9c60 --- /dev/null +++ b/CrIa/src/Ta/AngleMethod.c @@ -0,0 +1 @@ +../../../TargetAcquisition/src/AngleMethod.c \ No newline at end of file diff --git a/CrIa/src/Ta/AngleMethod.h b/CrIa/src/Ta/AngleMethod.h new file mode 120000 index 0000000000000000000000000000000000000000..416a43a08d2f102d38ff1673e20fa1a10c322e85 --- /dev/null +++ b/CrIa/src/Ta/AngleMethod.h @@ -0,0 +1 @@ +../../../TargetAcquisition/src/AngleMethod.h \ No newline at end of file diff --git a/CrIa/src/Ta/StarExtractor.c b/CrIa/src/Ta/StarExtractor.c new file mode 120000 index 0000000000000000000000000000000000000000..bc9c2028564f8e8d99c8d7e91c1532a84b557345 --- /dev/null +++ b/CrIa/src/Ta/StarExtractor.c @@ -0,0 +1 @@ +../../../TargetAcquisition/src/StarExtractor.c \ No newline at end of file diff --git a/CrIa/src/Ta/StarExtractor.h b/CrIa/src/Ta/StarExtractor.h new file mode 120000 index 0000000000000000000000000000000000000000..1a8d0fea6c88ba09233699604504d357cfcb6f2e --- /dev/null +++ b/CrIa/src/Ta/StarExtractor.h @@ -0,0 +1 @@ +../../../TargetAcquisition/src/StarExtractor.h \ No newline at end of file diff --git a/CrIa/src/Ta/StarPosDistortCorr.c b/CrIa/src/Ta/StarPosDistortCorr.c new file mode 120000 index 0000000000000000000000000000000000000000..1f8bac890f881a58f51dc15e033061dca97f0570 --- /dev/null +++ b/CrIa/src/Ta/StarPosDistortCorr.c @@ -0,0 +1 @@ +../../../TargetAcquisition/src/StarPosDistortCorr.c \ No newline at end of file diff --git a/CrIa/src/Ta/StarPosDistortCorr.h b/CrIa/src/Ta/StarPosDistortCorr.h new file mode 120000 index 0000000000000000000000000000000000000000..48d3bc41706fa4cac64c00927425a06e6c6e4340 --- /dev/null +++ b/CrIa/src/Ta/StarPosDistortCorr.h @@ -0,0 +1 @@ +../../../TargetAcquisition/src/StarPosDistortCorr.h \ No newline at end of file diff --git a/CrIa/src/Ta/TaDatatypes.h b/CrIa/src/Ta/TaDatatypes.h new file mode 120000 index 0000000000000000000000000000000000000000..7dd40c5141898efc373df0c378a7a6ddef7b234b --- /dev/null +++ b/CrIa/src/Ta/TaDatatypes.h @@ -0,0 +1 @@ +../../../TargetAcquisition/src/TaDatatypes.h \ No newline at end of file diff --git a/CrIa/src/Ta/TargetAcquisition.c b/CrIa/src/Ta/TargetAcquisition.c new file mode 120000 index 0000000000000000000000000000000000000000..585d31bc1bffc47f3ce39cab67a05930b772fb60 --- /dev/null +++ b/CrIa/src/Ta/TargetAcquisition.c @@ -0,0 +1 @@ +../../../TargetAcquisition/src/TargetAcquisition.c \ No newline at end of file diff --git a/CrIa/src/Ta/TargetAcquisition.h b/CrIa/src/Ta/TargetAcquisition.h new file mode 120000 index 0000000000000000000000000000000000000000..722b5cd7beafbe2f05e33432a141ca2c3c44af30 --- /dev/null +++ b/CrIa/src/Ta/TargetAcquisition.h @@ -0,0 +1 @@ +../../../TargetAcquisition/src/TargetAcquisition.h \ No newline at end of file diff --git a/CrIa/src/byteorder.h b/CrIa/src/byteorder.h new file mode 100644 index 0000000000000000000000000000000000000000..b0397059a8dfb1f632f2df24db380ec1d46beab9 --- /dev/null +++ b/CrIa/src/byteorder.h @@ -0,0 +1,273 @@ +/** + * @file byteorder.h + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * This is a set of macros for consistent endianess conversion. They work + * for both little and big endian cpus. + * + * conversion of XX-bit integers (16- or 32-) between native CPU format + * and little/big endian format: + * cpu_to_[bl]eXX(uintXX_t x) + * [bl]eXX_to_cpu(uintXX_t x) + * + * the same, but change in situ: + * cpu_to_[bl]eXXs(uintXX_t x) + * [bl]eXX_to_cpus(uintXX_t x) + * + * + * This is based on the byte order macros from the linux kernel, see: + * include/linux/byteorder/generic.h + * include/uapi/linux/swab.h + * include/uapi/linux/byteorder/big_endian.h + * include/uapi/linux/byteorder/little_endian.h + * by @author Linus Torvalds et al. + * + */ +#ifndef BYTEORDER_H +#define BYTEORDER_H + +#include <stdint.h> + + + +#ifdef __BIG_ENDIAN +#undef __BIG_ENDIAN +#endif + +#ifdef __LITTLE_ENDIAN +#undef __LITTLE_ENDIAN +#endif + +#if (__sparc__) +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif +#endif + +#if (__i386__ || __x86_64__) +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#endif + + +#define ___constant_swab16(x) ((uint16_t)( \ + (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ + (((uint16_t)(x) & (uint16_t)0xff00U) >> 8))) + +#define ___constant_swab32(x) ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))) + + +#ifdef USE_BUILTIN_BSWAP +#if GCC_VERSION >= 40400 +#define __HAVE_BUILTIN_BSWAP32__ +#endif +#if GCC_VERSION >= 40800 +#define __HAVE_BUILTIN_BSWAP16__ +#endif +#endif /* USE_BUILTIN_BSWAP */ + + +static inline __attribute__((const)) uint16_t __fswab16(uint16_t val) +{ +#ifdef __HAVE_BUILTIN_BSWAP16__ + return __builtin_bswap16(val); +#else + return ___constant_swab16(val); +#endif +} + + +static inline __attribute__((const)) uint32_t __fswab32(uint32_t val) +{ +#ifdef __HAVE_BUILTIN_BSWAP32__ + return __builtin_bswap32(val); +#else + return ___constant_swab32(val); +#endif +} + + +/** + * @brief return a byteswapped 16-bit value + * @param x value to byteswap + */ + +#define __swab16(x) \ + (__builtin_constant_p((uint16_t)(x)) ? \ + ___constant_swab16(x) : \ + __fswab16(x)) + + +/** + * @brief return a byteswapped 32-bit value + * @param x a value to byteswap + */ + +#define __swab32(x) \ + (__builtin_constant_p((uint32_t)(x)) ? \ + ___constant_swab32(x) : \ + __fswab32(x)) + + +/** + * @brief return a byteswapped 16-bit value from a pointer + * @param p a pointer to a naturally-aligned 16-bit value + */ +static inline uint16_t __swab16p(const uint16_t *p) +{ + return __swab16(*p); +} + + +/** + * @brief return a byteswapped 32-bit value from a pointer + * @param p a pointer to a naturally-aligned 32-bit value + */ +static inline uint32_t __swab32p(const uint32_t *p) +{ + return __swab32(*p); +} + + +/** + * @brief byteswap a 16-bit value in-place + * @param p a pointer to a naturally-aligned 16-bit value + */ + +static inline void __swab16s(uint16_t *p) +{ + *p = __swab16p(p); +} + + +/** + * @brief byteswap a 32-bit value in-place + * @param p a pointer to a naturally-aligned 32-bit value + */ + +static inline void __swab32s(uint32_t *p) +{ + *p = __swab32p(p); +} + + + +#ifdef __BIG_ENDIAN + +#define __cpu_to_le16(x) ((uint16_t)__swab16((x))) +#define __cpu_to_le32(x) ((uint32_t)__swab32((x))) + +#define __cpu_to_le16s(x) __swab16s((x)) +#define __cpu_to_le32s(x) __swab32s((x)) + +#define __cpu_to_be16(x) ((uint16_t)(x)) +#define __cpu_to_be32(x) ((uint32_t)(x)) + +#define __cpu_to_be16s(x) { (void)(x); } +#define __cpu_to_be32s(x) { (void)(x); } + + + +#define __le16_to_cpu(x) __swab16((uint16_t)(x)) +#define __le32_to_cpu(x) __swab32((uint32_t)(x)) + +#define __le16_to_cpus(x) __swab16s((x)) +#define __le32_to_cpus(x) __swab32s((x)) + +#define __be16_to_cpu(x) ((uint16_t)(x)) +#define __be32_to_cpu(x) ((uint32_t)(x)) + +#define __be16_to_cpus(x) { (void)(x); } +#define __be32_to_cpus(x) { (void)(x); } + +#endif /* __BIG_ENDIAN */ + + +#ifdef __LITTLE_ENDIAN + +#define __cpu_to_le16(x) ((uint16_t)(x)) +#define __cpu_to_le32(x) ((uint32_t)(x)) + +#define __cpu_to_le16s(x) { (void)(x); } +#define __cpu_to_le32s(x) { (void)(x); } + +#define __cpu_to_be16(x) ((uint16_t)__swab16((x))) +#define __cpu_to_be32(x) ((uint32_t)__swab32((x))) + +#define __cpu_to_be16s(x) __swab16s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) + + + +#define __le16_to_cpu(x) ((uint16_t)(x)) +#define __le32_to_cpu(x) ((uint32_t)(x)) + +#define __le32_to_cpus(x) { (void)(x); } +#define __le16_to_cpus(x) { (void)(x); } + +#define __be16_to_cpu(x) __swab16((uint16_t)(uint16_t)(x)) +#define __be32_to_cpu(x) __swab32((uint32_t)(uint32_t)(x)) + +#define __be16_to_cpus(x) __swab16s((x)) +#define __be32_to_cpus(x) __swab32s((x)) + +#endif /* __LITTLE_ENDIAN */ + + + +/** these are the conversion macros */ + +/** convert cpu order to little endian */ +#define cpu_to_le16 __cpu_to_le16 +#define cpu_to_le32 __cpu_to_le32 + +/** in-place convert cpu order to little endian */ +#define cpu_to_le16s __cpu_to_le16s +#define cpu_to_le32s __cpu_to_le32s + +/** convert cpu order to big endian */ +#define cpu_to_be16 __cpu_to_be16 +#define cpu_to_be32 __cpu_to_be32 + +/** in-place convert cpu order to big endian */ +#define cpu_to_be16s __cpu_to_be16s +#define cpu_to_be32s __cpu_to_be32s + + +/* same, but in reverse */ + +/** convert little endian to cpu order*/ +#define le16_to_cpu __le16_to_cpu +#define le32_to_cpu __le32_to_cpu + +/** in-place convert little endian to cpu order*/ +#define le16_to_cpus __le16_to_cpus +#define le32_to_cpus __le32_to_cpus + +/** convert big endian to cpu order*/ +#define be16_to_cpu __be16_to_cpu +#define be32_to_cpu __be32_to_cpu + +/** in-place convert big endian to cpu order*/ +#define be16_to_cpus __be16_to_cpus +#define be32_to_cpus __be32_to_cpus + + + +#endif /* BYTEORDER_H */ diff --git a/FwProfile/.tup/db b/FwProfile/.tup/db new file mode 100644 index 0000000000000000000000000000000000000000..a0621b5537cc0453c752dea45dfac9d6cdbc038a Binary files /dev/null and b/FwProfile/.tup/db differ diff --git a/FwProfile/.tup/object b/FwProfile/.tup/object new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/FwProfile/.tup/shared b/FwProfile/.tup/shared new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/FwProfile/.tup/tri b/FwProfile/.tup/tri new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/FwProfile/Makefile b/FwProfile/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d7ccca0e7097958a17077689f9ed5ddcf76e3674 --- /dev/null +++ b/FwProfile/Makefile @@ -0,0 +1,28 @@ +.PHONY: all +all: ifsw-dpu ifsw-pc + @echo "finished building all targets" + +ifsw-dpu: + @echo "+-------------------------------+" + @echo "| building fwprofile DPU target |" + @echo "+-------------------------------+" + make -f ./Makefile-dpu.mk ifsw + @echo "+----------------------------+" + @echo "| built fwprofile DPU target |" + @echo "+----------------------------+" + @echo + +ifsw-pc: + @echo "+------------------------------+" + @echo "| building fwprofile PC target |" + @echo "+------------------------------+" + make -f ./Makefile-pc.mk ifsw + @echo "+---------------------------+" + @echo "| built fwprofile PC target |" + @echo "+---------------------------+" + @echo + +.PHONY: clean +clean: + make -f ./Makefile-dpu.mk clean + make -f ./Makefile-pc.mk clean diff --git a/FwProfile/Makefile-dpu.mk b/FwProfile/Makefile-dpu.mk new file mode 100644 index 0000000000000000000000000000000000000000..26d1fcaa3d7f6787de4907e4f03cb3eaf40dbb57 --- /dev/null +++ b/FwProfile/Makefile-dpu.mk @@ -0,0 +1,35 @@ +CC = sparc-elf-gcc +#CFLAGS = -O2 -mv8 -W -Wall -Wextra -Werror -std=gnu89 -pedantic +CFLAGS = -mv8 -mhard-float -mfix-gr712rc -O2 -std=gnu89 -ggdb -W -Wall -Wextra -Werror -pedantic -Wshadow -Wuninitialized -fdiagnostics-show-option -Wcast-qual -Wformat=2 + +AR = sparc-elf-ar +ARFLAGS = crs + +FWROOT = $(shell pwd) +TARGET = dpu +SOURCEDIR = $(FWROOT)/src +BUILDDIR = $(FWROOT)/build/$(TARGET) + +SOURCES = $(shell ls $(SOURCEDIR)/*.c) +OBJECTS = $(patsubst %.c,$(BUILDDIR)/%.o,$(notdir $(SOURCES))) + +LIBS = "" +INCLUDE = "" + +ifsw: $(SOURCES) + @echo "building" $(TARGET) "target" + mkdir -p $(BUILDDIR) + # compile + cd $(BUILDDIR) && $(CC) $(CFLAGS) -c $(SOURCES) + # archive + cd $(BUILDDIR) && $(AR) $(ARFLAGS) $(BUILDDIR)/libfwprofile.a $(OBJECTS) + @echo "libfwprofile.a is ready" + +.PHONY: all +all: ifsw + @echo "finished building all targets" + +.PHONY: clean +clean: + rm -f $(BUILDDIR)/*.[ao] + diff --git a/FwProfile/Makefile-pc.mk b/FwProfile/Makefile-pc.mk new file mode 100644 index 0000000000000000000000000000000000000000..131b8f0c6107170a9f18312212c05b47d359d3b9 --- /dev/null +++ b/FwProfile/Makefile-pc.mk @@ -0,0 +1,35 @@ +CC = gcc +CFLAGS = -O0 -W -Wall -Wextra -Werror -std=gnu89 -m32 -pedantic -ggdb +DEFS = -DPC_TARGET + +AR = ar +ARFLAGS = crs + +FWROOT = $(shell pwd) +TARGET = pc +SOURCEDIR = $(FWROOT)/src +BUILDDIR = $(FWROOT)/build/$(TARGET) + +SOURCES = $(shell ls $(SOURCEDIR)/*.c) +OBJECTS = $(patsubst %.c,$(BUILDDIR)/%.o,$(notdir $(SOURCES))) + +LIBS = "" +INCLUDE = "" + +ifsw: $(SOURCES) + @echo "building" $(TARGET) "target" + mkdir -p $(BUILDDIR) + # compile + cd $(BUILDDIR) && $(CC) $(CFLAGS) $(DEFS) -c $(SOURCES) + # archive + cd $(BUILDDIR) && $(AR) $(ARFLAGS) $(BUILDDIR)/libfwprofile.a $(OBJECTS) + @echo "libfwprofile.a is ready" + +.PHONY: all +all: ifsw + @echo "finished building all targets" + +.PHONY: clean +clean: + rm -f $(BUILDDIR)/*.[ao] + diff --git a/FwProfile/src/FwPrConfig.c b/FwProfile/src/FwPrConfig.c new file mode 100644 index 0000000000000000000000000000000000000000..1af2f6b9c68861e42df028c5a8fec97fe54e4356 --- /dev/null +++ b/FwProfile/src/FwPrConfig.c @@ -0,0 +1,475 @@ +/** + * @file + * @ingroup prGroup + * Implements the configuration functions for the FW Procedure Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwPrConfig.h" +#include "FwPrPrivate.h" +#include <stdlib.h> + +/** + * Create a control flow (other than the control flow from the initial node) with the + * given characteristics and add it to state machine. + * The newly created control flow is stored in the control flow array at the first non-null location + * (in other words, the first control flow to be added to the state machine is stored at location 0, + * the second control flow is stored at location 1, etc). + * @param prDesc the descriptor of the state machine to which the control flow is added. + * @param srcId the identifier of the source of the control flow. + * @param srcType the type of the source. + * @param destId the identifier of the destination of the control flow. If the destination is an action + * node, this argument has a positive value equal to the destination identifier. If the destination + * is a decision node, this argument has a negative value equal to the opposite of the destination + * identifier. If the destination is the final node, this argument has the value zero. + * @param cfGuard the control flow guard (or NULL if no guard is associated to this control flow). + */ +static void AddFlow(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, NodeType_t srcType, FwPrCounterS1_t destId, + FwPrGuard_t cfGuard); + +/** + * Add an action to the set of actions in the procedure descriptor. + * This function scans the array of actions in the procedure descriptor and + * can then have one of three outcomes: + * - if the argument action is already present in the array of actions, the function + * returns the index of the location where the action is stored; + * - if the argument action is not present and the array of actions is not full, the + * function adds it at the first free location and returns the index of this + * location; + * - if the argument action is not present but the array of actions is already full, + * the function returns 0. + * . + * Note that the argument action is guaranteed to be different from NULL + * (because function <code>::FwPrAddAction</code> handles the case of action + * being equal to NULL and, in that case, it does not call <code>AddAction</code>. + * @param prDesc descriptor of the procedure where the action is added + * @param action action to be added + * @return the location where the action is stored in the array or -1 if the + * action cannot be added because the array is already full + */ +static FwPrCounterS1_t AddAction(FwPrDesc_t prDesc, FwPrAction_t action); + +/** + * Add a guard to the set of guards in the procedure descriptor. + * This function scans the array of guards in the procedure descriptor and + * can then have one of three outcomes: + * - if the argument guard is equal to NULL, the function returns 0; + * - if the argument guard is already present in the array of guards, the function + * returns the index of the location where the guard is stored; + * - if the argument guard is not present and the array of guards is not full, the + * function adds it at the first free location and returns the index of this + * location; + * - if the argument guard is not present but the array of guards is already full, the + * function returns 0. + * @param prDesc descriptor of the procedure where the guard is added + * @param guard guard to be added + * @return the location where the guard is stored in the array or -1 if the + * guard cannot be added because the array is already full + */ +static FwPrCounterS1_t AddGuard(FwPrDesc_t prDesc, FwPrGuard_t guard); + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrSetData(FwPrDesc_t prDesc, void* prData) { + prDesc->prData = prData; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void* FwPrGetData(FwPrDesc_t prDesc) { + return prDesc->prData; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddActionNode(FwPrDesc_t prDesc, FwPrCounterS1_t nodeId, FwPrAction_t action) { + + PrANode_t* aNode; + PrBaseDesc_t* prBase = prDesc->prBase; + + if (action == NULL) { + prDesc->errCode = prNullAction; + return; + } + + if (nodeId > prBase->nOfANodes) { + prDesc->errCode = prIllActNodeId; + return; + } + + if (nodeId < 1) { + prDesc->errCode = prIllActNodeId; + return; + } + + if (prBase->aNodes[nodeId - 1].iFlow != -1) { + prDesc->errCode = prActNodeIdInUse; + return; + } + + if (prDesc->flowCnt + 1 > prBase->nOfFlows) { + prDesc->errCode = prTooManyOutFlows; + return; + } + + /* Initialize newly added state */ + aNode = &(prBase->aNodes[nodeId - 1]); + + aNode->iFlow = prDesc->flowCnt; + prDesc->flowCnt = (FwPrCounterS1_t)(prDesc->flowCnt + 1); + + aNode->iAction = AddAction(prDesc, action); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddDecisionNode(FwPrDesc_t prDesc, FwPrCounterS1_t nodeId, FwPrCounterS1_t nOfOutFlows) { + PrDNode_t* dNode; + PrBaseDesc_t* prBase = prDesc->prBase; + + if (nodeId > prBase->nOfDNodes) { + prDesc->errCode = prIllDecNodeId; + return; + } + + if (nodeId < 1) { + prDesc->errCode = prIllDecNodeId; + return; + } + + if (prBase->dNodes[nodeId - 1].outFlowIndex != -1) { + prDesc->errCode = prDecNodeIdInUse; + return; + } + + if (nOfOutFlows < 2) { + prDesc->errCode = prIllNOfOutFlows; + return; + } + + if (prDesc->flowCnt + nOfOutFlows > prBase->nOfFlows) { + prDesc->errCode = prTooManyOutFlows; + return; + } + + /* Initialize newly added decision node */ + dNode = &(prBase->dNodes[nodeId - 1]); + + dNode->outFlowIndex = prDesc->flowCnt; + prDesc->flowCnt = (FwPrCounterS1_t)(prDesc->flowCnt + nOfOutFlows); + + dNode->nOfOutTrans = nOfOutFlows; + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowIniToAct(FwPrDesc_t prDesc, FwPrCounterS1_t destId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, 0, stoppedNode, destId, cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowIniToDec(FwPrDesc_t prDesc, FwPrCounterS1_t destId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, 0, stoppedNode, (FwPrCounterS1_t)(-destId), cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowActToAct(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, srcId, actionNode, destId, cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowActToDec(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, srcId, actionNode, (FwPrCounterS1_t)(-destId), cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowDecToAct(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, srcId, decisionNode, destId, cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowDecToDec(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, srcId, decisionNode, (FwPrCounterS1_t)(-destId), cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowActToFin(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, srcId, actionNode, 0, cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrAddFlowDecToFin(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrGuard_t cfGuard) { + AddFlow(prDesc, srcId, decisionNode, 0, cfGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static void AddFlow(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, NodeType_t srcType, FwPrCounterS1_t destId, + FwPrGuard_t cfGuard) { + + FwPrCounterS1_t i, baseLoc, nOfOutFlows; + FwPrCounterS1_t loc = -1; + PrFlow_t* flow; + PrBaseDesc_t* prBase = prDesc->prBase; + + /* check that the source state is legal and has been defined */ + if (srcType == actionNode) { + if (srcId > prBase->nOfANodes) { + prDesc->errCode = prIllFlowSrc; + return; + } + if (srcId < 1) { + prDesc->errCode = prIllFlowSrc; + return; + } + if (prBase->aNodes[srcId - 1].iFlow == -1) { + prDesc->errCode = prUndefinedFlowSrc; + return; + } + baseLoc = prBase->aNodes[srcId - 1].iFlow; + nOfOutFlows = 1; + } + else if (srcType == decisionNode) { + if (srcId > prBase->nOfDNodes) { + prDesc->errCode = prIllFlowSrc; + return; + } + if (srcId < 1) { + prDesc->errCode = prIllFlowSrc; + return; + } + if (prBase->dNodes[srcId - 1].outFlowIndex == -1) { + prDesc->errCode = prUndefinedFlowSrc; + return; + } + baseLoc = prBase->dNodes[srcId - 1].outFlowIndex; + nOfOutFlows = prBase->dNodes[srcId - 1].nOfOutTrans; + } + else { /* Source state is the stopped state */ + baseLoc = 0; + nOfOutFlows = 1; + } + + /* New control flow will be stored in the control flow array of the Procedure Descriptor at a location + * in the range [baseLoc, baseLoc+nOfOutFlows-1]. We check that this range of locations + * is not already full (note that the checks performed when a node is added to the procedure + * ensure that the location [baseLoc+nOfOutFlows-1] is within the range of flow array.. + */ + if (prBase->flows[baseLoc + nOfOutFlows - 1].iGuard != -1) { + prDesc->errCode = prTooManyFlows; + return; + } + + /* Identify location where newly added control flow will be stored in the control flow array. + * Note that the nOfOutFlows is guaranteed to be greater than zero by the way it is + * initialized in the previous statements in this function. Hence, the loop will be + * taken at least once. */ + for (i = 0; i < nOfOutFlows; i++) { + if (prBase->flows[baseLoc + i].iGuard == -1) { + loc = (FwPrCounterS1_t)(baseLoc + i); + break; + } + } + flow = &(prBase->flows[loc]); + + /* Assign control flow destination */ + flow->dest = destId; + + /* add guard to control flow descriptor */ + flow->iGuard = AddGuard(prDesc, cfGuard); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static FwPrCounterS1_t AddAction(FwPrDesc_t prDesc, FwPrAction_t action) { + FwPrCounterS1_t i; + + for (i = 0; i < prDesc->nOfActions; i++) { + if (prDesc->prActions[i] == NULL) { + break; + } + if (action == prDesc->prActions[i]) { + return i; + } + } + + if (i < prDesc->nOfActions) { + prDesc->prActions[i] = action; + return i; + } + + prDesc->errCode = prTooManyActions; + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static FwPrCounterS1_t AddGuard(FwPrDesc_t prDesc, FwPrGuard_t guard) { + FwPrCounterS1_t i; + + if (guard == NULL) { + return 0; + } + + for (i = 1; i < prDesc->nOfGuards; i++) { + if (prDesc->prGuards[i] == NULL) { + break; + } + if (guard == prDesc->prGuards[i]) { + return i; + } + } + + if (i < prDesc->nOfGuards) { + prDesc->prGuards[i] = guard; + return i; + } + + prDesc->errCode = prTooManyGuards; + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrErrCode_t FwPrCheck(FwPrDesc_t prDesc) { + + FwPrCounterS1_t i, j; + PrBaseDesc_t* prBase = prDesc->prBase; + FwPrBool_t found; + + /* Check that no error occurred during the configuration process */ + if (prDesc->errCode != prSuccess) { + return prConfigErr; + } + + /* Check that all action nodes have been defined */ + for (i = 0; i < prBase->nOfANodes; i++) { + if (prBase->aNodes[i].iFlow == -1) { + return prNullActNode; + } + } + + /* Check that all decision nodes have been defined */ + for (i = 0; i < prBase->nOfDNodes; i++) { + if (prBase->dNodes[i].outFlowIndex == -1) { + return prNullDecNode; + } + } + + /* Check that all control flows have been defined */ + for (i = 0; i < prBase->nOfFlows; i++) { + if (prBase->flows[i].iGuard == -1) { + return prNullFlow; + } + } + + /* Check that all control flow destinations are legal action nodes or decision nodes */ + for (i = 0; i < prBase->nOfFlows; i++) { + if (prBase->flows[i].dest > prBase->nOfANodes) { + return prIllegalADest; + } + if (prBase->flows[i].dest < -prBase->nOfDNodes) { + return prIllegalDDest; + } + } + + /* Check that all actions have been defined */ + for (i = 0; i < prDesc->nOfActions; i++) { + if (prDesc->prActions[i] == NULL) { + return prTooFewActions; + } + } + + /* Check that all guards have been defined */ + for (i = 0; i < prDesc->nOfGuards; i++) { + if (prDesc->prGuards[i] == NULL) { + return prTooFewGuards; + } + } + + /* Check that all action nodes are reachable */ + for (i = 1; i <= prBase->nOfANodes; i++) { + found = 0; + for (j = 0; j < prBase->nOfFlows; j++) { + if (prBase->flows[j].dest == i) { + found = 1; + break; + } + } + if (found == 0) { + return prUnreachableANode; + } + } + + /* Check that all decision nodes are reachable */ + for (i = 1; i <= prBase->nOfDNodes; i++) { + found = 0; + for (j = 0; j < prBase->nOfFlows; j++) { + if (prBase->flows[j].dest == -i) { + found = 1; + break; + } + } + if (found == 0) { + return prUnreachableDNode; + } + } + + return prSuccess; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrOverrideAction(FwPrDesc_t prDesc, FwPrAction_t oldAction, FwPrAction_t newAction) { + FwPrCounterS1_t i; + + if (prDesc->flowCnt != 0) { + prDesc->errCode = prNotDerivedPr; + return; + } + + for (i = 0; i < prDesc->nOfActions; i++) { + if (prDesc->prActions[i] == oldAction) { + prDesc->prActions[i] = newAction; + return; + } + } + + prDesc->errCode = prUndefAction; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrOverrideGuard(FwPrDesc_t prDesc, FwPrGuard_t oldGuard, FwPrGuard_t newGuard) { + FwPrCounterS1_t i; + + if (prDesc->flowCnt != 0) { + prDesc->errCode = prNotDerivedPr; + return; + } + + for (i = 1; i < prDesc->nOfGuards; i++) { + if (prDesc->prGuards[i] == oldGuard) { + prDesc->prGuards[i] = newGuard; + return; + } + } + + prDesc->errCode = prUndefGuard; +} diff --git a/FwProfile/src/FwPrConfig.h b/FwProfile/src/FwPrConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..90e9402456b95bca40b3e9de7b00ec7ce7b7942e --- /dev/null +++ b/FwProfile/src/FwPrConfig.h @@ -0,0 +1,459 @@ +/** + * @file + * @ingroup prGroup + * Declaration of the configuration interface for a FW Procedure. + * A FW Procedure is described by a procedure descriptor. + * The functions declared in this interface allow a procedure descriptor + * to be configured. + * During the configuration process, the action nodes, the decision nodes and + * the control flows of the procedure are defined. + * + * There are two types of procedures: newly created procedures + * (i.e. procedures which are created from scratch using <code>::FwPrCreate</code> + * or <code>#FW_PR_INST</code>) and derived procedures (i.e. procedures + * which are created by extending another procedure through calls + * to <code>::FwPrCreateDer</code> or <code>#FW_PR_INST_DER</code>). + * The functions declared in this header file can be used to configure both types + * of procedures. + * + * In the case of a newly created procedure, the mode of use of the + * functions in this header file is as follows: + * -# The action nodes of the procedure are added to its descriptor with + * the <code>::FwPrAddActionNode</code> function. + * -# The decision nodes of the procedure are added to its + * descriptor with the <code>::FwPrAddDecisionNode</code> function. + * -# The control flows of the procedures are added to the procedure + * with the <code>FwPrAddFlow*</code> functions (there are several of these + * functions, one for each type of control flow source and destination). + * -# The pointer to the procedure data in the procedure descriptor + * is set with the <code>::FwPrSetData</code> function. + * -# The consistency and completeness of the procedure configuration may + * optionally be verified with function <code>::FwPrCheck</code>. + * . + * The only constraint on the order in which the above functions are called is + * that a control flow from an action node or decision node can only be defined + * after the source action node or decision node has been defined. + * + * In the case of a derived procedure, the mode of use of the functions + * declared in this header file is as follows: + * -# An action can be overridden + * with the <code>::FwPrOverrideAction</code> function. + * -# A guard can be overridden with the <code>::FwPrOverrideGuard</code> function. + * -# The consistency and completeness of the configuration of the derived + * procedure may optionally be verified with function <code>::FwPrCheck</code>. + * . + * There are no constraints on the order in which the above functions are + * called. + * + * Error handling is done as follows: + * - Errors are reported through error codes. The range of error codes is + * defined in header file <code>FwPrConstant.h</code>. The error code is + * stored in the procedure descriptor (see <code>::FwPrGetErrCode</code>). + * - If an illegal input value could cause a corruption of the internal data + * structures of a procedure descriptor, a check is performed on the + * input parameter value and the function is aborted if this is found to be + * illegal. + * - When a function takes a procedure descriptor as an argument, no + * check is performed that the argument is non-NULL and valid (e.g. if + * a configuration function is called with a NULL value for the procedure + * descriptor argument, this error is not handled and the call + * will probably result in a segmentation fault). + * . + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWPR_CONFIG_H_ +#define FWPR_CONFIG_H_ + +#include "FwPrConstants.h" + +/** + * Set the pointer to the procedure data in the procedure descriptor. + * The procedure data are data which are manipulated by the procedure + * actions and guards. + * The procedure descriptor holds a pointer to the procedure data. + * This function allows this pointer to be defined. + * The exact type of the procedure data is defined by applications for each + * procedure. + * It is therefore unknown at the level of the procedure module. + * This function accordingly treats the pointer to the procedure data as a + * pointer to <code>void</code>. + * In most cases, the procedure data will take the form of a <code>struct</code> + * whose fields represent the inputs and outputs for the procedure actions + * and guards. + * + * The functions which implement the actions and guards access the procedure + * data as follows: + * - The functions implementing the actions and guards of a procedure + * take the procedure descriptor as an argument (because they must conform + * to the prototype defined by <code>::FwPrAction_t</code> and + * <code>::FwPrGuard_t</code>). + * - The functions implementing the actions and guards of a procedure + * use the <code>::FwPrGetData</code> function to retrieve the pointer to the + * procedure data. + * - The pointer returned by <code>::FwPrGetData</code> is defined as a pointer + * to <code>void</code> and will normally have to be cast to its true type. + * . + * @param prDesc the descriptor of the procedure to which the data structure is attached. + * @param prData the pointer to the procedure data. + * A value of NULL is legal (but note that the default value of the pointer to the + * procedure data when the procedure is created is NULL). + */ +void FwPrSetData(FwPrDesc_t prDesc, void* prData); + +/** + * Get the pointer to the procedure data in the procedure descriptor. + * This function returns the pointer which was set with the + * <code>::FwPrSetData</code> function. + * This function is normally used by the functions implementing a procedure + * action or guard to access the procedure data. + * See the description of the <code>::FwPrSetData</code> function for more details. + * @param prDesc the descriptor of the procedure to which the data structure is attached. + * @return the pointer to the procedure data or NULL if no procedure data + * were defined for the procedure. + */ +void* FwPrGetData(FwPrDesc_t prDesc); + +/** + * Create an action node with the given characteristics and add it to a procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllActNodeId: illegal value of the action node identifier + * - #prActNodeIdInUse: an action node with this identifier has already been defined + * - #prTooManyOutFlows: there is no space left in the procedure descriptor for the + * out-going control flow of this node + * - #prTooManyActions: there is no space left in the procedure descriptor for the + * action of this node + * - #prNullAction: the action associated to this node is a NULL pointer + * . + * @param prDesc the procedure to which the action node is added. + * @param nodeId the identifier of the action node to be added + * (an integer in the range [1,N] where N is the number of action nodes in the procedure). + * @param action the action for the new action node (a function pointer). + */ +void FwPrAddActionNode(FwPrDesc_t prDesc, FwPrCounterS1_t nodeId, FwPrAction_t action); + +/** + * Create a decision node with the given characteristics and add it to a procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllDecNodeId: illegal identifier for the decision node + * - #prDecNodeIdInUse: a decision node with this identifier has already been defined + * - #prIllNOfOutFlows: the number of out-going control flows is smaller than 2 + * - #prTooManyOutFlows: the decision node adds too many out-going control flows + * . + * @param prDesc the descriptor of the procedure to which the decision node is added. + * @param nodeId the identifier of the decision node to be added (an integer + * in the range [1,N] where N is the number of decision nodes). + * @param nOfOutFlows the number of outgoing control flows from the new action node (a positive + * integer greater than 1). + */ +void FwPrAddDecisionNode(FwPrDesc_t prDesc, FwPrCounterS1_t nodeId, FwPrCounterS1_t nOfOutFlows); + +/** + * Create a control flow from the initial node to an action node and add it + * to a procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param destId the identifier of the destination action node of the control flow (an integer in the + * range [1,N] where N is the number of action nodes). + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowIniToAct(FwPrDesc_t prDesc, FwPrCounterS1_t destId, FwPrGuard_t cfGuard); + +/** + * Create a control flow from the initial node to a decision node and add + * it to a procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param destId the identifier of the destination decision node of the control flow (an + * integer in the range [1,N] where N is the number of decision nodes). + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowIniToDec(FwPrDesc_t prDesc, FwPrCounterS1_t destId, FwPrGuard_t cfGuard); + +/** + * Create a control flow from an action node to another action node and add it + * to a procedure. + * This function should only be performed after the source action node of the control flow + * has been added to the procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllFlowSrc: the identifier of the source of this control flow has an illegal value + * - #prUndefinedFlowSrc: the source of this control flow has not yet been added to the procedure + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param srcId the identifier of the source action node of the control flow (an integer in the range + * [1,N] where N is the number of action nodes). + * @param destId the identifier of the destination action node of the control flow (an integer + * in the range [1,N] where N is the number of action nodes). + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowActToAct(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard); + +/** + * Create a control flow from an action node to a decision node and add it to a procedure. + * This function should only be performed after the source action node of the control flow + * has been added to the action node procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllFlowSrc: the identifier of the source of this control flow has an illegal value + * - #prUndefinedFlowSrc: the source of this control flow has not yet been added to the procedure + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param srcId the identifier of the source action node of the control flow (an integer in the range + * [1,N] where N is the number of action nodes) + * @param destId the identifier of the destination decision node of the control flow (an integer + * in the range [1,M] where M is the number of decision nodes) + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowActToDec(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard); + +/** + * Create a control flow from a decision node to an action node and add it to a procedure. + * This function should only be performed after the source of the control flow has been added + * to the action node procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllFlowSrc: the identifier of the source of this control flow has an illegal value + * - #prUndefinedFlowSrc: the source of this control flow has not yet been added to the procedure + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param srcId the identifier of the source decision node of the control flow (an integer + * in the range [1,N] where N is the number of decision nodes). + * @param destId the identifier of the destination action node of the control flow (an integer in the range + * [1,N] where N is the number of action nodes). + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowDecToAct(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard); + +/** + * Create a control flow from a decision node to another decision node and add it to a procedure. + * This function should only be performed after the source of the control flow has been added + * to the action node procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllFlowSrc: the identifier of the source of this control flow has an illegal value + * - #prUndefinedFlowSrc: the source of this control flow has not yet been added to the procedure + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param srcId the identifier of the source decision node of the control flow (an integer + * in the range [1,N] where N is the number of decision nodes). + * @param destId the identifier of the destination decision node of the control flow (an integer in the range + * [1,N] where N is the number of decision nodes). + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowDecToDec(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrCounterS1_t destId, FwPrGuard_t cfGuard); + +/** + * Create a control flow from an action node to the final node and add it to a procedure. + * This function should only be performed after the source action node of the control flow + * has been added to the action node procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllFlowSrc: the identifier of the source of this control flow has an illegal value + * - #prUndefinedFlowSrc: the source of this control flow has not yet been added to the procedure + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param srcId the identifier of the source action node of the control flow (an integer in the range + * [1,N] where N is the number of action nodes). + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowActToFin(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrGuard_t cfGuard); + +/** + * Create a control flow from a decision node to the final node and add it to a procedure. + * This function should only be performed after the source action node of the control flow + * has been added to the action node procedure. + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prIllFlowSrc: the identifier of the source of this control flow has an illegal value + * - #prUndefinedFlowSrc: the source of this control flow has not yet been added to the procedure + * - #prTooManyFlows: there is no space left in the control flow array of the procedure + * descriptor for this control flow + * - #prTooManyGuards: there is no space left in the guard array of the procedure + * descriptor for the guard defined by this control flow + * . + * @param prDesc the descriptor of the procedure to which the control flow is added. + * @param srcId the identifier of the source action node of the control flow (an integer in the range + * [1,N] where N is the number of action nodes). + * @param cfGuard the control flow guard (a function pointer) or NULL if no guard is attached to this + * control flow. + */ +void FwPrAddFlowDecToFin(FwPrDesc_t prDesc, FwPrCounterS1_t srcId, FwPrGuard_t cfGuard); + +/** + * Check the correctness and completeness of the configuration of a procedure descriptor. + * This function may be called on a procedure descriptor after it has been created and + * configured. + * This function does not modify the configuration of the procedure. + * It checks the error conditions which may arise when an application configures a + * procedure using the configuration functions declared in this header file. + * More specifically, this function performs the following checks: + * -# Check that no configuration errors have occurred (i.e. check that the error code + * in the procedure descriptor is equal to: <code>::prSuccess</code>). + * -# Check that all action nodes have been defined. + * -# Check that all decision nodes have been defined. + * -# Check that all control flows have been defined. + * -# Check that the destinations of the control flows out of a action node represent + * legal entities. + * -# Check that the destinations of the control flows out of a decision node represent + * legal entities. + * -# Check that the number of actions declared when the procedure was created is the same + * as the number of actions defined during the procedure configuration process. + * -# Check that the number of guards declared when the procedure was created is the same + * as the number of guards defined during the procedure configuration process. + * -# Check that all action nodes are reachable (i.e. they are a destination for a + * control flow). + * -# Check that all decision nodes are reachable (i.e. they are a destination for a + * control flow). + * . + * Note that there are configuration errors which are not covered by this function because + * they cannot occur if the procedure is configured using the functions declared in + * this header file. + * @param prDesc the descriptor of the procedure to be checked. + * @return the outcome of the check. The outcome of the check is one of the following: + * - #prSuccess: all checks have been passed. + * - #prConfigErr: check 1 has failed. + * - #prNullActNode: check 2 has failed. + * - #prNullDecNode: check 3 has failed. + * - #prNullFlow: check 4 has failed. + * - #prIllegalADest: check 5 has failed + * - #prIllegalDDest: check 6 has failed + * - #prTooFewActions: check 7 has failed + * - #prTooFewGuards: check 8 has failed + * - #prUnreachableANode: check 9 has failed + * - #prUnreachableDNode: check 10 has failed + * . + * This function returns when it encounters the first error. Hence, the function return value + * is determined by the first error encountered by the function. + */ +FwPrErrCode_t FwPrCheck(FwPrDesc_t prDesc); + +/** + * Override an action in a derived procedure. + * By default a derived procedure has the same actions as the base procedure + * from which it was derived. + * This function overrides one of the actions of the derived procedure. + * + * As an example consider the case of a base procedure B and suppose that action + * a1 is attached to node S1 and node S2. + * If an application creates a derived procedure D from B (for instance, through + * function <code>::FwPrCreateDer</code>), then, after creation, the action of + * action nodes S1 and S2 in procedure D is still a1. + * This function can be used to change a1. + * Note that a single invocation of this function will change the action of both + * S1 and S2. + * + * If an attempt is made to override a non-existent action, an error is declared + * and the function returns without doing anything. + * + * The override mechanism is only available for derived procedures. + * If this function is called on a procedure which was not derived by extending + * some other procedure, an error is declared. + * + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prUndefAction: the action to be overridden does not exist + * - #prNotDerivedPr: the procedure is not a derived procedure + * . + * @param prDesc the descriptor of the derived procedure. + * @param oldAction the action to be overridden + * @param newAction the new action which overrides the old action + */ +void FwPrOverrideAction(FwPrDesc_t prDesc, FwPrAction_t oldAction, FwPrAction_t newAction); + +/** + * Override a guard in a derived procedure. + * By default a derived procedure has the same guards as the base procedure + * from which it was derived. + * This function overrides one of the guards of the derived procedure. + * + * As an example consider the case of a base procedure B and suppose that + * the control flows F1 and F2 both have the same guard g1. + * If an application creates a derived procedure D from B (for instance, through + * function <code>::FwPrCreateDer</code>), then, after creation, the guard of the + * control flows F1 and F2 in D is still g1. + * This function can be used to change g1. + * Note that a single invocation of this function will change the guard on both + * control flows. + * + * If an attempt is made to override a non-existent guard, the function declares + * an error and returns. + * + * The override mechanism is only available for derived procedures. + * If this function is called on a procedure which was not derived by extending + * some other procedure, an error is declared. + * + * This function reports the following errors in the error code of the procedure + * descriptor: + * - #prUndefGuard: the guard to be overridden does not exist + * - #prNotDerivedPr: the procedure is not a derived procedure + * . + * @param prDesc the descriptor of the derived procedure. + * @param oldGuard the guard to be overridden + * @param newGuard the new guard which overrides the old guard + */ +void FwPrOverrideGuard(FwPrDesc_t prDesc, FwPrGuard_t oldGuard, FwPrGuard_t newGuard); + +#endif /* FWPR_CONFIG_H_ */ diff --git a/FwProfile/src/FwPrConstants.h b/FwProfile/src/FwPrConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..a426809cb8021e3db681acf0e988f0e36e9e15e1 --- /dev/null +++ b/FwProfile/src/FwPrConstants.h @@ -0,0 +1,227 @@ +/** + * @file + * @ingroup prGroup + * Header file to define all constants and types for the procedure + * module of the FW Profile. + * This header file should be included by all applications which use the + * procedure module of the FW Profile. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWPR_CONSTANTS_H_ +#define FWPR_CONSTANTS_H_ + +/** + * Forward declaration for the pointer to a procedure descriptor. + * A procedure descriptor is a data structure which holds all the information + * describing a procedure instance. + * Users only manipulate the pointer to the procedure descriptor. The internal + * definition of the procedure descriptor (see <code>FwPrPrivate.h</code>) is + * kept hidden from users. + */ +typedef struct FwPrDesc* FwPrDesc_t; + +/** + * Type for a pointer to a procedure action. + * A procedure action is a function which encapsulates an action of a + * procedure node. + * A procedure action takes the descriptor of the procedure as an argument. + * + * Pointers to procedure actions are used when a new procedure is defined: + * all the actions in the procedure must be defined as functions which conform + * to the <code>FwPrAction_t</code> prototype and are loaded into the procedure + * as function pointers. + */ +typedef void (*FwPrAction_t)(FwPrDesc_t); + +/** Type used for booleans (0 is "false" and 1 is "true"). */ +typedef int FwPrBool_t; + +/** + * Type for a pointer to a procedure guard. + * A procedure guard is a function which encapsulates a transition guard in a + * procedure. + * The procedure guard takes the descriptor of the procedure as an argument + * and it returns 0 to signify that the guard is false or a non-zero value + * (typically 1) to signify that the guard is true. + * + * Pointers to procedure guards are used when a new procedure is defined: + * all the guards in the procedure must be defined as functions which conform + * to the <code>FwPrGuard_t</code> prototype and are loaded into the procedure + * as function pointers. + */ +typedef FwPrBool_t (*FwPrGuard_t)(FwPrDesc_t); + +/** Type used for unsigned counters with a "short" range. */ +typedef unsigned char FwPrCounterU1_t; + +/** Type used for unsigned counters with a "medium" range. */ +typedef unsigned short int FwPrCounterU2_t; + +/** Type used for unsigned counters with a "long" range. */ +typedef unsigned int FwPrCounterU3_t; + +/** Type used for unsigned counters with a "long int" range. */ +typedef long unsigned int FwPrCounterU4_t; + +/** Type used for signed counters with a "short" range. */ +typedef signed char FwPrCounterS1_t; + +/** Error codes and function return codes for the procedure functions. */ +typedef enum { + /** + * Return codes of a function which has completed execution without errors. + */ + prSuccess = 1, + /** + * A call to <code>malloc</code> has failed (it has returned a NULL pointer). + */ + prOutOfMemory = 2, + /** + * The number of actions in the base procedure is not the same as in the derived + * procedure. + */ + prWrongNOfActions = 3, + /** + * The number of guards in the base procedure is not the same as in the derived + * procedure. + */ + prWrongNOfGuards = 4, + /** + * An action node is added to a procedure with an illegal (out-of-range) identifier. + */ + prIllActNodeId = 5, + /** + * An action node is added twice to the same procedure. + */ + prActNodeIdInUse = 6, + /** + * A decision node is added to a procedure with an illegal (out-of-range) identifier. + */ + prIllDecNodeId = 7, + /** + * A decision node is added twice to the same procedure. + */ + prDecNodeIdInUse = 8, + /** + * The number of actions added to the procedure exceeds the number of actions declared + * when the procedure descriptor was created. + */ + prTooManyActions = 9, + /** + * The number of guards added to the procedure exceeds the number of guards declared + * when the procedure descriptor was created. + */ + prTooManyGuards = 10, + /** + * An action node is defined with a null action. + */ + prNullAction = 11, + /** + * A node is added to a procedure which has more + * out-going transitions than fit into the control flow array of the procedure descriptor. + */ + prTooManyOutFlows = 12, + /** + * A choice pseudo-state is added to a procedure with less than 2 out-going control flows. + */ + prIllNOfOutFlows = 13, + /** + * A control flow from a certain source is added + * to a procedure but there isn't space for it in the control flow array of the + * procedure descriptor. + */ + prTooManyFlows = 14, + /** + * A control flow is added to a SM with a source which has an illegal value. + */ + prIllFlowSrc = 15, + /** + * A configuration error has been detected during the procedure configuration process. + */ + prConfigErr = 16, + /** + * There is an undefined action node in a procedure. + */ + prNullActNode = 17, + /** + * There is an undefined decision node in a procedure. + */ + prNullDecNode = 18, + /** + * There is an undefined control flow in a procedure. + */ + prNullFlow = 19, + /** + * A control flow is added to a procedure with a source (either a state or a source + * choice pseudo-state) which has not yet been defined. + */ + prUndefinedFlowSrc = 20, + /** + * A control flow is added to a procedure with an illegal (out-of-range) action node destination. + */ + prIllegalADest = 21, + /** + * A control flow is added to a procedure with an illegal (out-of-range) decision node destination. + */ + prIllegalDDest = 22, + /** + * The number of actions added to the procedure is smaller than the number of actions declared + * when the procedure descriptor was created. + */ + prTooFewActions = 23, + /** + * The number of guards added to the procedure is smaller than the number of guards declared + * when the procedure descriptor was created. + */ + prTooFewGuards = 24, + /** + * An error was encountered while executing a transition in a procedure (see + * <code>::FwPrExecute</code>). + */ + prFlowErr = 25, + /** + * The overridden action in a derived procedure does not exist. + */ + prUndefAction = 26, + /** + * The overridden guard in a derived procedure does not exist. + */ + prUndefGuard = 27, + /** + * The procedure where an action or a guard is overridden or a procedure is embedded + * is not a derived procedure. + */ + prNotDerivedPr = 28, + /** + * The procedure has an action node which is not a destination of any control flow + */ + prUnreachableANode = 29, + /** + * The procedure has a decision node which is not a destination of any control flow + */ + prUnreachableDNode = 30 +} FwPrErrCode_t; + +#endif /* FWPR_CONSTANTS_H_ */ diff --git a/FwProfile/src/FwPrCore.c b/FwProfile/src/FwPrCore.c new file mode 100644 index 0000000000000000000000000000000000000000..b164c37529cca6a4b4eba1744769516e48bb5b67 --- /dev/null +++ b/FwProfile/src/FwPrCore.c @@ -0,0 +1,154 @@ +/** + * @file + * @ingroup prGroup + * Implements Core Functions of the FW Procedure. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwPrCore.h" +#include "FwPrPrivate.h" +#include <stdlib.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrBool_t PrDummyGuard(FwPrDesc_t prDesc) { + (void)(prDesc); + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrStart(FwPrDesc_t prDesc) { + if (prDesc->curNode == 0) { + prDesc->curNode = -1; + prDesc->prExecCnt = 0; + prDesc->nodeExecCnt = 0; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrStop(FwPrDesc_t prDesc) { + prDesc->curNode = 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrExecute(FwPrDesc_t prDesc) { + PrANode_t* curNode; + PrDNode_t* decNode; + PrFlow_t* flow; + FwPrCounterS1_t i; + PrBaseDesc_t* prBase = prDesc->prBase; + FwPrCounterS1_t trueGuardFound; + + /* check if procedure is started */ + if (prDesc->curNode == 0) { /* procedure is stopped */ + return; + } + + prDesc->prExecCnt++; /* Increment procedure execution counter */ + prDesc->nodeExecCnt++; /* Increment node execution counter */ + + /* Get the Control Flow issuing from the current node */ + if (prDesc->curNode == -1) { /* procedure is at initial node */ + flow = &(prBase->flows[0]); + } + else { + curNode = &(prBase->aNodes[prDesc->curNode - 1]); /* procedure is at an action node */ + flow = &(prBase->flows[curNode->iFlow]); + } + + /* Evaluate guard of control flow issuing from current node */ + trueGuardFound = (FwPrCounterS1_t)prDesc->prGuards[flow->iGuard](prDesc); + + /* Execute loop as long as guard of control flow issuing from current node is true */ + while (trueGuardFound) { + /* Target of flow is a final node */ + if (flow->dest == 0) { + prDesc->curNode = 0; /* Stop procedure */ + return; + } + + if (flow->dest > 0) { /* Target of control flow is an action node */ + prDesc->curNode = flow->dest; + prDesc->nodeExecCnt = 0; + curNode = &(prBase->aNodes[(prDesc->curNode) - 1]); + prDesc->prActions[curNode->iAction](prDesc); + flow = &(prBase->flows[curNode->iFlow]); + trueGuardFound = (FwPrCounterS1_t)prDesc->prGuards[flow->iGuard](prDesc); + } + else { /* Target of flow is a decision node */ + trueGuardFound = 0; + decNode = &(prBase->dNodes[(-flow->dest) - 1]); + /* Evaluate guards of control flows issuing from decision node */ + for (i = 0; i < decNode->nOfOutTrans; i++) { + flow = &(prBase->flows[decNode->outFlowIndex + i]); + if (prDesc->prGuards[flow->iGuard](prDesc) != 0) { + trueGuardFound = 1; + break; /* First control flow out of dec. node with true guard */ + } + } + /* All control flows out of decision node have false guards */ + if (trueGuardFound == 0) { + prDesc->errCode = prFlowErr; + return; + } + } + } + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrRun(FwPrDesc_t prDesc) { + FwPrStart(prDesc); + FwPrExecute(prDesc); + FwPrStop(prDesc); + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrCounterS1_t FwPrGetCurNode(FwPrDesc_t prDesc) { + return prDesc->curNode; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrBool_t FwPrIsStarted(FwPrDesc_t prDesc) { + if (prDesc->curNode == 0) { + return 0; + } + + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrErrCode_t FwPrGetErrCode(FwPrDesc_t prDesc) { + return prDesc->errCode; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrCounterU3_t FwPrGetExecCnt(FwPrDesc_t prDesc) { + return prDesc->prExecCnt; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrCounterU3_t FwPrGetNodeExecCnt(FwPrDesc_t prDesc) { + return prDesc->nodeExecCnt; +} diff --git a/FwProfile/src/FwPrCore.h b/FwProfile/src/FwPrCore.h new file mode 100644 index 0000000000000000000000000000000000000000..c140054ad2ea4d2a9c17b26bf1adc4e26cb3da60 --- /dev/null +++ b/FwProfile/src/FwPrCore.h @@ -0,0 +1,163 @@ +/** + * @file + * @ingroup prGroup + * Declaration of the execution interface for a FW Procedure. + * The execution interface offers the functions to start and stop + * a procedure and to execute a procedure. + * The functions declared in this header file, take a procedure descriptor + * as their first argument. + * This represents the procedure upon which the functions operate. + * + * The functions declared in this header file can only be used after a + * procedure has been fully configured. + * This is normally done using the configuration functions declared + * in <code>FwPrConfig.h</code>. + * The basic mode of use of the functions declared in this file is as follows: + * -# The procedure is started with function <code>::FwPrStart</code>. + * -# The procedure is executed with function + * <code>::FwPrExecute</code>. + * -# The procedure is stopped with function <code>::FwPrStop</code>. + * . + * + * The functions declared in this header file assume that they are passed + * a valid procedure descriptor representing a correctly configured + * procedure. + * Failure to comply with this assumption will result in undefined + * behaviour. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWPR_CORE_H_ +#define FWPR_CORE_H_ + +#include "FwPrConstants.h" + +/** + * Start a procedure. The semantics of this operation is defined by the activity + * diagram of the following figure + * (this is figure 3.3-1 in the "FW Profile Definition Document"): + * @image html PR_StartStop.png + * @param prDesc the descriptor of the procedure to be started. + */ +void FwPrStart(FwPrDesc_t prDesc); + +/** + * Stop a procedure. The semantics of this operation is defined by the activity + * diagram of the following figure + * (this is figure 3.3-1 in the "FW Profile Definition Document"): + * @image html SM_StartStop.png + * @param prDesc the descriptor of the procedure to be started. + */ +void FwPrStop(FwPrDesc_t prDesc); + +/** + * Execute a procedure. The semantics of this function is defined + * by the following activity diagram (this is taken from figure 3.3-2 in the "FW Profile + * Definition Document"): + * @image html PR_Execution.png + * + * If the execution of the procedure passes through a decision node and there are two + * or more control flows out of that node which have guards which evaluate to true, + * the control flow to be taken is the one which was added first to the procedure. + * + * The FW Profile stipulates that at least one of the control flows out of a + * decision node must have a guard evaluating to true. This constraint is not enforced + * by this function. + * However, if the constraint is violated, the error code is set to + * <code>#prFlowErr</code>. + * The procedure, however, remains in a consistent state. + * @param prDesc the descriptor of the procedure where the transition is triggered. + */ +void FwPrExecute(FwPrDesc_t prDesc); + +/** + * Run a procedure. + * When a procedure is run, the procedure is first started, then it is executed + * once, and then it is stopped. + * @param prDesc the descriptor of the procedure where the transition is triggered. + */ +void FwPrRun(FwPrDesc_t prDesc); + +/** + * Return the identifier of the current action node in a procedure. + * The following convention is used: + * - If the procedure is in the STOPPED state, this function returns 0. + * - If the procedure is in the STARTED state but has not yet executed + * any action (either because the procedure has not yet been executed or because it + * has been executed but the guard from the initial node is false), + * this function returns -1. + * - If the procedure is in the STARTED state and has already left the + * initial node, the procedure returns the identifier of the current node + * (a positive integer). + * . + * @param prDesc the descriptor of the procedure. + * @return the identifier of the current action node of the procedure (or 0 + * if the procedure is at the initial node, or -1 if the procedure is in the + * STOPPED state). + */ +FwPrCounterS1_t FwPrGetCurNode(FwPrDesc_t prDesc); + +/** + * Check whether the procedure is started. + * @param prDesc the descriptor of the procedure. + * @return 1 if the procedure is STARTED or 0 if it is STOPPED. + */ +FwPrBool_t FwPrIsStarted(FwPrDesc_t prDesc); + +/** + * Return the error code of the argument procedure. + * The error code of a procedure holds either <code>#prSuccess</code> if the + * procedure never encountered an error or else it holds the code of the last error + * encountered by the procedure. + * If the error code is different from <code>#prSuccess</code>, the behaviour of + * the procedure is undefined. + * @param prDesc the descriptor of the procedure. + * @return either <code>#prSuccess</code> or the code of the last error encountered + * by the procedure. + */ +FwPrErrCode_t FwPrGetErrCode(FwPrDesc_t prDesc); + +/** + * Return the Procedure Execution Counter. + * The Procedure Execution Counter holds the number of execution cycles since + * the procedure was started. + * Note that the Procedure Execution Counter is not reset when the procedure + * is stopped (it is only reset when the procedure is started). + * @param prDesc the descriptor of the procedure. + * @return the value of the Procedure Execution Counter. + */ +FwPrCounterU3_t FwPrGetExecCnt(FwPrDesc_t prDesc); + +/** + * Return the Node Execution Counter. + * The Node Execution Counter holds the number of execution cycles since + * the current node was entered. + * Note that the Node Execution Counter is not reset when the procedure + * is stopped (it is only reset when the procedure is started). + * @param prDesc the descriptor of the procedure. + * @return the value of the Node Execution Counter. + */ +FwPrCounterU3_t FwPrGetNodeExecCnt(FwPrDesc_t prDesc); + +#endif /* FWPR_CORE_H_ */ diff --git a/FwProfile/src/FwPrDCreate.c b/FwProfile/src/FwPrDCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..bd718b4bf046741887a0dbbe6b1f32465a9c3edf --- /dev/null +++ b/FwProfile/src/FwPrDCreate.c @@ -0,0 +1,228 @@ +/** + * @file + * @ingroup prGroup + * Implements the dynamical creation functions for the FW Procedure Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwPrDCreate.h" +#include "FwPrPrivate.h" +#include <stdlib.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t FwPrCreate(FwPrCounterS1_t nOfANodes, FwPrCounterS1_t nOfDNodes, FwPrCounterS1_t nOfFlows, + FwPrCounterS1_t nOfActions, FwPrCounterS1_t nOfGuards) { + + FwPrCounterS1_t i; + PrBaseDesc_t* prBase; + FwPrDesc_t prDesc; + + if (nOfFlows < 2) { + return NULL; + } + + if (nOfANodes < 1) { + return NULL; + } + + if (nOfDNodes < 0) { + return NULL; + } + + if (nOfActions < 1) { + return NULL; + } + + if (nOfActions > nOfANodes) { + return NULL; + } + + if (nOfGuards < 0) { + return NULL; + } + + if (nOfGuards > nOfFlows) { + return NULL; + } + + prDesc = (FwPrDesc_t)malloc(sizeof(struct FwPrDesc)); + if (prDesc == NULL) { + return NULL; + } + + prBase = (PrBaseDesc_t*)malloc(sizeof(PrBaseDesc_t)); + if (prBase == NULL) { + return NULL; + } + + prBase->aNodes = (PrANode_t*)malloc(((FwPrCounterU4_t)(nOfANodes)) * sizeof(PrANode_t)); + if (prBase->aNodes == NULL) { + return NULL; + } + for (i = 0; i < nOfANodes; i++) { + prBase->aNodes[i].iFlow = -1; + } + + if (nOfDNodes > 0) { + prBase->dNodes = (PrDNode_t*)malloc(((FwPrCounterU4_t)(nOfDNodes)) * sizeof(PrDNode_t)); + if (prBase->dNodes == NULL) { + return NULL; + } + for (i = 0; i < nOfDNodes; i++) { + prBase->dNodes[i].outFlowIndex = -1; + } + } + else { + prBase->dNodes = NULL; + } + + prBase->flows = (PrFlow_t*)malloc(((FwPrCounterU4_t)(nOfFlows)) * sizeof(PrFlow_t)); + if (prBase->flows == NULL) { + return NULL; + } + for (i = 0; i < nOfFlows; i++) { + prBase->flows[i].iGuard = -1; + } + + prDesc->prActions = (FwPrAction_t*)malloc(((FwPrCounterU4_t)(nOfActions)) * sizeof(FwPrAction_t)); + if (prDesc->prActions == NULL) { + return NULL; + } + for (i = 0; i < nOfActions; i++) { + prDesc->prActions[i] = NULL; + } + + prDesc->prGuards = (FwPrGuard_t*)malloc(((FwPrCounterU4_t)(nOfGuards + 1)) * sizeof(FwPrGuard_t)); + if (prDesc->prGuards == NULL) { + return NULL; + } + + for (i = 1; i <= nOfGuards; i++) { + prDesc->prGuards[i] = NULL; + } + prDesc->prGuards[0] = &PrDummyGuard; + + prBase->nOfANodes = nOfANodes; + prBase->nOfDNodes = nOfDNodes; + prBase->nOfFlows = nOfFlows; + prDesc->prBase = prBase; + prDesc->curNode = 0; + prDesc->prData = NULL; + prDesc->flowCnt = 1; + prDesc->nOfActions = nOfActions; + prDesc->nOfGuards = (FwPrCounterS1_t)(nOfGuards + 1); + prDesc->errCode = prSuccess; + prDesc->nodeExecCnt = 0; + prDesc->prExecCnt = 0; + + return prDesc; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwPrDesc_t FwPrCreateDer(FwPrDesc_t prDesc) { + FwPrCounterS1_t i; + PrBaseDesc_t* prBase = prDesc->prBase; + FwPrDesc_t extPrDesc; + + /* Create descriptor for derived SM */ + extPrDesc = (FwPrDesc_t)malloc(sizeof(struct FwPrDesc)); + if (extPrDesc == NULL) { + return NULL; + } + + /* Create array of actions in the derived SM */ + extPrDesc->prActions = (FwPrAction_t*)malloc(((FwPrCounterU4_t)(prDesc->nOfActions)) * sizeof(FwPrAction_t)); + if (extPrDesc->prActions == NULL) { + return NULL; + } + for (i = 0; i < prDesc->nOfActions; i++) { + extPrDesc->prActions[i] = prDesc->prActions[i]; + } + + /* Create array of guards in the derived SM (NB: number of guards is guaranteed to be greater than 0 */ + extPrDesc->prGuards = (FwPrGuard_t*)malloc(((FwPrCounterU4_t)(prDesc->nOfGuards)) * sizeof(FwPrGuard_t)); + if (extPrDesc->prGuards == NULL) { + return NULL; + } + for (i = 0; i < prDesc->nOfGuards; i++) { + extPrDesc->prGuards[i] = prDesc->prGuards[i]; + } + + extPrDesc->prBase = prBase; + extPrDesc->curNode = 0; + extPrDesc->prData = NULL; + extPrDesc->flowCnt = 0; + extPrDesc->nOfActions = prDesc->nOfActions; + extPrDesc->nOfGuards = prDesc->nOfGuards; + extPrDesc->errCode = prDesc->errCode; + extPrDesc->nodeExecCnt = 0; + extPrDesc->prExecCnt = 0; + + return extPrDesc; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrRelease(FwPrDesc_t prDesc) { + PrBaseDesc_t* prBase; + + /* Release memory allocated to base descriptor (base descriptor is always allocated and + * hence it is not necessary to check whether it is non-NULL) */ + prBase = prDesc->prBase; + + /* Release memory allocated to action node array (this is guaranteed to have at least one entry + * since procedure are constrained to have at least one action node) */ + free(prBase->aNodes); + + /* Release memory allocated to decision node array (this may be empty) */ + if (prBase->dNodes != NULL) { + free(prBase->dNodes); + } + + /* Release pointer to transition array (note that the transition array is guaranteed to exist and to + * have at least one element, see operation FwPrCreate) */ + free(prBase->flows); + + /* Release memory allocated to base descriptor */ + free(prDesc->prBase); + + /* Release memory allocated to extension part of the state machine descriptor */ + FwPrReleaseDer(prDesc); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrReleaseDer(FwPrDesc_t prDesc) { + + /* Release pointer to the action and guard arrays (note that both arrays are guaranteed to + * have non-zero length) */ + free(prDesc->prActions); + free(prDesc->prGuards); + + /* Release pointer to state machine descriptor */ + free(prDesc); + prDesc = NULL; + + return; +} diff --git a/FwProfile/src/FwPrDCreate.h b/FwProfile/src/FwPrDCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..c4ab2475762def6b3242c4a65d8bed82aaae49c7 --- /dev/null +++ b/FwProfile/src/FwPrDCreate.h @@ -0,0 +1,196 @@ +/** + * @file + * @ingroup prGroup + * Declaration of the dynamical creation interface for a FW Procedure. + * A FW Procedure is described by a procedure descriptor. + * This interface declares the functions required to create and release + * a procedure descriptor dynamically. + * Dynamic creation and release of memory is done through calls to + * <code>malloc</code> and <code>free</code>. + * + * A procedure can be created in two ways: + * - It can be created from scratch, or + * - It can be created by extending an existing procedure. + * . + * The functions offered by this interface cover both creation of a new + * procedure descriptor from scratch (<code>::FwPrCreate</code>) and + * the extension of an existing procedure descriptor to create the + * descriptor for a derived procedure (<code>::FwPrCreateDer</code>). + * + * Both the creation and the extension functions create a new procedure + * descriptor and return a pointer to the newly created descriptor instance. + * The procedure descriptor returned by these functions is initialized + * (i.e. all its attributes have a well-defined value) but will normally + * need to be configured. + * Configuration can be done using the functions offered by + * <code>FwPrConfig.h</code>. + * + * The creation and the extension functions in this header file always check the + * success of calls to <code>malloc</code>. + * In case of failure, the caller aborts and returns a NULL pointer. + * + * Applications which do not wish to use dynamic memory allocation can + * create a procedure descriptor statically using the services offered + * by <code>FwPrSCreate.h</code>. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWPR_DCREATE_H_ +#define FWPR_DCREATE_H_ + +#include "FwPrConstants.h" + +/** + * Create a new procedure descriptor. + * This function creates the procedure descriptor and its internal data structures + * dynamically through calls to <code>malloc</code>. + * If any of these calls fails, the function aborts and returns NULL. + * In this case, there may be a memory leak if part of the procedure descriptor memory + * had been allocated before the function was aborted. + * + * It is legal to create a procedure descriptor with no decision + * nodes but it is not legal to create a procedure descriptor with no + * control flows or with no action nodes. + * @param nOfANodes the number of action nodes in the new procedure (a positive integer). + * @param nOfDNodes the number of decision nodes in the new procedure + * (a non-negative integer). + * @param nOfFlows the number of control flows in the new procedure (an + * integer greater than 1). + * @param nOfActions the total number of actions which the + * user wishes to define for the procedure. + * The total number of actions must be a positive integer not greater than the number + * of action nodes. + * If the same action appears more than once in a procedure, it is counted only once. + * @param nOfGuards the total number of control flow guards which the + * user wishes to define for the procedure. + * The total number of guards must be a non-negative integer not greater than the number + * control flows. + * If the same guard appears more than once in a procedure, it is counted only once. + * @return the descriptor of the new procedure (or NULL if creation of the + * data structures to hold the procedure descriptor failed or one of the + * function parameters had an illegal value). + */ +FwPrDesc_t FwPrCreate(FwPrCounterS1_t nOfANodes, FwPrCounterS1_t nOfDNodes, FwPrCounterS1_t nOfFlows, + FwPrCounterS1_t nOfActions, FwPrCounterS1_t nOfGuards); + +/** + * Create the descriptor of a derived procedure. + * A derived procedure is a procedure which is created by extending + * another procedure. + * The procedure which is thus extended is called base procedure. + * + * This function takes a procedure as an argument and creates a derived + * procedure from it. + * The function returns the descriptor of the newly created derived procedure. + * + * The base procedure should be fully and correctly configured (i.e. it should + * pass the configuration check implemented by <code>::FwPrCheck</code>). + * Compliance with this constraint is not checked by this function. + * If the constraint is not satisfied, the behaviour of the derived procedure + * is undefined. + * + * After being created, the derived procedure has the following characteristics: + * - It has the same number of action and decision nodes as the base procedure. + * - Its action and decision nodes are connected by the same control flows as + * the base procedure. + * - Its action nodes have the same actions as the homologous nodes of the base node + * machine. + * - Its control flows have the same guards as the homologous control flows of + * the base procedure. + * . + * Thus, the derived procedure is a structural clone of its base procedure. + * + * The attributes of the derived procedure are initialized as follows: + * - The error code is the same as the error code of the base procedure. + * - No procedure data are associated to the derived procedure. + * - The execution counters are equal to zero + * - The procedure state is STOPPED. + * - The <code>flowCnt</code> field in the procedure descriptor is initialized + * to zero. + * . + * After being created, the derived procedure is fully configured because it + * inherits the configuration of its base procedure. + * The configuration of a derived procedure can be modified by: + * - loading its procedure data, and + * - overriding some or all of its actions and guards. + * . + * The functions to perform these reconfiguration operations are defined in + * <code>FwPrConfig.h</code>. + * + * A procedure descriptor consists of two parts: the base descriptor and + * the extension descriptor (see <code>FwPrPrivate.h</code>). + * A derived procedure and its base procedure share the same base descriptor + * (which defines the topology of the procedure) but have different extension + * descriptors. + * The extension descriptor is linked to the base descriptor through a pointer. + * This function accordingly creates a new extension descriptor and links it to the + * base descriptor of the base procedure. + * @param prDesc the descriptor of the base procedure. The base procedure + * should be a fully and correctly configured procedure (i.e. it should pass + * the <code>::FwPrCheck</code> configuration check). + * @return the descriptor of the derived procedure (or NULL if creation of the + * data structures to hold the extended procedure descriptor failed). + */ +FwPrDesc_t FwPrCreateDer(FwPrDesc_t prDesc); + +/** + * Release the memory which was allocated when the procedure descriptor was created. + * After this operation is called, the procedure descriptor can no longer be used. + * + * This function releases the memory of both the base and the extension parts of the + * procedure descriptor. + * Hence, if the argument procedure descriptor acted as base for other procedure + * descriptors, the derived procedure descriptors are no longer usable + * after the function has been called. + * + * Use of this function is subject to the following constraints: + * - It should only be called on a procedure descriptor which was created using + * function <code>FwPrCreate</code>. + * - It should only be called once on the same procedure descriptor. + * - It should only be called on a procedure descriptor which is correctly configured. + * . + * Violation of any of the above constraints may result in memory corruption. + * @param prDesc the descriptor of the procedure. + */ +void FwPrRelease(FwPrDesc_t prDesc); + +/** + * Release the memory allocated to a derived procedure descriptor. + * After this operation is called, the argument procedure descriptor can no longer + * be used. + * The procedure descriptor of the base procedure is unaffected by this + * function. + * + * Use of this function is subject to the following constraints: + * - It should only be called on a procedure descriptor which was created using + * function <code>FwPrCreateDer</code>. + * - It should only be called once on the same procedure descriptor. + * - It should only be called on a procedure descriptor which is correctly configured. + * . + * Violation of any of the above constraints may result in memory corruption. + * @param prDesc the descriptor of the procedure. + */ +void FwPrReleaseDer(FwPrDesc_t prDesc); + +#endif /* FWSM_DCREATE_H_ */ diff --git a/FwProfile/src/FwPrPrivate.h b/FwProfile/src/FwPrPrivate.h new file mode 100644 index 0000000000000000000000000000000000000000..6e872c01a441cc23fb7988db042e8d488490ac86 --- /dev/null +++ b/FwProfile/src/FwPrPrivate.h @@ -0,0 +1,290 @@ +/** + * @file + * @ingroup prGroup + * Declaration of the internal data structures of the FW Procedure + * Module. + * Users should not normally be concerned with these data structures. + * + * The data structures declared in this header file are used to define the + * procedure descriptor. + * A procedure descriptor holds all the information related to a certain procedure. + * A procedure descriptor consists of two parts: the base descriptor and + * the extension descriptor. + * + * The base descriptor holds the information which is not changed when the + * procedure is extended. + * This consists of: + * - The list of action nodes in the procedure + * - The list of decision nodes in the procedure + * - The list of control flows in the procedure + * . + * + * The extension descriptor holds the information which may be overridden when the + * procedure is extended. + * This consists of: + * - The list of actions used in the procedure + * - The list of guards used in the procedure + * - The pointer to the procedure data (the data upon which the + * procedure actions operate) + * - The current node of the procedure + * - The execution counters of the procedure + * - The error code for the procedure + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWPR_PRIVATE_H_ +#define FWPR_PRIVATE_H_ + +#include "FwPrConstants.h" + +/** + * Enumerated type for the type of a node in a procedure. + */ +typedef enum { + /** + * An action state in a procedure. + */ + actionNode = 1, + /** + * A decision node in a procedure. + */ + decisionNode = 2, + /** + * Either the initial or the final node. + */ + stoppedNode = 3 +} NodeType_t; + +/** + * Dummy guard which always returns true. + * This guard is used where no control flow guard is specified. + * @param prDesc procedure descriptor. This parameter is unused in this dummy guard. + * The parameter is retained for compatibility with the <code>::FwPrGuard_t</code> type. + * @return always return 1 (to signify that the guard is true). + */ +FwPrBool_t PrDummyGuard(FwPrDesc_t prDesc); + +/** + * Structure representing an action node in a procedure. + * An action node is characterized by: + * - the out-going control flow + * - the action associated to the node + * . + * The out-going control flow is identified by an integer pointing at the location + * in the control flow array in the base descriptor (see <code>::PrBaseDesc_t</code>). + * Thus, for instance, if the <code>iFlow</code> field for node N is equal to 5, + * then the out-going control flow of node N is the one stored at location 5 of the + * control flow array of that procedure. + * + * The node action is identified by an integer pointing at the location in the + * action array of the procedure descriptor where the action is stored. + * Thus, for instance, if the <code>iAction</code> field for node N is equal to 5, + * then the action of node N is the one stored at location 5 of the + * action array of that procedure. + * + * By convention, the implementation treats an action node as uninitialized if its + * <code>iFlow</code> field is equal to -1. + */ +typedef struct { + /** index of out-going control flows */ + FwPrCounterS1_t iFlow; + /** index of the action attached to the node */ + FwPrCounterS1_t iAction; +} PrANode_t; + +/** + * Structure representing a decision node in a procedure. + * A decision node is characterized by the set of its out-going control flows. + * The set of out-going control flows is defined as follows. + * Control flows which originate from the same decision node are located in adjacent + * locations in the control flow array of the base descriptor (see + * <code>::PrBaseDesc_t</code>). + * Field <code>outFlowIndex</code> identifies the first location of this set of adjacent + * locations. + * Thus, for instance, if a decision node has 3 out-going control flows and if its + * <code>outFlowIndex</code> field has value 4, then the three out-going control flows + * are located in elements 4, 5 and 6 of the array of control flows. + * + * By convention, the implementation treats a decision node as uninitialized if its + * <code>outFlowIndex</code> field is equal to -1. + */ +typedef struct { + /** index of first out-going control flow in control flow array */ + FwPrCounterS1_t outFlowIndex; + /** number of outgoing control flows from the decision node */ + FwPrCounterS1_t nOfOutTrans; +} PrDNode_t; + +/** + * Structure representing a control flow. + * A control flow is characterized by: + * - the destination of the control flow + * - the guard associated to the control flow + * . + * The destination of the control flow may be either an action node, or the final node, + * or a decision node. The type of the control flow destination is identified as follows: + * - a value of zero means that the destination is the final node + * - a positive value means that the destination is an action node and the value of + * <code>dest</code> is the identifier of the destination node + * - a negative value means that the destination is a decision node and the value of + * <code>-dest</code> is the identifier of the decision + * . + * The guard is an integer which identifies the location in the + * guard array of the procedure descriptor (see <code>FwPrDesc</code>) + * where the guard is stored as a function pointer. + * Control flows which do not have a guard associated to them, set <code>iGuard</code> + * equal to zero (the zero-th location in the guard array holds the "dummy + * guard" <code>::PrDummyGuard</code> which always returns 1). + * + * By convention, the implementation treats a control flow as uninitialized if its + * <code>iGuard</code> field is equal to -1. + */ +typedef struct { + /** the index of the destination of the control flow */ + FwPrCounterS1_t dest; + /** the index of the guard associated to the control flow */ + FwPrCounterS1_t iGuard; +} PrFlow_t; + +/** + * Structure representing the base descriptor of a procedure. + * The base descriptor holds the information which is not changed when the procedure + * is extended. + * This consists of: + * - The list of action nodes in the procedure (array <code>aNodes</code>) + * - The list of decision nodes in the procedure (array <code>dNodes</code>) + * - The list of control flows in the procedure (array <code>flows</code>) + * . + * Array <code>aNodes</code> holds the action nodes in the procedure. + * The action nodes are identified by an integer in the range [1,N] (N is the total + * number of nodes). + * The i-th action node is stored in the (i-1)-th location of <code>aNodes</code>. + * The number of action nodes is stored in field <code>nOfANodes</code>. + * + * Array <code>dNodes</code> holds the decision nodes in the procedure. + * The decision nodes are identified by an integer in the range [1,M] (M is the total + * number of decision nodes). + * The i-th decision node is stored in the (i-1)-th location of <code>dNodes</code>. + * The number of decision nodes is stored in field <code>nOfDNodes</code>. + * + * Array <code>flows</code> holds the control flows in the procedure. + * The control flows are stored in groups of adjacent locations where each group + * holds the control flows out of the same node (see also + * <code>::PrANode_t</code> and <code>::PrDNode_t</code>). + * The number of control flows is stored in field <code>nOfFlows</code>. + */ +typedef struct { + /** array holding the action nodes in the procedure */ + PrANode_t* aNodes; + /** array holding the decision nodes in the procedure */ + PrDNode_t* dNodes; + /** array holding the control flows in the procedure */ + PrFlow_t* flows; + /** the number of action nodes in the procedure */ + FwPrCounterS1_t nOfANodes; + /** the number of decision nodes in the procedure */ + FwPrCounterS1_t nOfDNodes; + /** the number of control flows in the procedure (excluding control flow from initial node) */ + FwPrCounterS1_t nOfFlows; +} PrBaseDesc_t; + +/** + * Structure representing a procedure descriptor. + * Field <code>prBase</code> points to the base descriptor for the procedure + * which holds the information about the action nodes, decision nodes and the + * control flows connecting them. + * + * Array <code>prActions</code> holds the list of all actions in the procedure. + * Each distinct action only appears once in the action array. + * If the same action is used several times in a procedure, only one instance is + * registered in the action array. + * + * Array <code>prGuards</code> holds the list of all control flow guards in the + * procedure. + * If the same guard is used several times in a procedure, only one instance is + * registered in the guard array. + * The first location in the guard array (location 0) holds the "dummy guard" + * <code>::PrDummyGuard</code> which always returns 1. + * + * When a new action node is added to the procedure, field + * <code>flowCnt</code> holds the position in the control flow array where its + * out-going control flow will be stored. + * + * The identifier of the current node is stored in <code>curNode</code>. + * The following convention is used: + * - A value of 0 indicates that the procedure is in the STOPPED state; + * - A value of -1 indicates that the procedure is in the STARTED state but the + * guard on the flow out of the initial node was false and hence the + * procedure is waiting in the initial node; + * - A value of i (a positive integer) indicates that the procedure is in the + * STARTED state and i is the identifier of its current node. + * . + * + * If during the creation, configuration or execution of the procedure, an error is + * encountered, the corresponding error code is stored in field <code>errCode</code>. + * This field is initialized to <code>#prSuccess</code> and should nominally remain + * unchanged throughout the life of the procedure. + * If the error code has a value other than <code>#prSuccess</code>, the behaviour of + * the procedure is undefined. + * + * There are two types of procedures: base procedures (i.e. + * procedures which are created from scratch using <code>::FwPrCreate</code> or + * <code>#FW_SM_INST</code>) and derived procedures (i.e. procedures + * which are created by extending a base procedure through calls + * to <code>::FwPrCreateDer</code> or <code>#FW_PR_INST_DER</code>). + * By convention, a derived procedure is characterized by field + * <code>flowCnt</code> being equal to zero. + * + * Two counters are associated to a procedure: the Procedure Execution Counter + * and the Node Execution Counter. + * The Procedure Execution Counter holds the number of execution cycles since + * the procedure was started and the Node Execution Counter holds the number of cycle + * since the current node was entered. + */ +struct FwPrDesc { + /** pointer to the base descriptor */ + PrBaseDesc_t* prBase; + /** the procedure actions */ + FwPrAction_t* prActions; + /** the control flow guards in the procedure */ + FwPrGuard_t* prGuards; + /** the number of actions in the procedure */ + FwPrCounterS1_t nOfActions; + /** the number of guards in the procedure */ + FwPrCounterS1_t nOfGuards; + /** the counter for the number of control flows added to the procedure */ + FwPrCounterS1_t flowCnt; + /** the current node of the procedure */ + FwPrCounterS1_t curNode; + /** either 'success' or the code of the last error encountered by the procedure */ + FwPrErrCode_t errCode; + /** the procedure execution counter */ + FwPrCounterU3_t prExecCnt; + /** the node execution counter */ + FwPrCounterU3_t nodeExecCnt; + /** the pointer to the data manipulated by the procedure actions and guards */ + void* prData; +}; + +#endif /* FWPR_PRIVATE_H_ */ diff --git a/FwProfile/src/FwPrSCreate.c b/FwProfile/src/FwPrSCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..c5dc822e9a55a1752db78fda75817ac6c6c786fb --- /dev/null +++ b/FwProfile/src/FwPrSCreate.c @@ -0,0 +1,102 @@ +/** + * @file + * @ingroup prGroup + * Implements the static initialization functions for the FW + * Procedure Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwPrPrivate.h" +#include <stdlib.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrInit(FwPrDesc_t prDesc) { + + FwPrCounterS1_t i; + PrBaseDesc_t* prBase = prDesc->prBase; + + for (i = 0; i < prBase->nOfANodes; i++) { + prBase->aNodes[i].iFlow = -1; + } + + for (i = 0; i < prBase->nOfDNodes; i++) { + prBase->dNodes[i].outFlowIndex = -1; + } + + for (i = 0; i < prBase->nOfFlows; i++) { + prBase->flows[i].iGuard = -1; + } + + for (i = 0; i < prDesc->nOfActions; i++) { + prDesc->prActions[i] = NULL; + } + + prDesc->prGuards[0] = &PrDummyGuard; + for (i = 1; i < prDesc->nOfGuards; i++) { + prDesc->prGuards[i] = NULL; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwPrInitDer(FwPrDesc_t prDesc, FwPrDesc_t prDescBase) { + FwPrCounterS1_t i; + PrBaseDesc_t* prBase = prDescBase->prBase; + + if (prDesc->nOfActions != prDescBase->nOfActions) { + prDesc->errCode = prWrongNOfActions; + return; + } + + if (prDesc->nOfGuards != prDescBase->nOfGuards) { + prDesc->errCode = prWrongNOfGuards; + return; + } + + prDesc->prBase = prBase; + + /* This cycle will always be executed at least once because + * the number of actions (nOfActions) is always greater than + * zero (since all procedures have at least one action node) + */ + for (i = 0; i < prDesc->nOfActions; i++) { + prDesc->prActions[i] = prDescBase->prActions[i]; + } + + /* This cycle will always be executed at least once because + * the number of guards (nOfGuards) is always greater than + * zero (since all procedures have at least the dummy guard) + */ + for (i = 0; i < prDesc->nOfGuards; i++) { + prDesc->prGuards[i] = prDescBase->prGuards[i]; + } + + prDesc->errCode = prDescBase->errCode; + + prDesc->flowCnt = 0; + prDesc->curNode = 0; + prDesc->nodeExecCnt = 0; + prDesc->prExecCnt = 0; + + return; +} diff --git a/FwProfile/src/FwPrSCreate.h b/FwProfile/src/FwPrSCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..683210c137b3d08da34a4b2f2c33caaa3dce10b1 --- /dev/null +++ b/FwProfile/src/FwPrSCreate.h @@ -0,0 +1,278 @@ +/** + * @file + * @ingroup prGroup + * Declaration of the static creation interface for a FW Procedure. + * A FW Procedure is described by a procedure descriptor. + * This interface allows a procedure descriptor to be created + * statically (i.e. without using dynamic memory allocation). + * In this sense, this interface is alternative to the dynamic creation + * interface defined in <code>FwPrDCreate.h</code>. + * + * A procedure can be created in two ways: + * - It can be created from scratch, or + * - It can be created by extending an existing procedure. + * . + * In both cases, creation of a procedure descriptor is done in two + * steps: + * - The procedure descriptor and its internal data structures are + * instantiated. + * - The procedure descriptor and its internal data structures are + * initialized. + * . + * Instantiation is done by means of the following macros. + * - <code>#FW_PR_INST</code> should be used to instantiate from scratch + * a descriptor for a procedure with one or more choice + * pseudo-states. + * - <code>#FW_PR_INST_NODEC</code> should be used to instantiate from + * scratch a descriptor for a procedure with no choice pseudo-states. + * - <code>#FW_PR_INST_DER</code> should be used to instantiate a + * descriptor for a procedure which is derived by extending another + * procedure. + * . + * Initialization is done by means of the following functions: + * - <code>::FwPrInit</code> should be used to initialize a descriptor + * which has been created from scratch with either + * <code>#FW_PR_INST</code> or <code>#FW_PR_INST_NODEC</code>. + * - <code>::FwPrInitDer</code> should be used to initialize a descriptor + * of a procedure which is derived by extending another procedure + * . + * After a procedure descriptor has been instantiated and + * initialized, it will normally need to be configured. + * Configuration of a procedure descriptor can be done using the + * functions described in the <code>FwPrConfig.h</code> file. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWPR_SCREATE_H_ +#define FWPR_SCREATE_H_ + +#include "FwPrPrivate.h" + +/** + * Instantiate a procedure descriptor and its internal data structure. + * This macro compiles correctly only if the number of action nodes N, the number + * of decision NDEC and the number of control flows NFLOWS is positive. + * If there is a need to define a procedure with zero decision nodes, + * the <code>::FW_PR_INST_NODEC</code> macro should be used. + * + * The macro generates code that does the following: + * - It defines an array of N elements of type <code>PrANode_t</code> to + * represent the array holding the procedure action nodes. + * - It defines an array of NDEC elements of type <code>PrDNodes_t</code> to + * represent the array holding the procedure decision nodes. + * - It defines an array of NFLOWS elements of type <code>PrFlow_t</code> to + * represent the array holding the procedure control flows. + * - It defines an array of NA elements of type <code>PrAction_t</code> to + * represent the array holding the procedure actions. + * - It defines an array of (NG+1) elements of type <code>PrGuard_t</code> to + * represent the array holding the procedure guards (the extra guard is + * the "dummy guard" <code>::PrDummyGuard"</code> to be attached to control flows + * which have no guard). + * - It defines and initializes a variable of type <code>FwPrDescBase_t</code> + * to represent the base part of the procedure descriptor. + * - It defines and initializes a variable with the name PR_DESC of type + * <code>struct FwPrDesc</code> to represent the procedure descriptor. + * . + * All variables defined by this macro are <code>static</code>. + * + * The procedure descriptor instantiated by the macro is only partially + * initialized. + * Full initialization is performed using function <code>::FwPrInit</code>. + * + * Since the macro includes the declaration of several variables, it should be located + * in the section of a c-file where variable declaration is legal. + * @param PR_DESC the variable holding the procedure descriptor + * @param N a positive integer representing the number of action nodes + * @param NDEC a positive integer the number of decision nodes + * @param NFLOWS a positive integer representing the number of control flows + * @param NA a positive integer representing the number of actions + * @param NG a non-negative integer representing the number of guards (i.e. the + * number of transition actions which are defined on the procedure) + */ +#define FW_PR_INST(PR_DESC, N, NDEC, NFLOWS, NA, NG) \ + static PrANode_t PR_DESC##_aNodes[(N)]; \ + static PrDNode_t PR_DESC##_dNodes[(NDEC)]; \ + static PrFlow_t PR_DESC##_flows[(NFLOWS)]; \ + static FwPrAction_t PR_DESC##_actions[(NA)]; \ + static FwPrGuard_t PR_DESC##_guards[(NG) + 1]; \ + static PrBaseDesc_t PR_DESC##_base = {(PR_DESC##_aNodes), (PR_DESC##_dNodes), (PR_DESC##_flows), N, NDEC, NFLOWS}; \ + static struct FwPrDesc(PR_DESC) = { \ + &(PR_DESC##_base), (PR_DESC##_actions), (PR_DESC##_guards), NA, (NG) + 1, 1, 0, prSuccess, 0, 0, NULL}; + +/** + * Instantiate a procedure descriptor and its internal data structure. + * This macro compiles correctly only if the number of action nodes N + * and the number of control flows is positive. + * This macro instantiates a descriptor for a procedure without decision + * nodes. + * If there is a need to define a procedure with one or more decision + * nodes, the <code>::FW_PR_INST</code> macro should be used. + * + * The macro generates code that does the following: + * - It defines an array of N elements of type <code>PrANode_t</code> to + * represent the array holding the procedure action nodes. + * - It defines an array of NFLOWS elements of type <code>PrFlow_t</code> to + * represent the array holding the procedure control flows. + * - It defines an array of NA elements of type <code>PrAction_t</code> to + * represent the array holding the procedure actions. + * - It defines an array of (NG+1) elements of type <code>PrGuard_t</code> to + * represent the array holding the procedure guards (the extra guard is + * the "dummy guard" <code>::PrDummyGuard"</code> to be attached to control flows + * which have no guard). + * - It defines and initializes a variable of type <code>FwPrDescBase_t</code> + * to represent the base part of the procedure descriptor. + * - It defines and initializes a variable with the name PR_DESC of type + * <code>struct FwPrDesc</code> to represent the procedure descriptor. + * . + * All variables defined by this macro are <code>static</code>. + * + * The procedure descriptor instantiated by the macro is only partially + * initialized. + * Full initialization is performed using function <code>::FwPrInit</code>. + * + * Since the macro includes the declaration of several variables, it should be located + * in the section of a c-file where variable declaration is legal. + * + * @param PR_DESC the variable holding the procedure descriptor + * @param N a positive integer representing the number of action nodes + * @param NFLOWS a positive integer representing the number of control flows + * @param NA a positive integer representing the number of actions + * @param NG a non-negative integer representing the number of guards (i.e. the + * number of transition actions which are defined on the procedure) + */ +#define FW_PR_INST_NODEC(PR_DESC, N, NFLOWS, NA, NG) \ + static PrANode_t PR_DESC##_aNodes[(N)]; \ + static PrFlow_t PR_DESC##_flows[(NFLOWS)]; \ + static FwPrAction_t PR_DESC##_actions[(NA)]; \ + static FwPrGuard_t PR_DESC##_guards[(NG) + 1]; \ + static PrBaseDesc_t PR_DESC##_base = {(PR_DESC##_aNodes), NULL, (PR_DESC##_flows), N, 0, NFLOWS}; \ + static struct FwPrDesc(PR_DESC) = { \ + &(PR_DESC##_base), (PR_DESC##_actions), (PR_DESC##_guards), NA, (NG) + 1, 1, 0, prSuccess, 0, 0, NULL}; + +/** + * Instantiate a descriptor for a derived procedure. + * A derived procedure is a procedure which is created by extending + * another procedure. + * The procedure which is thus extended is called base procedure. + * + * A procedure descriptor consists of two parts: the base descriptor and + * the extension descriptor (see <code>FwPrPrivate.h</code>). + * A derived procedure and its base procedure share the same base descriptor + * (which defines the topology of the procedure) but have different extension + * descriptors. + * This macro accordingly only instantiates a new extension descriptor. + * More precisely, this macro generates code that does the following: + * - It defines an array of NA elements of type <code>PrAction_t</code> to + * represent the array holding the procedure actions. + * - It defines an array of (NG+1) elements of type <code>PrGuard_t</code> to + * represent the array holding the procedure guards (the extra guard is + * the "dummy guard" <code>::PrDummyGuard"</code> to be attached to control + * flows which have no guard). + * - It defines and initializes a variable with the name PR_DESC of type + * <code>struct FwPrDesc</code> to represent the procedure descriptor. + * . + * All variables defined by this macro are <code>static</code>. + * + * The procedure descriptor instantiated by the macro is only partially + * initialized. + * Full initialization is performed using function <code>::FwPrInitDer</code>. + * + * Since the macro includes the declaration of several variables, it should be located + * in the section of a c-file where variable declaration is legal. + * + * @param PR_DESC the variable holding the procedure descriptor + * @param NA a non-negative integer representing the number of actions + * @param NG a non-negative integer representing the number of guards + */ +#define FW_PR_INST_DER(PR_DESC, NA, NG) \ + static FwPrAction_t PR_DESC##_actions[(NA)]; \ + static FwPrGuard_t PR_DESC##_guards[(NG) + 1]; \ + static struct FwPrDesc(PR_DESC) = { \ + NULL, (PR_DESC##_actions), (PR_DESC##_guards), NA, (NG) + 1, 1, 0, prSuccess, 0, 0, NULL}; + +/** + * Initialize a procedure descriptor to represent an unconfigured procedure + * with no control flows, no actions, and no guards. + * After this function has been executed, the argument procedure descriptor + * has the same content as a procedure descriptor which has been + * created by calling <code>::FwPrCreate</code>. + * + * This function is primarily intended to be used to initialize a procedure + * descriptor which has been statically instantiated with macro + * <code>#FW_PR_INST</code> or <code>#FW_PR_INST_NODEC</code>. + * + * If the function is called upon a procedure descriptor that had already been + * initialized, the previous initialization values are lost. + * In such a case, a memory leak is possible due to the potential loss of the pointers + * to the arrays where the procedures nodes and control flows are stored. + * @param prDesc the procedure descriptor to be initialized. + */ +void FwPrInit(FwPrDesc_t prDesc); + +/** + * Initialize a procedure descriptor to extend another procedure (the + * base procedure). + * This function checks that the descriptor to be initialized satisfies + * the following constraints: + * - it has the same number of actions as the base procedure, and + * - it has the same number of guards as the base procedure. + * . + * If either constraint is not satisfied, the function reports an error + * by setting the error code of the descriptor to be initialized and then + * returns. + * If the first constraint is not satisfied, the function sets the error + * code to <code>#prWrongNOfActions</code>. + * If the second constraint is not satisfied, the function sets the error + * code to <code>#prWrongNOfGuards</code>. + * + * If both constraints are satisfied, this function initializes a descriptor + * as follows: + * - It links it to the descriptor of the base procedure. + * - It initializes its actions to be the same as the actions of the base state + * machine. + * - It initializes its guards to be the same as the guards of the base state + * machine. + * - It initializes its error code to be the same as the error code of the base + * procedure. + * - It initializes its <code>flowCnt</code> field to zero. + * - It sets its state to STOPPED. + * . + * Thus, the descriptor initialized by this function represents + * exactly the same procedure as the descriptor created by calling + * function <code>::FwPrCreateDer</code>. + * + * This function is primarily intended to be used to initialize a procedure + * descriptor which has been statically instantiated with macro + * <code>#FW_PR_INST_DER</code>. + * If the function is called upon a procedure descriptor that had already been + * initialized, the previous initialization values are lost. + * In such a case, a memory leak is possible due to the potential loss of the pointers + * to the arrays where the procedures states, choice pseudo-states, transitions and + * embedded procedures are stored. + * @param prDesc the procedure descriptor to be initialized. + * @param prDescBase the procedure descriptor of the base procedure. + */ +void FwPrInitDer(FwPrDesc_t prDesc, FwPrDesc_t prDescBase); + +#endif /* FWPR_SCREATE_H_ */ diff --git a/FwProfile/src/FwRtConfig.c b/FwProfile/src/FwRtConfig.c new file mode 100644 index 0000000000000000000000000000000000000000..013b265c44d0d86daf640658e2f2e1b6dc07659f --- /dev/null +++ b/FwProfile/src/FwRtConfig.c @@ -0,0 +1,278 @@ +/** + * @file + * @ingroup rtGroup + * Implements Configuration Functions of the RT Container. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwRtConfig.h" +#if 0 +#include "FwRtConstants.h" +#include <pthread.h> +#endif +#include <stdlib.h> + +/** + * Dummy function which always returns 1. + * This function is used as the default for the procedure actions of the RT Container. + * @param rtDesc the descriptor of the RT Container + * @return this function always returns 1 + */ +FwRtOutcome_t DummyAction(FwRtDesc_t rtDesc); + +void FwRtReset(FwRtDesc_t rtDesc) { + rtDesc->state = rtContUninitialized; + rtDesc->activPrStarted = 0; + rtDesc->notifPrStarted = 0; + rtDesc->errCode = 0; + rtDesc->execFuncBehaviour = &DummyAction; + rtDesc->finalizeActivPr = &DummyAction; + rtDesc->finalizeNotifPr = &DummyAction; + rtDesc->implementActivLogic = &DummyAction; + rtDesc->implementNotifLogic = &DummyAction; + rtDesc->initializeActivPr = &DummyAction; + rtDesc->initializeNotifPr = &DummyAction; + rtDesc->setUpNotification = &DummyAction; + rtDesc->notifCounter = 0; + rtDesc->pThreadAttr = NULL; + rtDesc->pCondAttr = NULL; + rtDesc->pMutexAttr = NULL; + rtDesc->rtData = NULL; +} + +/*--------------------------------------------------------------------------------------*/ +void FwRtInit(FwRtDesc_t rtDesc) { + int errCode; + + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + + /* Initialize mutex attributes */ + if (rtDesc->pMutexAttr != NULL) { + if ((errCode = pthread_mutexattr_init(rtDesc->pMutexAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexAttrInitErr; + return; + } + } + + /* Initialize condition variable attributes */ + if (rtDesc->pCondAttr != NULL) { + if ((errCode = pthread_condattr_init(rtDesc->pCondAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtCondAttrInitErr; + return; + } + } + + /* Initialize thread attributes */ + if (rtDesc->pThreadAttr != NULL) { + if ((errCode = pthread_attr_init(rtDesc->pThreadAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtThreadAttrInitErr; + return; + } + } + + /* Initialize mutex */ + if ((errCode = pthread_mutex_init(&(rtDesc->mutex), rtDesc->pMutexAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexInitErr; + return; + } + + /* Initialize condition variable */ + if ((errCode = pthread_cond_init(&(rtDesc->cond), rtDesc->pCondAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtCondInitErr; + return; + } + + rtDesc->state = rtContStopped; +} + +/*--------------------------------------------------------------------------------------*/ +void FwRtShutdown(FwRtDesc_t rtDesc) { + int errCode; + + /* Destroy mutex attributes */ + if (rtDesc->pMutexAttr != NULL) { + if ((errCode = pthread_mutexattr_destroy(rtDesc->pMutexAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexAttrDestroyErr; + return; + } + } + + /* Destroy condition variable attributes */ + if (rtDesc->pCondAttr != NULL) { + if ((errCode = pthread_condattr_destroy(rtDesc->pCondAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtCondAttrDestroyErr; + return; + } + } + + /* Destroy thread attributes */ + if (rtDesc->pThreadAttr != NULL) { + if ((errCode = pthread_attr_destroy(rtDesc->pThreadAttr)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtThreadAttrDestroyErr; + return; + } + } + + if ((errCode = pthread_cond_destroy(&(rtDesc->cond))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtCondDestroyErr; + return; + } + + if ((errCode = pthread_mutex_destroy(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexDestroyErr; + return; + } + + rtDesc->state = rtContUninitialized; +} + +/*--------------------------------------------------------------------------------------*/ +void FwRtSetPosixAttr(FwRtDesc_t rtDesc, pthread_attr_t* pThreadAttr, pthread_mutexattr_t* pMutexAttr, + pthread_condattr_t* pCondAttr) { + + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + + rtDesc->pThreadAttr = pThreadAttr; + rtDesc->pMutexAttr = pMutexAttr; + rtDesc->pCondAttr = pCondAttr; +} + +/*--------------------------------------------------------------------------------------*/ +pthread_attr_t* FwRtGetActivThreadAttr(FwRtDesc_t rtDesc) { + return rtDesc->pThreadAttr; +} + +/*--------------------------------------------------------------------------------------*/ +pthread_mutexattr_t* FwRtGetMutexAttr(FwRtDesc_t rtDesc) { + return rtDesc->pMutexAttr; +} + +/*--------------------------------------------------------------------------------------*/ +pthread_condattr_t* FwRtGetCondAttr(FwRtDesc_t rtDesc) { + return rtDesc->pCondAttr; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetData(FwRtDesc_t rtDesc, void* rtData) { + rtDesc->rtData = rtData; +} + +/* -------------------------------------------------------------------------------------*/ +void* FwRtGetData(FwRtDesc_t rtDesc) { + return rtDesc->rtData; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetInitializeNotifPr(FwRtDesc_t rtDesc, FwRtAction_t initializeNotifPr) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->initializeNotifPr = initializeNotifPr; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetFinalizeNotifPr(FwRtDesc_t rtDesc, FwRtAction_t finalizeNotifPr) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->finalizeNotifPr = finalizeNotifPr; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetImplementNotifLogic(FwRtDesc_t rtDesc, FwRtAction_t implementNotifLogicPr) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->implementNotifLogic = implementNotifLogicPr; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetInitializeActivPr(FwRtDesc_t rtDesc, FwRtAction_t initializeActivPr) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->initializeActivPr = initializeActivPr; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetFinalizeActivPr(FwRtDesc_t rtDesc, FwRtAction_t finalizeActivPr) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->finalizeActivPr = finalizeActivPr; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetSetUpNotif(FwRtDesc_t rtDesc, FwRtAction_t setUpNotification) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->setUpNotification = setUpNotification; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetImplementActivLogic(FwRtDesc_t rtDesc, FwRtAction_t implementActivLogic) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->implementActivLogic = implementActivLogic; +} + +/* -------------------------------------------------------------------------------------*/ +void FwRtSetExecFuncBehaviour(FwRtDesc_t rtDesc, FwRtAction_t execFuncBehaviour) { + if (rtDesc->state != rtContUninitialized) { + rtDesc->state = rtConfigErr; + return; + } + rtDesc->execFuncBehaviour = execFuncBehaviour; +} + +/* -------------------------------------------------------------------------------------*/ +FwRtOutcome_t DummyAction(FwRtDesc_t rtDesc) { + (void)(rtDesc); + return 1; +} diff --git a/FwProfile/src/FwRtConfig.h b/FwProfile/src/FwRtConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..187934153832d6bb139e1eb862fcacc339f18ac8 --- /dev/null +++ b/FwProfile/src/FwRtConfig.h @@ -0,0 +1,414 @@ +/** + * @file + * @ingroup rtGroup + * Declaration of the configuration interface for a RT Container. + * A RT Container is described by a container descriptor. + * The functions declared in this interface allow a container descriptor + * to be configured. + * + * The user instantiates a RT Container descriptor by creating a variable + * of type <code>struct FwRtCont</code>. + * After the container descriptor has been instantiated, it is configured + * using the functions defined in this header file as follows: + * -# The container descriptor is reset with function <code>::FwRtReset</code>. + * -# The attributes of the container's POSIX objects may be set with + * function <code>::FwRtSetPosixAttr</code>. + * -# The pointers to the procedure functions which implement the adaptation + * points of the container may be set with function <code>FwRtSetProcActions</code>. + * -# The pointer to the RT Container data in the container descriptor + * may be set with the <code>::FwRtSetData</code> function. + * -# The container is initialized with function <code>::FwRtInit</code>. + * This completes the configuration process. + * . + * Configuration can only be done before the container is started with + * <code>::FwRtStart</code> or after the container has been shut down with + * <code>::FwRtShutdown</code>. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWRT_CONFIG_H_ +#define FWRT_CONFIG_H_ + +#include "FwRtConstants.h" + +#if __sparc__ + #include <fsu_pthread.h> +#else + #include <pthread.h> +#endif + +/** + * Reset the RT Container descriptor (RTD). + * This function should be called at the beginning of the configuration process. + * The function initializes the fields of the container descriptor with default + * values as follows: + * - The actions of the Notification Procedure and of the Activation Procedure are set + * equal to a dummy action representing a situation where all + * procedure actions do nothing and always return 1. + * - The attribute objects for the Activation Thread, for the container mutex, and for + * the container condition variable are set to NULL. This represents a situation + * where the default values for these attributes are used. + * - The error code is set to zero. + * - The notification counter is set to zero. + * - The container state is set to: <code>::rtContUninitialized</code>. + * - The state of the Activation and Notification Procedures is set to: STOPPED. + * - The pointer to the container data is set to NULL. + * . + * @param rtDesc the descriptor of the RT Container + */ +void FwRtReset(FwRtDesc_t rtDesc); + +/** + * Initialize a RT Container. + * The following initialization actions are performed: + * - If the container state is not <code>::rtContUninitialized</code>, the function + * sets the container's state to the error state <code>::rtConfigErr</code> + * and then returns. + * - If non-NULL attributes have been loaded for the container's POSIX objects + * (i.e. if the user has called function <code>FwRtSetPosixAttr</code> with + * non-NULL values), the attributes are initialized using their POSIX initialization + * functions (<code>pthread_attr_init</code>, <code>pthread_mutexattr_init</code>, + * and <code>pthread_condattr_init</code>) and then the initialized attributes + * are used to initialize the mutex and the condition variable. + * - If no attributes have been loaded for the container's POSIX mutex and + * condition variable (i.e. if the user has not called function + * <code>::FwRtSetPosixAttr</code> or he has called it with NULL values for + * the POSIX attributes), the container POSIX mutex and condition variable are + * initialized with their default attribute values. + * - If any of the POSIX system calls made by this function returns an error, + * the container state is set to an error state (see <code>::FwRtState_t</code>) + * and the error code is initialized with the error code returned by the failed + * POSIX system call. + * - If all the POSIX system calls made by this function are successful, + * the container state is set to <code>::rtContStopped</code>. + * . + * A call to this function concludes the configuration process of the RTD. + * The configuration process has been successful if, after this function is called, + * the container is in state <code>::rtContStopped</code>. + * @param rtDesc the descriptor of the RT Container. + */ +void FwRtInit(FwRtDesc_t rtDesc); + +/** + * Shutdown the RT Container. + * The following shutdown actions are performed: + * - If non-NULL attributes have been loaded for the container's POSIX thread, + * or for the container's POSIX mutex, or for the container's POSIX condition + * variable, the attributes are destroyed using their POSIX destruction + * functions (<code>pthread_attr_destroy</code>, <code>pthread_mutexattr_destroy</code>, + * and <code>pthread_condattr_destroy</code>). + * - The container POSIX mutex and POSIX condition variables are destroyed using + * their POSIX destructor functions (<code>pthread_mutex_destroy</code> and + * <code>pthread_cond_destroy</code>). + * - If all the POSIX system calls made by this function are successful, then the + * container state is set to <code>::rtContUninitialized</code> to signify + * that the container is now uninitialized. + * - If any of the POSIX system calls made by this function returns an error, + * the container state is set to an error state (see <code>::FwRtState_t</code>) + * and the error code is set to the error code returned by the failed POSIX + * system call. + * . + * After this function has been called, the container must be again configured in + * full before it can again be used. + * + * This function should only be called when the RT Container is in state STOPPED + * and after its Activation Thread has terminated execution. + * Enforcement of this constraint is under the responsibility of the user. + * + * @param rtDesc the descriptor of the RT Container. + */ +void FwRtShutdown(FwRtDesc_t rtDesc); + +/** + * Set the pointers to the attribute objects of the POSIX thread, mutex and condition + * variable used by the container. + * A RT Container uses a POSIX thread, a POSIX mutex and a POSIX condition + * variable. + * Their configuration is defined by attribute objects. + * This function allows the attribute objects to be loaded into the container. + * A value of NULL for an attribute object means that the POSIX-defined default + * value for that attribute will be used. + * The attribute objects will be initialized at the end of the container + * configuration process when <code>::FwRtInit</code> is called. + * + * The thread attributes are used when the container's thread (the Activation Thread) + * is started by calling <code>::FwRtStart</code>. + * The mutex and condition variable attributes are used when the container mutex and + * its condition variable are initialized by calling <code>::FwRtInit</code>. + * + * If this function is not called during the container configuration process, + * the container will be configured with NULL values for all POSIX attribute + * objects (i.e. the POSIX thread, mutex and condition variable will be + * initialized with their POSIX-defined default attribute values). + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the descriptor of the RT Container + * @param pThreadAttr the attributes of the Activation Thread (or NULL if it is desired + * to use default attribute for the thread) + * @param pMutexAttr the attributes of the container's mutex (or NULL if it is desired + * to use default attribute for the mutex) + * @param pCondAttr the attributes of the container's mutex (or NULL if it is desired + * to use default attribute for the condition variable) + */ +void FwRtSetPosixAttr(FwRtDesc_t rtDesc, pthread_attr_t* pThreadAttr, pthread_mutexattr_t* pMutexAttr, + pthread_condattr_t* pCondAttr); + +/** + * Get the value of the attributes of the Activation Thread. + * The attribute values returned by this call are those set with + * <code>::FwRtSetPosixAttr</code> or NULL if the container + * was initialized without calling this function. + * @param rtDesc the descriptor of the RT Container + * @return the attributes of the Activation Thread + */ +pthread_attr_t* FwRtGetActivThreadAttr(FwRtDesc_t rtDesc); + +/** + * Get the value of the attributes of the mutex associated to the RT Container. + * The attribute values returned by this call are those set with + * <code>::FwRtSetPosixAttr</code> or NULL if the container + * was initialized without calling this function. + * @param rtDesc the descriptor of the RT Container + * @return the attributes of the mutex + */ +pthread_mutexattr_t* FwRtGetMutexAttr(FwRtDesc_t rtDesc); + +/** + * Get the value of the attributes of the condition variable associated to + * the RT Container. + * The attribute values returned by this call are those set with + * <code>::FwRtSetPosixAttr</code> or NULL if the container + * was initialized without calling this function. + * @param rtDesc the descriptor of the RT Container + * @return the attributes of the condition variable + */ +pthread_condattr_t* FwRtGetCondAttr(FwRtDesc_t rtDesc); + +/** + * Set the pointer to the RT Container data in the container descriptor. + * The container data are data which are manipulated by the container's + * procedures. + * The container descriptor holds a pointer to the procedure data. + * This function allows this pointer to be defined. + * The exact type of the container data is defined by applications for each + * RT Container. + * It is therefore unknown at the level of the RT Container module. + * This function accordingly treats the pointer to the procedure data as a + * pointer to <code>void</code>. + * In most cases, the container data will take the form of a <code>struct</code> + * whose fields represent the inputs and outputs for the procedure actions + * and guards. + * + * The functions which implement the container's procedures access the + * container data as follows: + * - The procedure functions take the container descriptor as an argument + * (because they must conform to the <code>::FwRtAction_t</code> prototype). + * - The procedure functions use the <code>::FwRtGetData</code> function to + * retrieve the pointer to the container data. + * - The pointer returned by <code>::FwRtGetData</code> is defined as a pointer + * to <code>void</code> and will normally have to be cast to its true type. + * . + * If this function is not called, the value of the container data is NULL. + * + * This function may be called at any time but should normally be called only during + * the container configuration process. + * @param rtDesc the RT Container descriptor. + * @param rtData the pointer to the container data (a value of NULL is legal + * if no data need be attached to the container). + */ +void FwRtSetData(FwRtDesc_t rtDesc, void* rtData); + +/** + * Get the pointer to the container data in the container descriptor. + * This function returns the pointer which was set with the + * <code>::FwRtSetData</code> function. + * @param rtDesc the RT Container descriptor. + * @return the pointer to the container data. + */ +void* FwRtGetData(FwRtDesc_t rtDesc); + +/** + * Define the function implementing the Initialization Action for the Notification + * Procedure. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the Initialization Action + * is used which is a dummy action which corresponds to a situation where no + * initialization action is performed by the Notification Procedure. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param initializeNotifPr the pointer to the function implementing the + * Initialization Action for the Notification Procedure. + */ +void FwRtSetInitializeNotifPr(FwRtDesc_t rtDesc, FwRtAction_t initializeNotifPr); + +/** + * Define the function implementing the Finalization Action for the Notification + * Procedure. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the Finalization Action + * is used which is a dummy action which corresponds to a situation where no + * finalization action is performed by the Notification Procedure. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param finalizeNotifPr the pointer to the function implementing the + * Finalization Action for the Notification Procedure. + */ +void FwRtSetFinalizeNotifPr(FwRtDesc_t rtDesc, FwRtAction_t finalizeNotifPr); + +/** + * Define the function implementing the Notification Logic for the Notification + * Procedure. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the Notification Logic + * is used which is a dummy action which never skips a notification. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param implementNotifLogicPr the pointer to the function implementing the + * Notification Logic for the Notification Procedure. + */ +void FwRtSetImplementNotifLogic(FwRtDesc_t rtDesc, FwRtAction_t implementNotifLogicPr); + +/** + * Define the function implementing the Initialization Action for the Activation + * Procedure. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the Initialization Action + * is used which is a dummy action which corresponds to a situation where no + * initialization action is performed by the Activation Procedure. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param initializeActivPr the pointer to the function implementing the + * Initialization Action for the Activation Procedure. + */ +void FwRtSetInitializeActivPr(FwRtDesc_t rtDesc, FwRtAction_t initializeActivPr); + +/** + * Define the function implementing the Finalization Action for the Activation + * Procedure. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the Finalization Action + * is used which is a dummy action which corresponds to a situation where no + * finalization action is performed by the Activation Procedure. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param finalizeActivPr the pointer to the function implementing the + * Finalization Action for the Activation Procedure. + */ +void FwRtSetFinalizeActivPr(FwRtDesc_t rtDesc, FwRtAction_t finalizeActivPr); + +/** + * Define the function implementing the logic to set up a notification for the + * RT Container. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the Set Up Notification + * Function is used which is a dummy action which corresponds to a situation + * where no notification set-up mechanism is implemented. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param setUpNotification the pointer to the function implementing the + * Set Up Notification logic. + */ +void FwRtSetSetUpNotif(FwRtDesc_t rtDesc, FwRtAction_t setUpNotification); + +/** + * Define the function implementing the activation logic for the RT Container. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the Implementation Activation + * Logic Function is used which is a dummy action which corresponds to a situation + * where the container's functional behaviour is executed at every activation cycle. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param implementActivLogic the pointer to the function implementing the + * container's activation logic. + */ +void FwRtSetImplementActivLogic(FwRtDesc_t rtDesc, FwRtAction_t implementActivLogic); + +/** + * Define the function which executes the functional behaviour associated to the + * RT Container. + * The argument function must conform to the <code>::FwRtAction_t</code> prototype. + * + * If this function is not called, the default value for the container's functional + * behaviour is used. + * This is a dummy action which corresponds to a situation where the + * container's functional behaviour is terminated after the first execution. + * + * This function may only be called during the container's configuration process + * (i.e. before <code>::FwRtInit</code> is called or after <code>::FwRtShutdown</code> + * is called). + * If it is called at any other time, it causes the container's state to be + * put in error state <code>::rtConfigErr</code>. + * @param rtDesc the RT Container descriptor. + * @param execFuncBehaviour the pointer to the function implementing the + * container's functional behaviour. + */ +void FwRtSetExecFuncBehaviour(FwRtDesc_t rtDesc, FwRtAction_t execFuncBehaviour); + +#endif /* FWRT_CONFIG_H_ */ diff --git a/FwProfile/src/FwRtConstants.h b/FwProfile/src/FwRtConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..f88fcd3d94a11e092e263948cb7e5d0030d92046 --- /dev/null +++ b/FwProfile/src/FwRtConstants.h @@ -0,0 +1,274 @@ +/** + * @file + * @ingroup rtGroup + * Header file to define all constants and types for the RT Container Module + * of the FW Profile. + * This header file should be included by all applications which use the + * RT Container Module of the FW Profile. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWRT_CONSTANTS_H_ +#define FWRT_CONSTANTS_H_ + +#if __sparc__ + #include <fsu_pthread.h> +#else + #include <pthread.h> +#endif + + +/** + * Forward declaration for the pointer to a RT Container Descriptor. + * A RT Container Descriptor is a data structure which holds all the information + * describing a RT Container instance. + */ +typedef struct FwRtDesc* FwRtDesc_t; + +/** Type used for booleans (0 is "false" and 1 is "true"). */ +typedef int FwRtBool_t; + +/** Type used for the outcome of a container action. */ +typedef int FwRtOutcome_t; + +/** Type used for unsigned integers with a "medium" range. */ +typedef short int FwRtCounterU2_t; + +/** + * Type for a pointer to a container action. + * A container action is a function which encapsulates an action executed by + * either the Notification Procedure or the Activation Procedure of a + * RT Container. + * Container actions return an outcome. + * The semantics of the outcome depends on the kind of action. + */ +typedef FwRtOutcome_t (*FwRtAction_t)(FwRtDesc_t); + +/** + * Enumerated type for the state of the RT Container. + * The only nominal values are <code>rtContStopped</code> and <code>rtContStarted</code>. + * If the container is not in one of these two states, its behaviour is undefined. + * All other values indicate that an error has been reported by a system call. + * The error code reported by the system call is stored in the error code field of + * the RT Container Descriptor. + */ +typedef enum { + /** The RT Container has not yet been initialized */ + rtContUninitialized = 0, + /** The RT Container is in state STOPPED */ + rtContStopped = 3, + /** The RT Container is in state STARTED */ + rtContStarted = 4, + /** The function to create the Activation Thread has reported an error */ + rtThreadCreateErr = 5, + /** The function to initialize the container mutex has reported an error */ + rtMutexInitErr = 6, + /** The function to destroy the container mutex has reported an error */ + rtMutexDestroyErr = 7, + /** The function to initialize the container condition has reported an error */ + rtCondInitErr = 8, + /** The function to destroy the container condition has reported an error */ + rtCondDestroyErr = 9, + /** The function to lock the container mutex has reported an error */ + rtMutexLockErr = 10, + /** The function to unlock the container mutex has reported an error */ + rtMutexUnlockErr = 11, + /** The function to signal a condition has reported an error */ + rtCondSignalErr = 12, + /** The function to wait on a condition has reported an error */ + rtCondWaitErr = 13, + /** The function to initialize a mutex attribute has reported an error */ + rtMutexAttrInitErr = 14, + /** The function to initialize a mutex attribute has reported an error */ + rtCondAttrInitErr = 15, + /** The function to initialize a thread attribute has reported an error */ + rtThreadAttrInitErr = 16, + /** The function to destroy a mutex attribute has reported an error */ + rtMutexAttrDestroyErr = 17, + /** The function to destroy a mutex attribute has reported an error */ + rtCondAttrDestroyErr = 18, + /** The function to destroy a thread attribute has reported an error */ + rtThreadAttrDestroyErr = 19, + /** The function to wait on a thread join has reported an error */ + rtJoinErr = 20, + /** A configuration function has been called during the container's normal operation + * (i.e. after <code>::FwRtInit</code> has been called but before <code>::FwRtShutdown</code> + * is called) */ + rtConfigErr = 21 +} FwRtState_t; + +typedef enum { rtSampleEnumItem } FwRtSampleEnum; + +/** + * Structure representing a RT Container Descriptor. + * The RT Container Descriptor holds all the information which describes a RT + * Container. + * This consists of: + * - The STARTED/STOPPED state of the RT Container; + * - The activation thread; + * - The lock (a mutex) associated to the RT Container; + * - The state of the Notification and Activation Procedures associated to the + * container; + * - The pointers to the functions which implement the adaptation points of + * the container; + * - The outcome of the last action executed by the Notification Procedure; + * - The outcome of the last action executed by the Activation Procedure; + * - The error code for the RT Container; + * - A pointer to a user-defined data structure to hold the container's data. + * . + * The STARTED/STOPPED state of the RT Container is not stored explicitly + * because a RT Container is started if and only if its pthread object is + * non-NULL. + */ +struct FwRtDesc { + /** The state of the RT Container. */ + FwRtState_t state; + /** + * The pointer to the Activation Thread attributes. + * The default value of NULL indicates the default values of a pthread + * attributes should be used. + */ + pthread_attr_t* pThreadAttr; + /** + * The pointer to the mutex attributes. + * The default value of NULL indicates the default values of a pthread + * mutex attributes should be used. + */ + pthread_mutexattr_t* pMutexAttr; + /** + * The pointer to the condition variable attributes. + * The default value of NULL indicates the default values of a pthread + * condition variable attributes should be used. + */ + pthread_condattr_t* pCondAttr; + /** The thread associated to the RT Container. */ + pthread_t activationThread; + /** The mutex associated to the RT Container. */ + pthread_mutex_t mutex; + /** The condition variable associated to the RT Container */ + pthread_cond_t cond; + /** The notification counter */ + FwRtCounterU2_t notifCounter; + /** + * Pointer to the function encapsulating the initialization action for the + * Notification Procedure. + * This is a user-defined function. + * This function is called once when the Notification Procedure is executed + * for the first time. + * It should perform any initialization action which is required by the + * Notification Procedure. + * The function always returns a value of 1. + */ + FwRtAction_t initializeNotifPr; + /** + * Pointer to the function encapsulating the finalization action for the + * Notification Procedure. + * This is a user-defined function. + * This function is called just before the Notification Procedure terminates. + * It should perform any finalization action which is required by the + * Notification Procedure. + * The function always returns a value of 1. + */ + FwRtAction_t finalizeNotifPr; + /** + * Pointer to the function encapsulating the implementation of the notification + * logic. + * This is a user-defined function. + * After the Notification Procedure has been executed for the first time, + * this function is called every time the procedure is executed as long as + * the Notification Procedure has not been stopped. + * This procedure should implement the logic which decides whether the Activation + * Thread should be notified. + * The function returns 1 if the Activation Thread is to be notified or it returns + * 0 if the notification of the Activation Thread should be skipped. + */ + FwRtAction_t implementNotifLogic; + /** + * Pointer to the function encapsulating the initialization action for the + * Activation Procedure. + * This is a user-defined function. + * This function is called once when the Activation Procedure is executed + * for the first time. + * It should perform any initialization action which is required by the + * Activation Procedure. + * The function always returns a value of 1. + */ + FwRtAction_t initializeActivPr; + /** + * Pointer to the function encapsulating the finalization action for the + * Activation Procedure. + * This is a user-defined function. + * This function is called just before the Activation Procedure terminates. + * It should perform any finalization action which is required by the + * Activation Procedure. + * The function always returns a value of 1. + */ + FwRtAction_t finalizeActivPr; + /** + * Pointer to the function encapsulating the logic to set up the notification + * for the RT Container. + * This is a user-defined function. + * This function is called each time the Activation Procedure is executed. + * This function may be used to implement the logic which determines when the + * next notification is sent to the RT Container. + * The function always returns a value of 1. + */ + FwRtAction_t setUpNotification; + /** + * Pointer to the function encapsulating the implementation of the activation + * logic. + * This is a user-defined function. + * After the Activation Procedure has been executed for the first time, + * this function is called every time the procedure is executed as long as + * the RT Container has not been stopped. + * This procedure should implement the logic which decides whether the Functional + * Behaviour associated to the RT Container is executed. + * The function returns 1 if the container's functional behaviour should be executed + * and it returns 0 if the container's functional behaviour should not be executed. + */ + FwRtAction_t implementActivLogic; + /** + * Pointer to the function encapsulating the execution of the functional behaviour + * associated to the RT Container. + * This is a user-defined function. + * After the Activation Procedure has been executed for the first time, + * this function is called every time the procedure is executed as long as + * the RT Container has not been stopped. + * This procedure should implement the functional behaviour associated to the + * RT Container. + * The function returns 1 if the execution of the functional behaviour has terminated + * and it returns 0 if the execution of the functional behaviour is not yet terminated. + */ + FwRtAction_t execFuncBehaviour; + /** The flag indicating whether the Notification Procedure is STÂRTED. */ + FwRtBool_t notifPrStarted; + /** The flag indicating whether the Activation Procedure is STÂRTED. */ + FwRtBool_t activPrStarted; + /** The return value of the last system call which failed. */ + int errCode; + /** The pointer to the RT Container data. */ + void* rtData; +}; + +#endif /* FWRT_CONSTANTS_H_ */ diff --git a/FwProfile/src/FwRtCore.c b/FwProfile/src/FwRtCore.c new file mode 100644 index 0000000000000000000000000000000000000000..b5ea2caf19b8186e82e377f33e1f8048e6f1a174 --- /dev/null +++ b/FwProfile/src/FwRtCore.c @@ -0,0 +1,290 @@ +/** + * @file + * @ingroup rtGroup + * Implements Core Functions of the RT Container. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwRtCore.h" +#include "FwRtConstants.h" +#if 0 + #include <pthread.h> /* use fsu_pthread.h on SPARC */ +#endif +#include <stdlib.h> + +/** + * The Activation Thread of the RT Container. + * This function is called by the Activation Thread when it is created. + * @param ptr this parameter is not used + * @return this function always returns NULL + */ +void* ExecActivThread(void* ptr); + +/** + * Execute the loop in the Notification Procedure. + * @param rtDesc the descriptor of the RT Container + */ +void ExecNotifProcedure(FwRtDesc_t rtDesc); + +/** + * Execute the loop in the Activation Procedure. + * No check is performed on whether the activation procedure is started + * because, by design, the Activation Procedure is only ever executed + * if it is started. + * @param rtDesc the descriptor of the RT Container + */ +void ExecActivProcedure(FwRtDesc_t rtDesc); + +/*--------------------------------------------------------------------------------------*/ +void FwRtStart(FwRtDesc_t rtDesc) { + int errCode; + + if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexLockErr; + return; + } + + if (rtDesc->state != rtContStopped) { + if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexUnlockErr; + return; + } + return; + } + + /* Start Notification Procedure */ + rtDesc->notifPrStarted = 1; + /* Start Activation Procedure */ + rtDesc->activPrStarted = 1; + + /* Execute Notification and Activation Procedures. Since the procedures have just been + * started, this is equivalent to executing their initialization actions and (for the + * Activation Procedure) its Set Up Notification action. */ + rtDesc->initializeNotifPr(rtDesc); + rtDesc->initializeActivPr(rtDesc); + rtDesc->setUpNotification(rtDesc); + + rtDesc->state = rtContStarted; + rtDesc->notifCounter = 0; + + /* Create thread */ + if ((errCode = pthread_create(&(rtDesc->activationThread), rtDesc->pThreadAttr, ExecActivThread, rtDesc)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtThreadCreateErr; + return; + } + + if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexUnlockErr; + return; + } + + return; +} + +/*--------------------------------------------------------------------------------------*/ +void FwRtStop(FwRtDesc_t rtDesc) { + int errCode; + + if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexLockErr; + return; + } + + if (rtDesc->state != rtContStarted) { + if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexUnlockErr; + return; + } + return; + } + + /* Stop the RT Container */ + rtDesc->state = rtContStopped; + + /* Notify the Activation Thread */ + rtDesc->notifCounter++; + + if ((errCode = pthread_cond_signal(&(rtDesc->cond))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtCondSignalErr; + return; + } + + if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexUnlockErr; + return; + } + + return; +} + +/*--------------------------------------------------------------------------------------*/ +void FwRtNotify(FwRtDesc_t rtDesc) { + int errCode; + + if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexLockErr; + return; + } + ExecNotifProcedure(rtDesc); + if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexUnlockErr; + return; + } +} + +/*--------------------------------------------------------------------------------------*/ +void FwRtWaitForTermination(FwRtDesc_t rtDesc) { + int errCode; + void* status = 0; + + if ((errCode = pthread_join(rtDesc->activationThread, &status)) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtJoinErr; + return; + } +} + +/*--------------------------------------------------------------------------------------*/ +FwRtBool_t FwRtIsNotifPrStarted(FwRtDesc_t rtDesc) { + return rtDesc->notifPrStarted; +} + +/*--------------------------------------------------------------------------------------*/ +FwRtBool_t FwRtIsActivPrStarted(FwRtDesc_t rtDesc) { + return rtDesc->activPrStarted; +} + +/*--------------------------------------------------------------------------------------*/ +FwRtState_t FwRtGetContState(FwRtDesc_t rtDesc) { + return rtDesc->state; +} + +/*--------------------------------------------------------------------------------------*/ +int FwRtGetErrCode(FwRtDesc_t rtDesc) { + return rtDesc->errCode; +} + +/*--------------------------------------------------------------------------------------*/ +FwRtCounterU2_t FwRtGetNotifCounter(FwRtDesc_t rtDesc) { + return rtDesc->notifCounter; +} + +/*--------------------------------------------------------------------------------------*/ +void ExecNotifProcedure(FwRtDesc_t rtDesc) { + int errCode; + + if (rtDesc->notifPrStarted == 0) { + return; + } + + if (rtDesc->activPrStarted == 0) { + rtDesc->finalizeNotifPr(rtDesc); + rtDesc->notifPrStarted = 0; + return; + } + + if (rtDesc->implementNotifLogic(rtDesc) == 1) { + rtDesc->notifCounter++; + if ((errCode = pthread_cond_signal(&(rtDesc->cond))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtCondSignalErr; + return; + } + } + + return; +} + +/*--------------------------------------------------------------------------------------*/ +void ExecActivProcedure(FwRtDesc_t rtDesc) { + + if (rtDesc->state == rtContStopped) { + rtDesc->finalizeActivPr(rtDesc); + rtDesc->activPrStarted = 0; + return; + } + + if (rtDesc->implementActivLogic(rtDesc) == 1) { /* Execute functional behaviour */ + if (rtDesc->execFuncBehaviour(rtDesc) == 1) { /* Functional behaviour is terminated */ + rtDesc->finalizeActivPr(rtDesc); + rtDesc->activPrStarted = 0; + return; + } + } + rtDesc->setUpNotification(rtDesc); + return; +} + +/*--------------------------------------------------------------------------------------*/ +void* ExecActivThread(void* ptr) { + FwRtDesc_t rtDesc = (FwRtDesc_t)ptr; + int errCode; + + while (1) { + if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexLockErr; + return NULL; + } + while (rtDesc->notifCounter == 0) { + if ((errCode = pthread_cond_wait(&(rtDesc->cond), &(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtCondWaitErr; + return NULL; + } + } + rtDesc->notifCounter--; + if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) { + rtDesc->errCode = errCode; + rtDesc->state = rtMutexUnlockErr; + return NULL; + } + + ExecActivProcedure(rtDesc); + + if (rtDesc->activPrStarted == 0) { + rtDesc->state = rtContStopped; /* Put RT Container in state STOPPED */ + FwRtNotify(rtDesc); /* Execute Notification Procedure in mutual exclusion */ + break; + } + + if (rtDesc->state == rtContStopped) { + ExecActivProcedure(rtDesc); + FwRtNotify(rtDesc); /* Execute Notification Procedure in mutual exclusion */ + break; + } + } + + return NULL; +} diff --git a/FwProfile/src/FwRtCore.h b/FwProfile/src/FwRtCore.h new file mode 100644 index 0000000000000000000000000000000000000000..aa1bb55cc3581d774fd0b879810133910ffe700d --- /dev/null +++ b/FwProfile/src/FwRtCore.h @@ -0,0 +1,220 @@ +/** + * @file + * @ingroup rtGroup + * Declaration of the API for a RT Container. + * A RT Container consists of: + * - A POSIX thread (the container's Activation Thread) + * - A POSIX mutex + * - A POSIX condition variable + * - Two procedures (the Notification Procedure and the Activation Procedure) + * - A pointer to a user-defined data structure to hold the data associated to the + * RT Container + * - An error code field to hold the code of the last error encountered by the + * container procedures + * . + * The Notification Procedure and the Activation Procedure implement the logic + * defined in the figure below. + * + * This interface offers functions to: + * - start and stop the RT Container; + * - execute the container's Notification Procedure; + * - query the state of the container or of its procedures. + * . + * The functions declared in this header file, take a RT Container Descriptor + * as their argument. + * This represents the RT Container upon which the functions operate. + * The functions assume that the container has been fully and correctly configured + * (this is done through the functions defined in <code>FwRtConfig.h</code>). + * + * The basic mode of use of the functions defined in this header file is as follows: + * -# The container is configured through the functions offered by + * <code>FwRtConfig.h</code>. + * -# The RT Container is started with function <code>::FwRtStart</code>. + * -# The RT Container is notified by calling function + * <code>::FwRtNotify</code>. + * -# The RT Container is stopped with function <code>::FwRtStop</code>. + * . + * After the container has been stopped, it can be re-started. + * @image html RTContainer.png + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWRT_CORE_H_ +#define FWRT_CORE_H_ + +#include "FwRtConstants.h" + +/** + * Start a RT Container. + * A RT Container can be in two states: STARTED or STOPPED. + * This function proceeds as follows: + * - It locks the container's mutex + * - If the container is not in state STOPPED, the function releases + * the mutex and returns without doing anything. + * - If instead the container is in state STOPPED, the function: + * 1. puts the container in state STARTED; + * 2. resets the Notification Counter + * 3. starts the Notification Procedure + * 4. starts the Activation Procedure + * 5. executes the Notification Procedure (this causes its initialization action + * to be performed) + * 6. executes the Activation Procedure (this causes its initialization action + * to be performed) + * 7. creates the container's Activation Thread (this also releases the thread); + * 8. release the mutex and returns + * . + * The attributes of the Activation Thread are NULL by default or are those + * set with function <code>::FwRtSetPosixAttr</code>. + * + * If any of the system calls made by this function returns an error, the + * container is put in an error state (see <code>::FwRtState_t</code>) and + * the error code is stored in the <code>errCode</code> field of the container + * descriptor. + * + * The Activation Thread is released upon creation and executes the following actions: + * <pre> + * while true do { + * lock container's mutex; + * wait until Notification Counter is greater than zero; + * decrement Notification Counter; + * release container's mutex; + * execute Activation Procedure; + * + * if (Activation Procedure has terminated) then { + * put RT Container in STOPPED state; + * execute Notification Procedure; + * break; + * } + * + * if (RT Container is in state STOPPED) then { + * execute Activation Procedure; + * execute Notification Procedure; + * break; + * } + * } + * </pre> + * Use of this function is subject to the following constraint: + * - The function may only be called before the Activation Thread has been created for + * the first time or after the Activation Thread has terminated execution (function + * <code>::FwRtWaitForTermination</code> can be used to wait for the Activation Thread + * to have terminated). + * . + * @param rtDesc the descriptor of the RT Container. + */ +void FwRtStart(FwRtDesc_t rtDesc); + +/** + * Stop a RT Container. + * A RT Container can be in two states: STARTED or STOPPED. + * This function proceeds as follows: + * - It locks the container's mutex. + * - If the container is not in state STARTED, the function releases + * the mutex and returns. + * - If instead the container is in state STARTED, the function: (a) puts + * the container in the STOPPED state; (b) sends a notification to + * the Activation Thread; and (c) releases the mutex. + * . + * If any of the system calls made by this function returns an error, the + * container is put in an error state (see <code>::FwRtState_t</code>) and + * the error code is stored in the <code>errCode</code> field of the container + * descriptor. + * @param rtDesc the descriptor of the RT Container. + */ +void FwRtStop(FwRtDesc_t rtDesc); + +/** + * Blocking function which returns when the Activation Thread has terminated. + * This function uses POSIX's <code>pthread_join</code> to wait until the + * Activation Thread has terminated. + * + * Use of this function is subject to the following constraints: + * - While this function is waiting on a given container, no other call to the + * function can be made on the same container. + * - Use of this function assumes that the thread in the argument container + * is joinable (this will normally be the case if the container's thread + * has been created with default attributes). + * . + * @param rtDesc the descriptor of the RT Container. + */ +void FwRtWaitForTermination(FwRtDesc_t rtDesc); + +/** + * Execute the Notification Procedure of a RT Container. + * This function proceeds as follows: + * - It locks the container mutex. + * - It executes the Notification Procedure + * - It releases the mutex + * . + * @param rtDesc the descriptor of the RT Container. + */ +void FwRtNotify(FwRtDesc_t rtDesc); + +/** + * Check whether the Notification Procedure is started. + * This function is not thread-safe (but note that it only returns the value of + * a field of the RT Container descriptor). + * @param rtDesc the descriptor of the RT Container. + * @return 1 if the Notification Procedure is started, 0 otherwise. + */ +FwRtBool_t FwRtIsNotifPrStarted(FwRtDesc_t rtDesc); + +/** + * Check whether the Activation Procedure is started. + * This function is not thread-safe (but note that it only returns the value of + * a field of the RT Container descriptor). + * @param rtDesc the descriptor of the RT Container. + * @return 1 if the Activation Procedure is started, 0 otherwise. + */ +FwRtBool_t FwRtIsActivPrStarted(FwRtDesc_t rtDesc); + +/** + * Return the RT Container state. + * This function is not thread-safe (but note that it only returns the value of + * a field of the RT Container descriptor). + * @param rtDesc the descriptor of the RT Container. + * @return the state of the RT Container. + */ +FwRtState_t FwRtGetContState(FwRtDesc_t rtDesc); + +/** + * Return the error code of the RT Container. + * This function is not thread-safe (but note that it only returns the value of + * a field of the RT Container descriptor). + * @param rtDesc the descriptor of the RT Container. + * @return the state of the RT Container. + */ +int FwRtGetErrCode(FwRtDesc_t rtDesc); + +/** + * Return the value of the notification counter. + * The value of the notification counter represents the number of pending notifications + * in the RT Container. + * This function is not thread-safe (but note that it only returns the value of + * a field of the RT Container descriptor). + * @param rtDesc the descriptor of the RT Container. + * @return the value of the notification counter. + */ +FwRtCounterU2_t FwRtGetNotifCounter(FwRtDesc_t rtDesc); + +#endif /* FWRT_CORE_H_ */ diff --git a/FwProfile/src/FwSmAux.c b/FwProfile/src/FwSmAux.c new file mode 100644 index 0000000000000000000000000000000000000000..ccf3a548cb3014d7e092e8d11dfdc65da0a99b38 --- /dev/null +++ b/FwProfile/src/FwSmAux.c @@ -0,0 +1,352 @@ +/** + * @file + * @ingroup smGroup + * Implements the auxiliary functions of the FW State Machine Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwSmAux.h" +#include "FwSmConfig.h" +#include "FwSmPrivate.h" + +/* ------------------------------------------------------------------------------- */ +void FwSmPrintConfig(FwSmDesc_t smDesc, FILE* stream) { + char prefix[1] = ""; + FwSmCounterS1_t actNOfPStates = 0; + FwSmCounterS1_t actNOfCStates = 0; + FwSmCounterS1_t actNOfTrans = 0; + FwSmCounterS1_t actNOfEsm = 0; + FwSmCounterS1_t actNOfActions = 0; + FwSmCounterS1_t actNOfGuards = 0; + FwSmCounterS1_t i, j, baseLoc; + SmTrans_t trans; + + if (smDesc == NULL) { + fprintf(stream, "%sThe argument state machine descriptor is NULL\n", prefix); + return; + } + + for (i = 0; i < smDesc->smBase->nOfPStates; i++) { + if (smDesc->smBase->pStates[i].outTransIndex != 0) { + actNOfPStates++; + } + } + + for (i = 0; i < smDesc->smBase->nOfCStates; i++) { + if (smDesc->smBase->cStates[i].outTransIndex != 0) { + actNOfCStates++; + } + } + + for (i = 0; i < smDesc->smBase->nOfTrans; i++) { + if (smDesc->smBase->trans[i].iTrAction != -1) { + actNOfTrans++; + } + } + + for (i = 0; i < smDesc->smBase->nOfPStates; i++) { + if (smDesc->esmDesc[i] != NULL) { + actNOfEsm++; + } + } + + for (i = 0; i < smDesc->nOfActions; i++) { + if (smDesc->smActions[i] != NULL) { + actNOfActions++; + } + } + + for (i = 0; i < smDesc->nOfGuards; i++) { + if (smDesc->smGuards[i] != NULL) { + actNOfGuards++; + } + } + + fprintf(stream, "\n"); + fprintf(stream, "%sSTATE MACHINE SIZE\n", prefix); + fprintf(stream, "%s------------------\n", prefix); + fprintf(stream, "%sDeclared number of states : %d\n", prefix, smDesc->smBase->nOfPStates); + fprintf(stream, "%sDeclared number of choice pseudo-states: %d\n", prefix, smDesc->smBase->nOfCStates); + fprintf(stream, "%sDeclared number of transitions : %d\n", prefix, smDesc->smBase->nOfTrans); + fprintf(stream, "%sDeclared number of actions : %d\n", prefix, smDesc->nOfActions - 1); + fprintf(stream, "%sDeclared number of guards : %d\n", prefix, smDesc->nOfGuards - 1); + fprintf(stream, "\n"); + + fprintf(stream, "%sSTATE MACHINE CONFIGURATION\n", prefix); + fprintf(stream, "%s---------------------------\n", prefix); + fprintf(stream, "%sThe error code is : %s\n", prefix, FwSmPrintErrCode(smDesc->errCode)); + fprintf(stream, "%sThe SM Execution Counter is : %u\n", prefix, smDesc->smExecCnt); + fprintf(stream, "%sThe State Execution Counter is : %u\n", prefix, smDesc->stateExecCnt); + fprintf(stream, "%sThe outcome of the configuration check is: %s\n", prefix, FwSmPrintErrCode(FwSmCheck(smDesc))); + fprintf(stream, "%sNumber of configured states : %d\n", prefix, actNOfPStates); + fprintf(stream, "%sNumber of configured choice pseudo-states: %d\n", prefix, actNOfCStates); + fprintf(stream, "%sNumber of configured transitions : %d\n", prefix, actNOfTrans); + fprintf(stream, "%sNumber of configured actions : %d\n", prefix, actNOfActions - 1); + fprintf(stream, "%sNumber of configured guards : %d\n", prefix, actNOfGuards - 1); + fprintf(stream, "%sNumber of embedded state machines : %d\n", prefix, actNOfEsm); + if (FwSmIsStarted(smDesc) == 0) { + fprintf(stream, "%sCurrent state machine state is : STOPPED\n", prefix); + } + else { + fprintf(stream, "%sState machine is STARTED and is in state : %d\n", prefix, FwSmGetCurState(smDesc)); + } + fprintf(stream, "\n"); + + fprintf(stream, "%sCONFIGURATION OF INITIAL PSEUDO STATE\n", prefix); + fprintf(stream, "%s-------------------------------------\n", prefix); + + if (smDesc->smBase->trans[0].iTrAction == -1) { + fprintf(stream, "%sThe transition from the initial pseudo-state is not defined\n", prefix); + } + else { + if (smDesc->smBase->trans[0].dest > 0) { + fprintf(stream, "%sThe transition from the initial pseudo state is to state n. %d\n", prefix, + smDesc->smBase->trans[0].dest); + } + else if (smDesc->smBase->trans[0].dest < 0) { + fprintf(stream, "%sThe transition from the initial pseudo state is to choice pseudo-state n. %d\n", prefix, + -smDesc->smBase->trans[0].dest); + } + else { + fprintf(stream, "%sThe transition from the initial pseudo state is to the final pseudo-state.\n", prefix); + } + + if (smDesc->smBase->trans[0].iTrAction != 0) { + fprintf(stream, "\tTransition Action is action n. %d\n", smDesc->smBase->trans[0].iTrAction); + } + else { + fprintf(stream, "\tNo Transition Action\n"); + } + + fprintf(stream, "\tNo Transition Guard\n"); + } + fprintf(stream, "\n"); + + if (smDesc->smBase->nOfPStates > 0) { + fprintf(stream, "%sCONFIGURATION OF STATES\n", prefix); + fprintf(stream, "%s-----------------------\n", prefix); + } + + for (i = 0; i < smDesc->smBase->nOfPStates; i++) { + if (smDesc->smBase->pStates[i].outTransIndex == 0) { + fprintf(stream, "%sState %d is not defined\n", prefix, i + 1); + } + else { + fprintf(stream, "%sState %d:\n", prefix, i + 1); + + if (smDesc->smBase->pStates[i].iEntryAction != 0) { + fprintf(stream, "\tEntry Action: action n. %d\n", smDesc->smBase->pStates[i].iEntryAction); + } + else { + fprintf(stream, "\tNo entry action\n"); + } + + if (smDesc->smBase->pStates[i].iDoAction != 0) { + fprintf(stream, "\tDo-Action: action n. %d\n", smDesc->smBase->pStates[i].iDoAction); + } + else { + fprintf(stream, "\tNo do-action\n"); + } + + if (smDesc->smBase->pStates[i].iExitAction != 0) { + fprintf(stream, "\tExit Action: action n. %d\n", smDesc->smBase->pStates[i].iExitAction); + } + else { + fprintf(stream, "\tNo exit action\n"); + } + + if (smDesc->esmDesc[i] == NULL) { + fprintf(stream, "\tNo state machine is embedded in this state\n"); + } + else { + fprintf(stream, "\tA state machine is embedded in this state\n"); + } + + baseLoc = smDesc->smBase->pStates[i].outTransIndex; + for (j = baseLoc; j < (baseLoc + smDesc->smBase->pStates[i].nOfOutTrans); j++) { + trans = smDesc->smBase->trans[j]; + if (trans.id == FW_TR_EXECUTE) { + if (trans.dest > 0) { + fprintf(stream, "\t'Execute' transition to state %d\n", trans.dest); + } + else if (trans.dest < 0) { + fprintf(stream, "\t'Execute' transition to choice pseudo-state %d\n", -trans.dest); + } + else { + fprintf(stream, "\t'Execute' transition to final pseudo-state\n"); + } + } + else { + if (trans.dest > 0) { + fprintf(stream, "\tTransition %d to state %d\n", trans.id, trans.dest); + } + else if (trans.dest < 0) { + fprintf(stream, "\tTransition %d to choice pseudo-state %d\n", trans.id, -trans.dest); + } + else { + fprintf(stream, "\tTransition %d to final pseudo-state\n", trans.id); + } + } + + if (trans.iTrAction != 0) { + fprintf(stream, "\t\tTransition Action is action n. %d\n", trans.iTrAction); + } + else { + fprintf(stream, "\t\tNo Transition Action\n"); + } + + if (trans.iTrGuard != 0) { + fprintf(stream, "\t\tTransition Guard is guard n. %d\n", trans.iTrGuard); + } + else { + fprintf(stream, "\t\tNo Transition Guard\n"); + } + } + } + } + fprintf(stream, "\n"); + + if (smDesc->smBase->nOfCStates > 0) { + fprintf(stream, "%sCONFIGURATION OF CHOICE PSEUDO-STATES\n", prefix); + fprintf(stream, "%s-------------------------------------\n", prefix); + } + + for (i = 0; i < smDesc->smBase->nOfCStates; i++) { + if (smDesc->smBase->cStates[i].outTransIndex == 0) { + fprintf(stream, "%sChoice Pseudo-State %d is not defined\n", prefix, i + 1); + } + else { + fprintf(stream, "%sChoice Pseudo-State %d:\n", prefix, i + 1); + + baseLoc = smDesc->smBase->cStates[i].outTransIndex; + for (j = baseLoc; j < (baseLoc + smDesc->smBase->cStates[i].nOfOutTrans); j++) { + if (smDesc->smBase->trans[j].dest > 0) { + fprintf(stream, "\tTransition to state %d\n", smDesc->smBase->trans[j].dest); + } + else if (smDesc->smBase->trans[j].dest < 0) { + fprintf(stream, "\tTransition to choice pseudo-state %d (this is an illegal transition)\n", + -smDesc->smBase->trans[j].dest); + } + else { + fprintf(stream, "\tTransition to final pseudo-state\n"); + } + + if (smDesc->smBase->trans[j].iTrAction != 0) { + fprintf(stream, "\t\tTransition Action: action n. %d\n", smDesc->smBase->trans[j].iTrAction); + } + else { + fprintf(stream, "\t\tNo Transition Action\n"); + } + + if (smDesc->smBase->trans[j].iTrGuard != 0) { + fprintf(stream, "\t\tTransition Guard: guard n. %d\n", smDesc->smBase->trans[j].iTrGuard); + } + else { + fprintf(stream, "\t\tNo Transition Guard\n"); + } + } + } + } +} + +/* ------------------------------------------------------------------------------- */ +void FwSmPrintConfigRec(FwSmDesc_t smDesc, FILE* stream) { + FwSmCounterS1_t i; + FwSmDesc_t embDesc; + + FwSmPrintConfig(smDesc, stream); + + for (i = 1; i <= smDesc->smBase->nOfPStates; ++i) { + embDesc = FwSmGetEmbSm(smDesc, i); + if (NULL != embDesc) { + FwSmPrintConfigRec(embDesc, stream); + } + } +} + +/* ------------------------------------------------------------------------------- */ +char* FwSmPrintErrCode(FwSmErrCode_t errCode) { + switch (errCode) { + case smSuccess: + return "success"; + case smOutOfMemory: + return "smOutOfMemory"; + case smNullPState: + return "smNullPState"; + case smNullCState: + return "smNullCState"; + case smNullTrans: + return "smNullTrans"; + case smConfigErr: + return "smConfigErr"; + case smIllStateId: + return "smIllStateId"; + case smIllChoiceId: + return "smIllChoiceId"; + case smStateIdInUse: + return "smStateIdInUse"; + case smChoiceIdInUse: + return "smChoiceIdInUse"; + case smUndefinedTransSrc: + return "smUndefinedTransSrc"; + case smIllegalPDest: + return "smIllegalPDest"; + case smIllegalCDest: + return "smIllegalCDest"; + case smIllNOfOutTrans: + return "smIllNOfOutTrans"; + case smIllTransSrc: + return "smIllTransSrc"; + case smTransErr: + return "smTransErr"; + case smTooManyTrans: + return "smTooManyTrans"; + case smTooManyOutTrans: + return "smTooManyOutTrans"; + case smTooManyActions: + return "smTooManyActions"; + case smTooManyGuards: + return "smTooManyGuards"; + case smTooFewActions: + return "smTooFewActions"; + case smTooFewGuards: + return "smTooFewGuards"; + case smNegOutTrans: + return "smNegOutTrans"; + case smUndefAction: + return "smUndefAction"; + case smUndefGuard: + return "smUndefGuard"; + case smNotDerivedSM: + return "smNotDerivedSM"; + case smEsmDefined: + return "smEsmDefined"; + case smWrongNOfActions: + return "smWrongNOfActions"; + case smWrongNOfGuards: + return "smWrongNOfGuards"; + default: + return "invalid error code"; + } +} diff --git a/FwProfile/src/FwSmAux.h b/FwProfile/src/FwSmAux.h new file mode 100644 index 0000000000000000000000000000000000000000..f279b95733cec6d0bb963d9d9b4a760280c4b3fb --- /dev/null +++ b/FwProfile/src/FwSmAux.h @@ -0,0 +1,99 @@ +/** + * @file + * @ingroup smGroup + * Declaration of the auxiliary interface for a FW State Machine. + * The auxiliary interface offers functions which support the + * development of an application which uses the FW State Machine + * but which are not expected to be used during normal operation. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWSM_AUX_H_ +#define FWSM_AUX_H_ + +#include "FwSmCore.h" +#include <stdio.h> + +/** + * Print the configuration of the state machine to an output stream. + * This function extracts all the configuration information from the + * argument state machine and prints it to the argument output stream. + * It is legal for the argument state machine to be only partly configured. + * It is also legal to call this function on a state machine which has + * already been started. + * + * The function describes the configuration of the argument state machine + * in terms of its states, choice pseudo-states, transitions, actions + * and guards. + * The following conventions are used to refer to these items: + * - The name of a state is its identifier. + * - The name of a choice pseudo-state is its identifier. + * - Transitions are identified by their source, destination, + * transition identifier, transition action and guard. + * - The name of an action is an integer in the range [1,N] where N is + * total number of actions declared for the state machine and the + * action with identifier 'i' is the i-th action to have been added + * to the state machine. + * - The name of a guard is an integer in the range [1,M] where M is + * total number of guards declared for the state machine and the + * guard with identifier 'i' is the i-th guard to have been added + * to the state machine. + * + * This function assumes the argument output stream to be open and + * to have enough space to receive the output generated by the function. + * The function neither closes nor flushes the output stream. + * Opening and closing of the output stream must thus be done by the caller. + * @param smDesc the descriptor of the state machine to be started. + * @param stream the output stream to which the configuration information is + * printed. + */ +void FwSmPrintConfig(FwSmDesc_t smDesc, FILE* stream); + +/** + * Print the configuration of the state machine and its embedded state machines + * to an output stream. + * This is a recursive version of <code>::FwSmPrintConfig</code> which operates + * on a state machine and, recursively, on all its embedded state machines. + * This function assumes the argument output stream to be open and + * to have enough space to receive the output generated by the function. + * The function neither closes nor flushes the output stream. + * Opening and closing of the output stream must thus be done by the caller. + * @param smDesc the descriptor of the state machine to be started. + * @param stream the output stream to which the configuration information is + * printed. + */ +void FwSmPrintConfigRec(FwSmDesc_t smDesc, FILE* stream); + +/** + * Print the name of a state machine error code. + * Error code are defined as instances of an enumerated type in + * <code>FwSmConstants.h</code>. + * This function translates an error code to a string holding the + * name of its enumerated value. + * @param errCode the error code + * @return the string holding the name of the error code + */ +char* FwSmPrintErrCode(FwSmErrCode_t errCode); + +#endif /* FWSM_AUX_H_ */ diff --git a/FwProfile/src/FwSmConfig.c b/FwProfile/src/FwSmConfig.c new file mode 100644 index 0000000000000000000000000000000000000000..25ce7674192c6965f0e90eb156736f26a65b7a45 --- /dev/null +++ b/FwProfile/src/FwSmConfig.c @@ -0,0 +1,529 @@ +/** + * @file + * @ingroup smGroup + * Implements the configuration functions for the FW State Machine Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwSmConfig.h" +#include "FwSmPrivate.h" +#include <stdlib.h> + +/** + * Create a transition (other than the transition from the initial pseudo-state) with the + * given characteristics and add it to state machine. + * The newly created transition is stored in the transition array at the first non-null location + * (in other words, the first transition to be added to the state machine is stored at location 0, + * the second transition is stored at location 1, etc). + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param transId the identifier of the trigger which is associated to the transition. This is an integer + * which is unique for the state machine and for all its embedded state machines. The zero identifier is + * reserved for the "execute" transition. + * @param srcId the identifier of the source of the transition. + * @param srcType the type of the source. + * @param destId the identifier of the destination of the transition. If the destination is a proper + * state, this argument has a positive value equal to the destination identifier. If the destination + * is a choice pseudo-state, this argument has a negative value equal to the opposite of the destination + * identifier. If the destination is the final pseudo-state, this argument has the value zero. + * @param trAction the transition action (or NULL if no action is associated to this transition). + * @param trGuard the transition guard (or NULL if no guard is associated to this transition). + */ +static void AddTrans(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, StateType_t srcType, + FwSmCounterS1_t destId, FwSmAction_t trAction, FwSmGuard_t trGuard); + +/** + * Add an action to the set of actions in the state machine descriptor. + * This function scans the array of actions in the state machine descriptor and + * can then have one of three outcomes: + * - if the argument action is equal to NULL, the function returns 0; + * - if the argument action is already present in the array of actions, the function + * returns the index of the location where the action is stored; + * - if the argument action is not present and the array of actions is not full, the + * function adds it at the first free location and returns the index of this + * location; + * - if the argument action is not present but the array of actions is already full, + * the function returns 0. + * @param smDesc descriptor of the state machine where the action is added + * @param action action to be added + * @return the location where the action is stored in the array or -1 if the + * action cannot be added because the array is already full + */ +static FwSmCounterS1_t AddAction(FwSmDesc_t smDesc, FwSmAction_t action); + +/** + * Add a guard to the set of guards in the state machine descriptor. + * This function scans the array of guards in the state machine descriptor and + * can then have one of three outcomes: + * - if the argument guard is equal to NULL, the function returns 0; + * - if the argument guard is already present in the array of guards, the function + * returns the index of the location where the guard is stored; + * - if the argument guard is not present and the array of guards is not full, the + * function adds it at the first free location and returns the index of this + * location; + * - if the argument guard is not present but the array of guards is already full, the + * function returns 0. + * @param smDesc descriptor of the state machine where the guard is added + * @param guard guard to be added + * @return the location where the guard is stored in the array or -1 if the + * guard cannot be added because the array is already full + */ +static FwSmCounterS1_t AddGuard(FwSmDesc_t smDesc, FwSmGuard_t guard); + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmSetData(FwSmDesc_t smDesc, void* smData) { + smDesc->smData = smData; +} + +void* FwSmGetData(FwSmDesc_t smDesc) { + return smDesc->smData; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddState(FwSmDesc_t smDesc, FwSmCounterS1_t stateId, FwSmCounterS1_t nOfOutTrans, FwSmAction_t entryAction, + FwSmAction_t exitAction, FwSmAction_t doAction, FwSmDesc_t esmDesc) { + + SmPState_t* pState; + SmBaseDesc_t* smBase = smDesc->smBase; + + if (stateId > smBase->nOfPStates) { + smDesc->errCode = smIllStateId; + return; + } + + if (stateId < 1) { + smDesc->errCode = smIllStateId; + return; + } + + if (smBase->pStates[stateId - 1].outTransIndex != 0) { + smDesc->errCode = smStateIdInUse; + return; + } + + if (nOfOutTrans < 0) { + smDesc->errCode = smNegOutTrans; + return; + } + + if (smDesc->transCnt + nOfOutTrans > smBase->nOfTrans) { + smDesc->errCode = smTooManyOutTrans; + return; + } + + /* Initialize newly added state */ + pState = &(smBase->pStates[stateId - 1]); + + pState->outTransIndex = smDesc->transCnt; + smDesc->transCnt = (FwSmCounterS1_t)(smDesc->transCnt + nOfOutTrans); + + pState->iDoAction = AddAction(smDesc, doAction); + pState->iEntryAction = AddAction(smDesc, entryAction); + pState->iExitAction = AddAction(smDesc, exitAction); + + smDesc->esmDesc[stateId - 1] = esmDesc; + pState->nOfOutTrans = nOfOutTrans; + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddChoicePseudoState(FwSmDesc_t smDesc, FwSmCounterS1_t choiceId, FwSmCounterS1_t nOfOutTrans) { + SmCState_t* cState; + SmBaseDesc_t* smBase = smDesc->smBase; + + if (choiceId > smBase->nOfCStates) { + smDesc->errCode = smIllChoiceId; + return; + } + + if (choiceId < 1) { + smDesc->errCode = smIllChoiceId; + return; + } + + if (smBase->cStates[choiceId - 1].outTransIndex != 0) { + smDesc->errCode = smChoiceIdInUse; + return; + } + + if (nOfOutTrans < 1) { + smDesc->errCode = smIllNOfOutTrans; + return; + } + + if (smDesc->transCnt + nOfOutTrans > smBase->nOfTrans) { + smDesc->errCode = smTooManyOutTrans; + return; + } + + /* Initialize newly added choice pseudo-state */ + cState = &(smBase->cStates[choiceId - 1]); + + cState->outTransIndex = smDesc->transCnt; + smDesc->transCnt = (FwSmCounterS1_t)(smDesc->transCnt + nOfOutTrans); + + cState->nOfOutTrans = nOfOutTrans; + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddTransIpsToSta(FwSmDesc_t smDesc, FwSmCounterS1_t destId, FwSmAction_t trAction) { + AddTrans(smDesc, 0, 0, stoppedState, destId, trAction, NULL); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddTransIpsToCps(FwSmDesc_t smDesc, FwSmCounterS1_t destId, FwSmAction_t trAction) { + AddTrans(smDesc, 0, 0, stoppedState, (FwSmCounterS1_t)(-destId), trAction, NULL); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddTransStaToSta(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, FwSmCounterS1_t destId, + FwSmAction_t trAction, FwSmGuard_t trGuard) { + AddTrans(smDesc, transId, srcId, properState, destId, trAction, trGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddTransStaToCps(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, FwSmCounterS1_t destId, + FwSmAction_t trAction, FwSmGuard_t trGuard) { + AddTrans(smDesc, transId, srcId, properState, (FwSmCounterS1_t)(-destId), trAction, trGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddTransCpsToSta(FwSmDesc_t smDesc, FwSmCounterS1_t srcId, FwSmCounterS1_t destId, FwSmAction_t trAction, + FwSmGuard_t trGuard) { + AddTrans(smDesc, 0, srcId, choicePseudoState, destId, trAction, trGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddTransStaToFps(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, FwSmAction_t trAction, + FwSmGuard_t trGuard) { + AddTrans(smDesc, transId, srcId, properState, 0, trAction, trGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmAddTransCpsToFps(FwSmDesc_t smDesc, FwSmCounterS1_t srcId, FwSmAction_t trAction, FwSmGuard_t trGuard) { + AddTrans(smDesc, 0, srcId, choicePseudoState, 0, trAction, trGuard); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static void AddTrans(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, StateType_t srcType, + FwSmCounterS1_t destId, FwSmAction_t trAction, FwSmGuard_t trGuard) { + + FwSmCounterS1_t i, baseLoc, nOfOutTrans; + FwSmCounterS1_t loc = -1; + SmTrans_t* trans; + SmBaseDesc_t* smBase = smDesc->smBase; + + /* check that the source state is legal and has been defined */ + if (srcType == properState) { + if (srcId > smBase->nOfPStates) { + smDesc->errCode = smIllTransSrc; + return; + } + if (smBase->pStates[srcId - 1].outTransIndex == 0) { + smDesc->errCode = smUndefinedTransSrc; + return; + } + if (smBase->pStates[srcId - 1].nOfOutTrans < 1) { + smDesc->errCode = smIllTransSrc; + return; + } + baseLoc = smBase->pStates[srcId - 1].outTransIndex; + nOfOutTrans = smBase->pStates[srcId - 1].nOfOutTrans; + } + else if (srcType == choicePseudoState) { + if (srcId > smBase->nOfCStates) { + smDesc->errCode = smIllTransSrc; + return; + } + if (smBase->cStates[srcId - 1].outTransIndex == 0) { + smDesc->errCode = smUndefinedTransSrc; + return; + } + baseLoc = smBase->cStates[srcId - 1].outTransIndex; + nOfOutTrans = smBase->cStates[srcId - 1].nOfOutTrans; + } + else { /* Source state is the stopped state */ + baseLoc = 0; + nOfOutTrans = 1; + } + + /* New transition will be stored in the transition array of the SM Descriptor at a location + * in the range [baseLoc, baseLoc+nOfOutTrans]. We check that this range of locations + * is not already full. + */ + if (smBase->trans[baseLoc + nOfOutTrans - 1].iTrAction != -1) { + smDesc->errCode = smTooManyTrans; + return; + } + + /* Identify location where newly added transition will be stored in the transition array. + * Note that the nOfOutTrans is guaranteed to be greater than zero by the way it is + * initialized in the previous statements in this function. Hence, the loop will be + * taken at least once. */ + for (i = 0; i < nOfOutTrans; i++) { + if (smBase->trans[baseLoc + i].iTrAction == -1) { + loc = (FwSmCounterS1_t)(baseLoc + i); + break; + } + } + trans = &(smBase->trans[loc]); + + /* Assign the transition identifier */ + trans->id = transId; + + /* Assign transition destination */ + trans->dest = destId; + + /* add transition action to transition descriptor */ + trans->iTrAction = AddAction(smDesc, trAction); + + /* add guard to transition descriptor */ + trans->iTrGuard = AddGuard(smDesc, trGuard); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static FwSmCounterS1_t AddAction(FwSmDesc_t smDesc, FwSmAction_t action) { + FwSmCounterS1_t i; + + if (action == NULL) { + return 0; + } + + for (i = 1; i < smDesc->nOfActions; i++) { + if (smDesc->smActions[i] == NULL) { + break; + } + if (action == smDesc->smActions[i]) { + return i; + } + } + + if (i < smDesc->nOfActions) { + smDesc->smActions[i] = action; + return i; + } + + smDesc->errCode = smTooManyActions; + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static FwSmCounterS1_t AddGuard(FwSmDesc_t smDesc, FwSmGuard_t guard) { + FwSmCounterS1_t i; + + if (guard == NULL) { + return 0; + } + + for (i = 1; i < smDesc->nOfGuards; i++) { + if (smDesc->smGuards[i] == NULL) { + break; + } + if (guard == smDesc->smGuards[i]) { + return i; + } + } + + if (i < smDesc->nOfGuards) { + smDesc->smGuards[i] = guard; + return i; + } + + smDesc->errCode = smTooManyGuards; + return 0; +} +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmErrCode_t FwSmCheck(FwSmDesc_t smDesc) { + + FwSmCounterS1_t i, j; + FwSmBool_t found; + SmBaseDesc_t* smBase = smDesc->smBase; + + /* Check that no error occurred during the configuration process */ + if (smDesc->errCode != smSuccess) { + return smConfigErr; + } + + /* Check that all proper states have been defined */ + for (i = 0; i < smBase->nOfPStates; i++) { + if (smBase->pStates[i].outTransIndex == 0) { + return smNullPState; + } + } + + /* Check that all choice pseudo-states have been defined */ + for (i = 0; i < smBase->nOfCStates; i++) { + if (smBase->cStates[i].outTransIndex == 0) { + return smNullCState; + } + } + + /* Check that all transitions have been defined */ + for (i = 0; i < smBase->nOfTrans; i++) { + if (smBase->trans[i].iTrAction == -1) { + return smNullTrans; + } + } + + /* Check that all transition destinations are legal states or choice pseudo-states */ + for (i = 0; i < smBase->nOfTrans; i++) { + if (smBase->trans[i].dest > smBase->nOfPStates) { + return smIllegalPDest; + } + if (smBase->trans[i].dest < -smBase->nOfCStates) { + return smIllegalCDest; + } + } + + /* Check that all actions have been defined */ + for (i = 0; i < smDesc->nOfActions; i++) { + if (smDesc->smActions[i] == NULL) { + return smTooFewActions; + } + } + + /* Check that all guards have been defined */ + for (i = 0; i < smDesc->nOfGuards; i++) { + if (smDesc->smGuards[i] == NULL) { + return smTooFewGuards; + } + } + + /* Check that all states are reachable */ + for (i = 1; i <= smBase->nOfPStates; i++) { + found = 0; + for (j = 0; j < smBase->nOfTrans; j++) { + if (smBase->trans[j].dest == i) { + found = 1; + break; + } + } + if (found == 0) { + return smUnreachablePState; + } + } + + /* Check that all choice pseudo-states are reachable */ + for (i = 1; i <= smBase->nOfCStates; i++) { + found = 0; + for (j = 0; j < smBase->nOfTrans; j++) { + if (smBase->trans[j].dest == -i) { + found = 1; + break; + } + } + if (found == 0) { + return smUnreachableCState; + } + } + + return smSuccess; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmErrCode_t FwSmCheckRec(FwSmDesc_t smDesc) { + FwSmErrCode_t outcome; + FwSmCounterS1_t i; + + /* Check all embedded state machines */ + for (i = 0; i < smDesc->smBase->nOfPStates; i++) { + if (smDesc->esmDesc[i] != NULL) { + outcome = FwSmCheckRec(smDesc->esmDesc[i]); + if (outcome != smSuccess) { + return outcome; + } + } + } + + return FwSmCheck(smDesc); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmOverrideAction(FwSmDesc_t smDesc, FwSmAction_t oldAction, FwSmAction_t newAction) { + FwSmCounterS1_t i; + + if (smDesc->transCnt != 0) { + smDesc->errCode = smNotDerivedSM; + return; + } + + for (i = 1; i < smDesc->nOfActions; i++) { + if (smDesc->smActions[i] == oldAction) { + smDesc->smActions[i] = newAction; + return; + } + } + + smDesc->errCode = smUndefAction; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmOverrideGuard(FwSmDesc_t smDesc, FwSmGuard_t oldGuard, FwSmGuard_t newGuard) { + FwSmCounterS1_t i; + + if (smDesc->transCnt != 0) { + smDesc->errCode = smNotDerivedSM; + return; + } + + for (i = 1; i < smDesc->nOfGuards; i++) { + if (smDesc->smGuards[i] == oldGuard) { + smDesc->smGuards[i] = newGuard; + return; + } + } + + smDesc->errCode = smUndefGuard; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmEmbed(FwSmDesc_t smDesc, FwSmCounterS1_t stateId, FwSmDesc_t esmDesc) { + + if (smDesc->transCnt != 0) { + smDesc->errCode = smNotDerivedSM; + return; + } + + if (stateId < 1) { + smDesc->errCode = smIllStateId; + return; + } + + if (stateId > smDesc->smBase->nOfPStates) { + smDesc->errCode = smIllStateId; + return; + } + + if (smDesc->esmDesc[stateId - 1] != NULL) { + smDesc->errCode = smEsmDefined; + return; + } + + smDesc->esmDesc[stateId - 1] = esmDesc; + return; +} diff --git a/FwProfile/src/FwSmConfig.h b/FwProfile/src/FwSmConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..dae01c579463c1832aba63d8603bb19defc8fbb0 --- /dev/null +++ b/FwProfile/src/FwSmConfig.h @@ -0,0 +1,546 @@ +/** + * @file + * @ingroup smGroup + * Declaration of the configuration interface for a FW State Machine. + * A FW State Machine is described by a state machine descriptor. + * The functions declared in this interface allow a state machine descriptor + * to be configured. + * During the configuration process, the states, the choice pseudo-states and + * the transitions of the state machine are defined. + * + * There are two types of state machines: newly created state machines + * (i.e. state machines which are created from scratch using <code>::FwSmCreate</code> + * or <code>#FW_SM_INST</code>) and derived state machines (i.e. state + * machines which are created by extending another state machine through calls + * to <code>::FwSmCreateDer</code> or <code>#FW_SM_INST_DER</code>). + * The functions declared in this header file can be used to configure both types + * of state machines. + * + * In the case of a newly created state machine, the mode of use of the + * functions in this header file is as follows: + * -# The states of the state machine are added to its descriptor with + * the <code>::FwSmAddState</code> function. + * -# The choice pseudo-states of the state machine are added to its + * descriptor with the <code>::FwSmAddChoicePseudoState</code> function. + * -# The transitions of the state machines are added to the state machine + * with the <code>FwSmAddFlow*</code> functions (there are several of these + * functions, one for each type of transition source and destination). + * -# The pointer to the state machine data in the state machine descriptor + * is set with the <code>::FwSmSetData</code> function. + * -# The consistency and completeness of the state machine configuration may + * be verified with function <code>::FwSmCheck</code> or + * <code>::FwSmCheckRec</code>. Use of this function is optional. + * . + * The only constraint on the order in which the above functions are called is + * that a transition from a state or choice pseudo-state can only be defined + * after the source state or choice pseudo-state has been defined. + * + * In the case of a derived state machine, the mode of use of the functions + * declared in this header file is as follows: + * -# An action (either a state or a transition action) can be overridden + * with the <code>::FwSmOverrideAction</code> function. + * -# A guard can be overridden with the <code>::FwSmOverrideGuard</code> function. + * -# A state machine can be embedded in the state of the derived state + * machine with the <code>::FwSmEmbed</code> function. + * -# The consistency and completeness of the configuration of the derived + * state machine may be verified with function <code>::FwSmCheck</code> or + * <code>::FwSmCheckRec</code>. Use of this function is optional. + * . + * There are no constraints on the order in which the above functions are + * called. + * + * Error handling is done as follows: + * - Errors are reported through error codes. The range of error codes is + * defined in header file <code>FwSmConstant.h</code>. The error code is + * stored in the state machine descriptor (see <code>::FwSmGetErrCode</code>). + * - If an illegal input value could cause a corruption of the internal data + * structures of a state machine descriptor, a check is performed on the + * input parameter value and the function is aborted if this is found to be + * illegal. + * - When a function takes a state machine descriptor as an argument, no + * check is performed that the argument is non-NULL and valid (e.g. if + * a configuration function is called with a NULL value for the state + * machine descriptor argument, this error is not handled and the call + * will probably result in a segmentation fault). + * . + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWSM_CONFIG_H_ +#define FWSM_CONFIG_H_ + +#include "FwSmCore.h" + +/** + * Set the pointer to the state machine data in the state machine descriptor. + * The state machine data are data which are manipulated by the state machine + * actions and guards. + * The state machine descriptor holds a pointer to the state machine data. + * This function allows this pointer to be defined. + * The exact type of the state machine data is defined by applications for each + * state machine. + * It is therefore unknown at the level of the FW State Machine Module. + * This function accordingly treats the pointer to the state machine data as a + * pointer to <code>void</code>. + * In most cases, the state machine data will take the form of a <code>struct</code> + * whose fields represents the inputs and outputs for the state machine actions + * and guards. + * + * The functions which implement the actions and guards access the state machine + * data as follows: + * - The functions implementing the actions and guards of a state machine + * take the state machine descriptor as an argument (because they must conform + * to the prototype defined by <code>::FwSmAction_t</code> and + * <code>::FwSmGuard_t</code>). + * - The functions implementing the actions and guards of a state machine + * use the <code>::FwSmGetData</code> function to retrieve the pointer to the + * state machine data. + * - The pointer returned by <code>::FwSmGetData</code> is defined as a pointer + * to <code>void</code> and will normally have to be cast to its true type. + * @param smDesc the descriptor of the state machine to which the data structure is attached. + * @param smData the pointer to the state machine data. + * A value of NULL is legal (but note that the default value of the pointer to the + * state machine data when the state machine is created is NULL). + */ +void FwSmSetData(FwSmDesc_t smDesc, void* smData); + +/** + * Get the pointer to the state machine data in the state machine descriptor. + * This function returns the pointer which was set with the + * <code>::FwSmSetData</code> function. + * This function is normally used by the functions implementing a state machine + * action or guard to access the state machine data. + * See the description of the <code>::FwSmSetData</code> function for more details. + * @param smDesc the descriptor of the state machine to which the data structure is attached. + * @return the pointer to the state machine data or NULL if no state machine data + * were defined for the state machine. + */ +void* FwSmGetData(FwSmDesc_t smDesc); + +/** + * Create a state with the given characteristics and add it to a state machine. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smIllStateId: illegal value of the state identifier + * - #smStateIdInUse: a state with this identifier has already been defined + * - #smNegOutTrans: the number of out-going transitions is negative + * - #smTooManyOutTrans: the state adds too many transitions + * - #smTooManyActions: the state adds too many actions + * . + * @param smDesc the state machine to which the state is added. + * @param stateId the identifier of the state to be added + * (an integer in the range [1,N] where N is the number of states in the state machine). + * @param nOfOutTrans the number of out-going transitions from the new state. This must be + * a non-negative integer. A negative value is illegal but will not be reported as an + * error by this function. + * @param entryAction the entry action for the new state (a function pointer) or NULL if no + * entry action is associated to this state. + * @param doAction the do action for the new state (a function pointer) or NULL if no + * do action is associated to this state. + * @param exitAction the exit action for the new state (a function pointer) or NULL if no + * exit action is associated to this state. + * @param esmDesc the descriptor of the state machine embedded in the new state or NULL + * if no state machine is embedded in the new state. + */ +void FwSmAddState(FwSmDesc_t smDesc, FwSmCounterS1_t stateId, FwSmCounterS1_t nOfOutTrans, FwSmAction_t entryAction, + FwSmAction_t exitAction, FwSmAction_t doAction, FwSmDesc_t esmDesc); + +/** + * Create a choice pseudo-state with the given characteristics and add it to a state machine. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smIllChoiceId: illegal identifier for the choice pseudo-state + * - #smChoiceIdInUse: a choice pseudo-state with this identifier has already been defined + * - #smIllNOfOutTrans: the number of out-going transitions is smaller than 1 + * - #smTooManyOutTrans: the choice pseudo-state adds too many out-going transitions + * . + * @param smDesc the descriptor of the state machine to which the choice pseudo-state is added. + * @param choiceId the identifier of the choice pseudo-state to be added (an integer + * in the range [1,N] where N is the number of choice pseudo-states). + * @param nOfOutTrans the number of outgoing transitions from the new state (a positive + * integer). + */ +void FwSmAddChoicePseudoState(FwSmDesc_t smDesc, FwSmCounterS1_t choiceId, FwSmCounterS1_t nOfOutTrans); + +/** + * Create a transition from the initial pseudo-state to a proper state and add it + * to a state machine. + * Transitions from the initial pseudo-state have no trigger and no guard. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smTooManyTrans: there is no space left in the transition array of the state machine + * descriptor for this transition + * - #smTooManyActions: there is no space left in the action array of the state machine + * for the transition action defined by this transition + * . + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param destId the identifier of the destination state of the transition (an integer in the + * range [1,N] where N is the number of states). + * @param trAction the transition action (a function pointer) or NULL if no action is associated + * to this transition. + */ +void FwSmAddTransIpsToSta(FwSmDesc_t smDesc, FwSmCounterS1_t destId, FwSmAction_t trAction); + +/** + * Create a transition from the initial pseudo-state to a choice pseudo-state and add + * it to a state machine. + * Transitions from the initial pseudo-state have no trigger and no guard. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smTooManyTrans: there is no space left in the transition array of the state machine + * descriptor for this transition + * - #smTooManyActions: there is no space left in the action array of the state machine + * for the transition action defined by this transition + * . + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param destId the identifier of the destination choice pseudo-state of the transition (an + * integer in the range [1,N] where N is the number of choice pseudo-states). + * @param trAction the transition action (a function pointer) or NULL if no action is associated + * to this transition. + */ +void FwSmAddTransIpsToCps(FwSmDesc_t smDesc, FwSmCounterS1_t destId, FwSmAction_t trAction); + +/** + * Create a transition from a proper state to a proper state and add it to a state machine. + * This function should only be performed after the source state of the transition has been added + * to the state state machine. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smIllTransSrc: the identifier of the source of this transition has an illegal value + * - #smUndefinedTransSrc: the source of this transition has not yet been added to the state machine + * - #smTooManyTrans: there is no space left in the transition array of the state machine + * descriptor for this transition + * - #smTooManyGuards: there is no space left in the guard array of the state machine + * descriptor for the guard defined by this transition + * - #smTooManyActions: there is no space left in the action array of the state machine + * for the transition action defined by this transition + * . + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param transId the identifier of the trigger which is associated to the transition. This is an integer + * which is unique for the state machine and for all its embedded state machines. The zero identifier is + * reserved for the "Execute" transition. + * @param srcId the identifier of the source state of the transition (an integer in the range + * [1,N] where N is the number of states). + * @param destId the identifier of the destination state of the transition. + * @param trAction the transition action (a function pointer) or NULL if no action is associated + * to this transition. + * @param trGuard the transition guard (a function pointer) or NULL if no guard is associated + * to this transition. + */ +void FwSmAddTransStaToSta(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, FwSmCounterS1_t destId, + FwSmAction_t trAction, FwSmGuard_t trGuard); + +/** + * Create a transition from a proper state to a choice pseudo-state and add it to a state machine. + * This function should only be performed after the source state of the transition has been added + * to the state state machine. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smIllTransSrc: the identifier of the source of this transition has an illegal value + * - #smUndefinedTransSrc: the source of this transition has not yet been added to the state machine + * - #smTooManyTrans: there is no space left in the transition array of the state machine + * descriptor for this transition + * - #smTooManyGuards: there is no space left in the guard array of the state machine + * descriptor for the guard defined by this transition + * - #smTooManyActions: there is no space left in the action array of the state machine + * for the transition action defined by this transition + * . + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param transId the identifier of the trigger which is associated to the transition. This is a + * non-negative integer but the value of zero is reserved for the "Execute" transition + * (see #FW_TR_EXECUTE). + * @param srcId the identifier of the source state of the transition (an integer in the range + * [1,N] where N is the number of states) + * @param destId the identifier of the destination choice pseudo-state of the transition (an integer + * in the range [1,M] where M is the number of choice pseudo-states) + * @param trAction the transition action (a function pointer) or NULL if no action is associated + * to this transition. + * @param trGuard the transition guard (a function pointer) or NULL if no guard is associated + * to this transition. + */ +void FwSmAddTransStaToCps(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, FwSmCounterS1_t destId, + FwSmAction_t trAction, FwSmGuard_t trGuard); + +/** + * Create a transition from a choice pseudo-state to a proper state and add it to a state machine. + * This function should only be performed after the source of the transition has been added + * to the state state machine. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smIllTransSrc: the identifier of the source of this transition has an illegal value + * - #smUndefinedTransSrc: the source of this transition has not yet been added to the state machine + * - #smTooManyTrans: there is no space left in the transition array of the state machine + * descriptor for this transition + * - #smTooManyGuards: there is no space left in the guard array of the state machine + * descriptor for the guard defined by this transition + * - #smTooManyActions: there is no space left in the action array of the state machine + * for the transition action defined by this transition + * . + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param srcId the identifier of the source choice pseudo-state of the transition (an integer + * in the range [1,N] where N is the number of choice pseudo-states). + * @param destId the identifier of the destination state of the transition (an integer in the range + * [1,N] where N is the number of states). + * @param trAction the transition action (a function pointer) or NULL if no action is associated + * to this transition. + * @param trGuard the transition guard (a function pointer) or NULL if no guard is associated + * to this transition. + */ +void FwSmAddTransCpsToSta(FwSmDesc_t smDesc, FwSmCounterS1_t srcId, FwSmCounterS1_t destId, FwSmAction_t trAction, + FwSmGuard_t trGuard); + +/** + * Create a transition from a proper state to the final pseudo-state and add it to a state machine. + * This function should only be performed after the source state of the transition has been added + * to the state state machine. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smIllTransSrc: the identifier of the source of this transition has an illegal value + * - #smUndefinedTransSrc: the source of this transition has not yet been added to the state machine + * - #smTooManyTrans: there is no space left in the transition array of the state machine + * descriptor for this transition + * - #smTooManyGuards: there is no space left in the guard array of the state machine + * descriptor for the guard defined by this transition + * - #smTooManyActions: there is no space left in the action array of the state machine + * for the transition action defined by this transition + * . + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param transId the identifier of the trigger which is associated to the transition. This is a + * non-negative integer but the value of zero is reserved for the "Execute" transition + * (see #FW_TR_EXECUTE). + * @param srcId the identifier of the source state of the transition (an integer in the range + * [1,N] where N is the number of states). + * @param trAction the transition action (a function pointer) or NULL if no action is associated + * to this transition. + * @param trGuard the transition guard (a function pointer) or NULL if no guard is associated + * to this transition. + */ +void FwSmAddTransStaToFps(FwSmDesc_t smDesc, FwSmCounterU2_t transId, FwSmCounterS1_t srcId, FwSmAction_t trAction, + FwSmGuard_t trGuard); + +/** + * Create a transition from a choice pseudo-state to the final pseudo-state and add it to a state machine. + * This function should only be performed after the source state of the transition has been added + * to the state state machine. + * Transitions from a choice pseudo-state have no trigger. + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smIllTransSrc: the identifier of the source of this transition has an illegal value + * - #smUndefinedTransSrc: the source of this transition has not yet been added to the state machine + * - #smTooManyTrans: there is no space left in the transition array of the state machine + * descriptor for this transition + * - #smTooManyGuards: there is no space left in the guard array of the state machine + * descriptor for the guard defined by this transition + * - #smTooManyActions: there is no space left in the action array of the state machine + * for the transition action defined by this transition + * . + * @param smDesc the descriptor of the state machine to which the transition is added. + * @param srcId the identifier of the source state of the transition (an integer in the range + * [1,N] where N is the number of states). + * @param trAction the transition action (a function pointer) or NULL if no action is associated + * to this transition. + * @param trGuard the transition guard (a function pointer) or NULL if no guard is associated + * to this transition + */ +void FwSmAddTransCpsToFps(FwSmDesc_t smDesc, FwSmCounterS1_t srcId, FwSmAction_t trAction, FwSmGuard_t trGuard); + +/** + * Check the correctness and completeness of the configuration of a state machine descriptor. + * This function may be called on a state machine descriptor after it has been created and + * configured. + * This function does not modify the configuration of the state machine. + * It checks the error conditions which may arise when an application configures a + * state machine using the configuration functions declared in this header file. + * More specifically, this function performs the following checks: + * -# Check that no configuration errors have occurred (i.e. check that the error code + * in the state machine descriptor is equal to: <code>::smSuccess</code>). + * -# Check that all states have been defined. + * -# Check that all choice pseudo-states have been defined. + * -# Check that all transitions have been defined. + * -# Check that the destinations of the transitions out of a state represent legal entities. + * -# Check that the destinations of the transitions out of a choice pseudo-state represent + * legal entities. + * -# Check that the number of actions declared when the state machine was created is the same + * as the number of actions defined during the state machine configuration process. + * -# Check that the number of guards declared when the state machine was created is the same + * as the number of guards defined during the state machine configuration process. + * -# Check that all states are reachable (i.e. they are at the end of at least one transition). + * -# Check that all choice pseudo-states are reachable (i.e. they are at the end of at least + * one transition). + * . + * Note that there are configuration errors which are not covered by this function because + * they cannot occur if the state machine is configured using the functions declared in + * this header file. + * Examples of this kind of errors include: + * - Defining a guard on a transition out of the initial pseudo-state; + * - Defining a transition which has a choice pseudo-state as both source and destination + * of the transition. + * . + * @param smDesc the descriptor of the state machine to be checked. + * @return the outcome of the check. The outcome of the check is one of the following: + * - #smSuccess: all checks have been passed. + * - #smConfigErr: check 1 has failed. + * - #smNullPState: check 2 has failed. + * - #smNullCState: check 3 has failed. + * - #smNullTrans: check 4 has failed. + * - #smIllegalPDest: check 5 has failed + * - #smIllegalCDest: check 6 has failed + * - #smTooFewActions: check 7 has failed + * - #smTooFewGuards: check 8 has failed + * - #smUnreachablePState: check 9 has failed + * - #smUnreachableCState: check 10 has failed + * . + * This function returns when it encounters the first error. Hence, the function return value + * is determined by the first error encountered by the function. + */ +FwSmErrCode_t FwSmCheck(FwSmDesc_t smDesc); + +/** + * Recursively check the configuration of a state machine and all its embedded state + * machines. + * This function performs the same checks as <code>::FwSmCheck</code> but the checks are + * also performed (recursively) on all the embedded state machines. + * The function returns the first error code it encounters while checking the + * outer state machine and its embedded state machine. + * Thus, the error reported by this function may have arisen either in the outer + * state machine or in one of its embedded state machines. + * @param smDesc the descriptor of the state machine to be checked. + * @return the outcome of the check (this is the same as for <code>::FwSmCheck</code>). + */ +FwSmErrCode_t FwSmCheckRec(FwSmDesc_t smDesc); + +/** + * Override an action (either a state action or a transition action) in a derived + * state machine. + * By default a derived state machine has the same actions as the base state machine + * from which it was derived. + * This function overrides one of the actions of the derived state machine. + * + * As an example consider the case of a base state machine B and suppose that action + * a1 is used as entry action of state S1 and as exit action of state S2. + * If an application creates a derived state machine D from B (for instance, through + * function <code>::FwSmCreateDer</code>), then, after creation, the entry action of + * state S1 and the exit action of state S2 in state machine D is still a1. + * This function can be used to change a1. + * Note that a single invocation of this function will change both the entry action + * of S1 and the exit action of S2. + * + * A call to this function on a state machine D has no effect on the actions of + * the state machines which are embedded in the states of D. + * + * If an attempt is made to override a non-existent action, an error is declared + * and the function returns without doing anything. + * + * The override mechanism is only available for derived state machines. + * If this function is called on a state machine which was not derived by extending + * some other state machine, an error is declared. + * + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smUndefAction: the action to be overridden does not exist + * - #smNotDerivedSM: the state machine is not a derived state machine + * . + * @param smDesc the descriptor of the derived state machine. + * @param oldAction the action to be overridden + * @param newAction the new action which overrides the old action + */ +void FwSmOverrideAction(FwSmDesc_t smDesc, FwSmAction_t oldAction, FwSmAction_t newAction); + +/** + * Override a guard in a derived state machine. + * By default a derived state machine has the same guards as the base state machine + * from which it was derived. + * This function overrides one of the guards of the derived state machine. + * + * As an example consider the case of a base state machine B and suppose that + * the transitions from state S1 to state S2 and the transition from state S3 to + * state S4 both have the same guard g1. + * If an application creates a derived state machine D from B (for instance, through + * function <code>::FwSmCreateDer</code>), then, after creation, the guard of the + * transition from S1 to S2 and from S3 to S4 is still g1. + * This function can be used to change g1. + * Note that a single invocation of this function will change the guard on both + * transitions. + * + * A call to this function on a state machine D has no effect on the guards of + * the state machines which are embedded in the states of D. + * + * If an attempt is made to override a non-existent guard, the function declares + * an error and returns. + * + * The override mechanism is only available for derived state machines. + * If this function is called on a state machine which was not derived by extending + * some other state machine, an error is declared. + * + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smUndefGuard: the guard to be overridden does not exist + * - #smNotDerivedSM: the state machine is not a derived state machine + * . + * @param smDesc the descriptor of the derived state machine. + * @param oldGuard the guard to be overridden + * @param newGuard the new guard which overrides the old guard + */ +void FwSmOverrideGuard(FwSmDesc_t smDesc, FwSmGuard_t oldGuard, FwSmGuard_t newGuard); + +/** + * Embed a state machine in a state of a derived state machine. + * By default a derived state machine has the same embedded state machines as + * the base state machine from which it was derived. + * This function allows a state machine to be embedded in one of the states + * of the derived state machine. + * A state machine can only be embedded in an "empty" state (i.e. a state which, + * in the base state machine, had no embedded state). + * + * As an example consider the case of a base state machine B and suppose that + * state S1 in this state machine has not embedded state machine. + * If an application creates a derived state machine D from B (for instance, through + * function <code>::FwSmCreateDer</code>), then, after creation, state S1 in the + * derived state machine has no embedded state machine. + * This function allows a state machine to be embedded in S1. + * + * If an attempt is made to embed a state machine in a non-empty state, the + * function returns with an error but does not modify in any way the state + * machine descriptor. + * + * The override mechanism is only available for derived state machines. + * If this function is called on a base state machine, an error is returned + * and the function returns without doing anything. + * + * This function reports the following errors in the error code of the state + * machine descriptor: + * - #smUndefGuard: the action to be overridden does not exist + * - #smIllStateId: the state identifier is illegal + * - #smNotDerivedSM: the state machine is a base state machine + * - #smEsmDefined: an embedded state machine is already defined for the target + * state + * . + * @param smDesc the descriptor of the derived state machine. + * @param stateId the identifier of the state where the state machine is to be + * embedded. + * @param esmDesc the descriptor of the state machine to be embedded. + */ +void FwSmEmbed(FwSmDesc_t smDesc, FwSmCounterS1_t stateId, FwSmDesc_t esmDesc); + +#endif /* FWSM_CONFIG_H_ */ diff --git a/FwProfile/src/FwSmConstants.h b/FwProfile/src/FwSmConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b171b3f27a86f16213f82066f0577a2244e480 --- /dev/null +++ b/FwProfile/src/FwSmConstants.h @@ -0,0 +1,245 @@ +/** + * @file + * @ingroup smGroup + * Header file to define all constants and types for the state machine + * module of the FW Profile. + * This header file should be included by all applications which use the + * state machine module of the FW Profile. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWSM_CONSTANTS_H_ +#define FWSM_CONSTANTS_H_ + +/** + * Forward declaration for the pointer to a state machine descriptor. + * A state machine descriptor is a data structure which holds all the information + * describing a state machine instance. + * Users only manipulate the pointer to the state machine descriptor. The internal + * definition of the state machine descriptor (see <code>FwSmPrivate.h</code>) is + * kept hidden from users. + */ +typedef struct FwSmDesc* FwSmDesc_t; + +/** + * Type for a pointer to a state machine action. + * A state machine action is a function which encapsulates one of the following: + * the entry action of a state, the exit action of a state, the do-action of a state, + * a transition action. + * A state machine action takes the descriptor of the state machine as an argument. + * + * Pointers to state machine actions are used when a new state machine is defined: + * all the actions in the state machine must be defined as functions which conform + * to the <code>FwSmAction_t</code> prototype and are loaded into the state machine + * as function pointers. + */ +typedef void (*FwSmAction_t)(FwSmDesc_t); + +/** Type used for booleans (0 is "false" and 1 is "true"). */ +typedef int FwSmBool_t; + +/** + * Type for a pointer to a state machine guard. + * A state machine guard is a function which encapsulates a transition guard in a + * state machine. + * The state machine guard takes the descriptor of the state machine as an argument + * and it returns 0 to signify that the guard is false or a non-zero value + * (typically 1) to signify that the guard is true. + * + * Pointers to state machine guards are used when a new state machine is defined: + * all the guards in the state machine must be defined as functions which conform + * to the <code>FwSmGuard_t</code> prototype and are loaded into the state machine + * as function pointers. + */ +typedef FwSmBool_t (*FwSmGuard_t)(FwSmDesc_t); + +/** Type used for unsigned counters with a "short" range. */ +typedef unsigned char FwSmCounterU1_t; + +/** Type used for unsigned counters with a "medium" range. */ +typedef unsigned short int FwSmCounterU2_t; + +/** Type used for unsigned counters with a "long" range. */ +typedef unsigned int FwSmCounterU3_t; + +/** Type used for unsigned counters with a "long int" range. */ +typedef long unsigned int FwSmCounterU4_t; + +/** Type used for signed counters with a "short" range. */ +typedef signed char FwSmCounterS1_t; + +/** Error codes and function return codes for the state machine functions. */ +typedef enum { + /** + * Return codes of a function which has completed execution without errors. + */ + smSuccess = 1, + /** + * A call to <code>malloc</code> has failed (it has returned a NULL pointer). + */ + smOutOfMemory = 2, + /** + * There is an undefined state in a state machine. + */ + smNullPState = 9, + /** + * There is an undefined choice pseudo-state in a state machine. + */ + smNullCState = 10, + /** + * There is an undefined transition in a state machine. + */ + smNullTrans = 11, + /** + * A configuration error has been detected during the state machine configuration process. + */ + smConfigErr = 16, + /** + * A state is added to a state machine with an illegal (out-of-range) identifier. + */ + smIllStateId = 22, + /** + * A choice pseudo-state is added to a state machine with an illegal (out-of-range) identifier. + */ + smIllChoiceId = 23, + /** + * A state is added twice to the same state machine. + */ + smStateIdInUse = 26, + /** + * A choice pseudo-state is added twice to the same state machine. + */ + smChoiceIdInUse = 27, + /** + * A transition is added to a state machine with a source (either a state or a + * choice pseudo-state) which has not yet been defined. + */ + smUndefinedTransSrc = 28, + /** + * A transition is added to a state machine with an illegal (out-of-range) state destination. + */ + smIllegalPDest = 29, + /** + * A transition is added to a state machine with an illegal (out-of-range) choice pseudo-state destination. + */ + smIllegalCDest = 30, + /** + * A choice pseudo-state is added to a state machine with less than 1 out-going transitions. + */ + smIllNOfOutTrans = 31, + /** + * A transition is added to a state machine with a source which has an illegal identifier. + */ + smIllTransSrc = 34, + /** + * An error was encountered while executing a transition in a state machine (see + * <code>::FwSmMakeTrans</code>). + */ + smTransErr = 35, + /** + * A transition from a certain source (either a state or a choice pseudo-state) is added + * to a state machine but there isn't space for it in the transition array of the + * state machine descriptor + * (because all the locations reserved for transitions from that source are already full). + * This error code is, for instance, generated if the same transition is added twice to + * the state machine or if an insufficient number of out-going transitions has been + * declared for a state or choice pseudo-state. + */ + smTooManyTrans = 36, + /** + * A state or choice pseudo-state is added to a state machine which has more + * out-going transitions than fit into the transition array of the state machine descriptor. + */ + smTooManyOutTrans = 37, + /** + * The number of actions added to the state machine exceeds the number of actions declared + * when the state machine descriptor was created. + */ + smTooManyActions = 38, + /** + * The number of guards added to the state machine exceeds the number of guards declared + * when the state machine descriptor was created. + */ + smTooManyGuards = 39, + /** + * The number of actions added to the state machine is smaller than the number of actions declared + * when the state machine descriptor was created. + */ + smTooFewActions = 40, + /** + * The number of guards added to the state machine is smaller than the number of guards declared + * when the state machine descriptor was created. + */ + smTooFewGuards = 41, + /** + * A state is added with a negative number of outgoing transitions. + */ + smNegOutTrans = 42, + /** + * The overridden action in a derived state machine does not exist. + */ + smUndefAction = 43, + /** + * The overridden guard in a derived state machine does not exist. + */ + smUndefGuard = 44, + /** + * The state in a derived state machine to which an embedded state machine is added + * already holds an embedded state machine. + */ + smEsmDefined = 45, + /** + * The state machine where an action or a guard is overridden or a state machine is embedded + * is not a derived state machine. + */ + smNotDerivedSM = 46, + /** + * The number of actions in the base state machine is not the same as in the derived + * state machine. + */ + smWrongNOfActions = 47, + /** + * The number of guards in the base state machine is not the same as in the derived + * state machine. + */ + smWrongNOfGuards = 48, + /** + * The state machine has a state which is not a destination of any transition + */ + smUnreachablePState = 49, + /** + * The state machine has a choice pseudo-state which is not a destination of any transition + */ + smUnreachableCState = 50 +} FwSmErrCode_t; + +/** + * Identifier of "Execute" transition in a state machine. + * Transition commands to a state machine are identified by a non-negative integer. + * The value of zero is reserved for the "Execute" transition and should not be used + * by applications. + */ +#define FW_TR_EXECUTE 0 + +#endif /* FWSM_CONSTANTS_H_ */ diff --git a/FwProfile/src/FwSmCore.c b/FwProfile/src/FwSmCore.c new file mode 100644 index 0000000000000000000000000000000000000000..d09a616547574ec8d0ade331a619226467b52e01 --- /dev/null +++ b/FwProfile/src/FwSmCore.c @@ -0,0 +1,271 @@ +/** + * @file + * @ingroup smGroup + * Implements the core functions of the FW State Machine Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwSmCore.h" +#include "FwSmPrivate.h" +#include <stdlib.h> + +/** + * Private helper function implementing the transition logic from the point where the + * transition action is executed to the end of the transition (see figure 4.3-3 of the + * FW Profile Definition Document). + * This operation may set the error code to #smTransErr if either of the following non-nominal + * situations occurs: + * - the transition encounters a choice pseudo-state which has no out-going transitions with a true + * guard; or + * - the transition encounters a transition which has a choice pseudo-state as both source and + * destination of the same transition. + * . + * In both the above cases, the state machine may remain in an inconsistent state. + * @param smDesc the descriptor of the state machine where the transition is executed + * @param trans the transition which is executed + */ +static void ExecTrans(FwSmDesc_t smDesc, SmTrans_t* trans); + +/* ----------------------------------------------------------------------------------------------------------------- */ +void SmDummyAction(FwSmDesc_t smDesc) { + (void)(smDesc); + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmBool_t SmDummyGuard(FwSmDesc_t smDesc) { + (void)(smDesc); + return 1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmStart(FwSmDesc_t smDesc) { + SmTrans_t* trans; + + if (smDesc->curState != 0) { /* Check if SM is already STARTED */ + return; + } + + /* Reset execution counters */ + smDesc->smExecCnt = 0; + smDesc->stateExecCnt = 0; + + /* Execution transition into initial state */ + trans = &(smDesc->smBase->trans[0]); + ExecTrans(smDesc, trans); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmStop(FwSmDesc_t smDesc) { + SmPState_t* pState; + SmBaseDesc_t* smBase = smDesc->smBase; + FwSmCounterS1_t iCurState = smDesc->curState; + + /* check if state machine (SM) is already stopped */ + if (iCurState == 0) { + return; + } + + pState = &(smBase->pStates[iCurState - 1]); /* get current state */ + /* If the current state (CS) has an embedded SM (ESM), stop it */ + if (smDesc->esmDesc[iCurState - 1] != NULL) { + FwSmStop(smDesc->esmDesc[iCurState - 1]); + } + /* execute exit action of current state */ + smDesc->smActions[pState->iExitAction](smDesc); + /* set state of SM to "undefined" */ + smDesc->curState = 0; + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmMakeTrans(FwSmDesc_t smDesc, FwSmCounterU2_t transId) { + SmPState_t* curState; + SmTrans_t* trans; + FwSmCounterS1_t i; + FwSmDesc_t esmDesc; + SmBaseDesc_t* smBase = smDesc->smBase; + + /* check if state machine (SM) is started */ + if (smDesc->curState == 0) { + return; + } + + /* get current state */ + curState = &(smBase->pStates[(smDesc->curState) - 1]); + + /* If this is the "execute" transition, increment execution counters and execute do-action */ + if (transId == FW_TR_EXECUTE) { + smDesc->smExecCnt++; + smDesc->stateExecCnt++; + smDesc->smActions[curState->iDoAction](smDesc); + } + + /* If there is an embedded SM (ESM), propagate transition trigger to it */ + esmDesc = smDesc->esmDesc[(smDesc->curState) - 1]; + if (esmDesc != NULL) { + FwSmMakeTrans(esmDesc, transId); + } + + /* look for transition from CS matching transition trigger */ + for (i = 0; i < curState->nOfOutTrans; i++) { + trans = &(smBase->trans[curState->outTransIndex + i]); + /* check if outgoing transition responds to trigger tr_id */ + if (trans->id == transId) { + /* check if outgoing transition has a true guard */ + if (smDesc->smGuards[trans->iTrGuard](smDesc) != 0) { + /* If CS has an ESM, stop it before exiting the CS */ + if (esmDesc != NULL) { + FwSmStop(esmDesc); + } + /* Execute exit action of CS */ + smDesc->smActions[curState->iExitAction](smDesc); + ExecTrans(smDesc, trans); + return; + } + } + } + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmExecute(FwSmDesc_t smDesc) { + FwSmMakeTrans(smDesc, FW_TR_EXECUTE); +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +static void ExecTrans(FwSmDesc_t smDesc, SmTrans_t* trans) { + SmPState_t* pDest; + SmCState_t* cDest; + SmTrans_t* cTrans; + FwSmCounterS1_t i; + FwSmDesc_t esmDesc; + SmBaseDesc_t* smBase = smDesc->smBase; + + /* execute transition action */ + smDesc->smActions[trans->iTrAction](smDesc); + + if (trans->dest > 0) { /* destination is a proper state */ + smDesc->curState = trans->dest; + smDesc->stateExecCnt = 0; + pDest = &(smBase->pStates[(trans->dest) - 1]); + /* execute entry action of destination state */ + smDesc->smActions[pDest->iEntryAction](smDesc); + esmDesc = smDesc->esmDesc[(trans->dest) - 1]; + if (esmDesc != NULL) { + FwSmStart(esmDesc); + } + return; + } + + if (trans->dest < 0) { /* destination is a choice pseudo-state */ + cDest = &(smBase->cStates[-(trans->dest) - 1]); + for (i = 0; i < cDest->nOfOutTrans; i++) { + cTrans = &(smBase->trans[cDest->outTransIndex + i]); + if (smDesc->smGuards[cTrans->iTrGuard](smDesc) != 0) { + /* Execute transition from choice pseudo-state */ + smDesc->smActions[cTrans->iTrAction](smDesc); + if (cTrans->dest > 0) { /* destination is a proper state */ + smDesc->curState = cTrans->dest; + smDesc->stateExecCnt = 0; + pDest = &(smBase->pStates[(cTrans->dest) - 1]); + /* execute entry action of destination state */ + smDesc->smActions[pDest->iEntryAction](smDesc); + esmDesc = smDesc->esmDesc[(cTrans->dest) - 1]; + if (esmDesc != NULL) { + FwSmStart(esmDesc); + } + return; + } + + if (cTrans->dest == 0) { /* destination is a final state */ + smDesc->curState = 0; + return; + } + + break; /* this point is reached only if there is a transition from a CPS to a CPS */ + } + } + smDesc->errCode = smTransErr; + } + else { /* destination is a final pseudo-state */ + smDesc->curState = 0; + return; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t FwSmGetEmbSmCur(FwSmDesc_t smDesc) { + if (smDesc->curState > 0) { + return smDesc->esmDesc[(smDesc->curState) - 1]; + } + + return NULL; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t FwSmGetEmbSm(FwSmDesc_t smDesc, FwSmCounterS1_t i) { + return smDesc->esmDesc[i - 1]; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmCounterS1_t FwSmGetCurState(FwSmDesc_t smDesc) { + return smDesc->curState; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmCounterS1_t FwSmGetCurStateEmb(FwSmDesc_t smDesc) { + if (smDesc->curState == 0) { + return -1; + } + + if (smDesc->esmDesc[(smDesc->curState) - 1] != NULL) { + return smDesc->esmDesc[(smDesc->curState) - 1]->curState; + } + + return -1; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmBool_t FwSmIsStarted(FwSmDesc_t smDesc) { + if (smDesc->curState != 0) { + return 1; + } + return 0; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmErrCode_t FwSmGetErrCode(FwSmDesc_t smDesc) { + return smDesc->errCode; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmCounterU3_t FwSmGetExecCnt(FwSmDesc_t smDesc) { + return smDesc->smExecCnt; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmCounterU3_t FwSmGetStateExecCnt(FwSmDesc_t smDesc) { + return smDesc->stateExecCnt; +} diff --git a/FwProfile/src/FwSmCore.h b/FwProfile/src/FwSmCore.h new file mode 100644 index 0000000000000000000000000000000000000000..09f97b98488c7968f4a813a1ef7d398d5814aa19 --- /dev/null +++ b/FwProfile/src/FwSmCore.h @@ -0,0 +1,226 @@ +/** + * @file + * @ingroup smGroup + * Declaration of the execution interface for a FW State Machine. + * The execution interface offers the functions to start and stop + * a state machine and to command a transition to a state machine. + * The functions declared in this header file, take a state machine descriptor + * as their first argument. + * This represents the state machine upon which the functions operate. + * + * The functions declared in this header file can only be used after a + * state machine has been fully configured. + * This is normally done using the configuration functions declared + * in <code>FwSmConfig.h</code>. + * The basic mode of use of the functions declared in this file is as follows: + * -# The state machine is started with function <code>::FwSmStart</code>. + * -# Transitions in the state machine are commanded with functions + * <code>::FwSmExecute</code> or <code>::FwSmMakeTrans</code>. + * -# The state machine is stopped with function <code>::FwSmStop</code>. + * . + * + * The functions declared in this header file assume that they are passed + * a valid state machine descriptor representing a correctly configured + * state machine. + * Failure to comply with this assumption will result in undefined + * behaviour. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWSM_CORE_H_ +#define FWSM_CORE_H_ + +#include "FwSmConstants.h" + +/** + * Start a state machine. The semantics of this operation is defined by the activity + * diagram on the left-hand side of the following figure + * (this is figure 4.3-1 in the "FW Profile Definition Document"): + * @image html SM_StartStop.png + * This function executes a transition from the initial pseudo-state to some state. + * It can set the error code to #smTransErr if either of the following non-nominal + * situations occurs while performing the transition: + * - the transition encounters a choice pseudo-state which has no out-going transitions + * with a true guard; or + * - the transition encounters a transition which has a choice pseudo-state as both source + * and destination of the same transition. + * . + * @param smDesc the descriptor of the state machine to be started. + */ +void FwSmStart(FwSmDesc_t smDesc); + +/** + * Stop a state machine. The semantics of this operation is defined by the activity + * diagram on the right-hand side of the following figure + * (this is figure 4.3-1 in the "FW Profile Definition Document"): + * @image html SM_StartStop.png + * @param smDesc the descriptor of the state machine to be started. + */ +void FwSmStop(FwSmDesc_t smDesc); + +/** + * Trigger a transition in a state machine. The semantics of this function is defined + * by the following activity diagram (this is taken from figure 4.3-2 in the "FW Profile + * Definition Document"): + * @image html SM_CmdProcessing.png + * The logic to execute a transition is implemented by the following activity + * diagram (this is taken from figure 4.3-3 in the "FW Profile + * Definition Document"): + * @image html SM_TransitionExecution.png + * This operation is recursive because a transition request is propagated to the + * embedded state machine of the source state. The maximum depth of recursion is the + * maximum depth of nesting of embedded state machines. + * + * If there are two transitions out of the current state which are both activated by + * this operation, the transition that will actually be taken is the one which was + * added first to the state machine (i.e. transitions are evaluated in the order in + * which they were added to the state machine). + * + * Similarly, if the transition goes through a choice pseudo-state (CPS) and if + * there are two transitions out of the CPS which have guards which evaluate to true, + * the transition to be taken is the one which was added first to the state machine. + * + * The FW Profile stipulates that at least one of the transitions out of a CPS + * must have a guard evaluating to true. This constraint is not enforced by the + * State Machine Module. If the constraint is violated, the error code is set to + * #smTransErr. + * + * This operation sets the error code to #smTransErr if either of the following non-nominal + * situations occurs: + * - the transition encounters a choice pseudo-state which has no out-going transitions + * with a true guard; or + * - the transition encounters a transition which has a choice pseudo-state as both source + * and destination of the same transition. + * . + * In both the above cases, the state machine may remain in an inconsistent state. + * @param smDesc the descriptor of the state machine where the transition is triggered. + * @param transId the identifier of the transition trigger. + */ +void FwSmMakeTrans(FwSmDesc_t smDesc, FwSmCounterU2_t transId); + +/** + * Convenience method to execute a state machine. Executing a state machine is equivalent + * to sending it the "Execute" transition command with function + * <code>::FwSmMakeTrans</code>. + * The identifier of the "Execute" transition command is stored in #FW_TR_EXECUTE. + * @param smDesc the descriptor of the state machine which is executed. + */ +void FwSmExecute(FwSmDesc_t smDesc); + +/** + * Return the state machine embedded in the current state. + * @param smDesc the descriptor of the state machine. + * @return the descriptor of the state machine embedded in the current state + * or NULL if there is no embedded state machine. + */ +FwSmDesc_t FwSmGetEmbSmCur(FwSmDesc_t smDesc); + +/** + * Return the state machine embedded in the i-th state of the argument + * state machine. + * No check is made on the legality of the value of argument 'i'. + * If this does not correspond to an existing state in the argument state + * machine, the behaviour of this function is undefined. + * @param smDesc the descriptor of the state machine. + * @param i the identifier of the state whose embedded state machine is + * returned + * @return the descriptor of the state machine embedded in the i-th state + * or NULL if there is no embedded state machine in the i-th state . + */ +FwSmDesc_t FwSmGetEmbSm(FwSmDesc_t smDesc, FwSmCounterS1_t i); + +/** + * Return the identifier of the current state in a state machine (or zero + * if the state machine is stopped). + * @param smDesc the descriptor of the state machine. + * @return the identifier of the current state of the state machine (or zero + * if the state machine is stopped). + */ +FwSmCounterS1_t FwSmGetCurState(FwSmDesc_t smDesc); + +/** + * Return the identifier of the current state of the state machine + * embedded in the current state (the sub-state). + * If the current state is S and if there is a state machine embedded in this + * state, then this function returns the current state of the embedded + * state machine. + * More precisely, this function implements the following logic: + * - If the outer state machine is stopped, then the function returns -1. + * - If the current state of the outer state machine has an embedded + * state machine, then this function returns the current state of the + * embedded state machine (or zero if the embedded state machine is + * stopped). + * - If the current state of the outer state machine has no embedded state + * machine, then this function returns -1. + * . + * @param smDesc the descriptor of the state machine. + * @return the identifier of the current state of the embedded state machine + * (or zero if the embedded state machine is stopped, or -1 if the current + * state has no embedded state machine). + */ +FwSmCounterS1_t FwSmGetCurStateEmb(FwSmDesc_t smDesc); + +/** + * Check whether the state machine is started. + * @param smDesc the descriptor of the state machine. + * @return 1 if the state machine is STARTED or 0 if it is STOPPED. + */ +FwSmBool_t FwSmIsStarted(FwSmDesc_t smDesc); + +/** + * Return the error code of the argument state machine. + * The error code of a state machine holds either <code>#smSuccess</code> if the state + * machine never encountered an error or else it holds the code of the last error + * encountered by the state machine. + * If the error code is different from <code>#smSuccess</code>, the behaviour of + * the state machine is undefined. + * @param smDesc the descriptor of the state machine to be checked. + * @return either <code>#smSuccess</code> or the code of the last error encountered + * by the state machine. + */ +FwSmErrCode_t FwSmGetErrCode(FwSmDesc_t smDesc); + +/** + * Return the State Machine Execution Counter. + * The State Machine Execution Counter holds the number of execution cycles since + * the state machine was started. + * Note that the State Machine Execution Counter is not reset when the state + * machine is stopped (it is only reset when it is started). + * @param smDesc the descriptor of the state machine. + * @return the value of the State Machine Execution Counter. + */ +FwSmCounterU3_t FwSmGetExecCnt(FwSmDesc_t smDesc); + +/** + * Return the State Execution Counter. + * The State Execution Counter holds the number of execution cycles since + * the current state was entered. + * Note that the State Execution Counter is not reset when the state machine + * is stopped (it is only reset when the state machine is started). + * @param smDesc the descriptor of the state machine. + * @return the value of the Node Execution Counter. + */ +FwSmCounterU3_t FwSmGetStateExecCnt(FwSmDesc_t smDesc); + +#endif /* FWSM_CORE_H_ */ diff --git a/FwProfile/src/FwSmDCreate.c b/FwProfile/src/FwSmDCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..8ad42de7a5020114e7ceda1916e18f1a3178553a --- /dev/null +++ b/FwProfile/src/FwSmDCreate.c @@ -0,0 +1,264 @@ +/** + * @file + * @ingroup smGroup + * Implements the dynamical creation functions for the FW State Machine Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwSmDCreate.h" +#include "FwSmPrivate.h" +#include <stdlib.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t FwSmCreate(FwSmCounterS1_t nOfStates, FwSmCounterS1_t nOfChoicePseudoStates, FwSmCounterS1_t nOfTrans, + FwSmCounterS1_t nOfActions, FwSmCounterS1_t nOfGuards) { + + FwSmCounterS1_t i; + SmBaseDesc_t* smBase; + FwSmDesc_t smDesc; + + if (nOfTrans < 1) { + return NULL; + } + + if (nOfStates < 0) { + return NULL; + } + + if (nOfChoicePseudoStates < 0) { + return NULL; + } + + if (nOfActions < 0) { + return NULL; + } + + if (nOfGuards < 0) { + return NULL; + } + + smDesc = (FwSmDesc_t)malloc(sizeof(struct FwSmDesc)); + if (smDesc == NULL) { + return NULL; + } + + smBase = (SmBaseDesc_t*)malloc(sizeof(SmBaseDesc_t)); + if (smBase == NULL) { + return NULL; + } + + if (nOfStates > 0) { + smBase->pStates = (SmPState_t*)malloc(((FwSmCounterU4_t)(nOfStates)) * sizeof(SmPState_t)); + if (smBase->pStates == NULL) { + return NULL; + } + for (i = 0; i < nOfStates; i++) { + smBase->pStates[i].outTransIndex = 0; + } + smDesc->esmDesc = (struct FwSmDesc**)malloc(((FwSmCounterU4_t)(nOfStates)) * sizeof(FwSmDesc_t)); + if (smDesc->esmDesc == NULL) { + return NULL; + } + for (i = 0; i < nOfStates; i++) { + smDesc->esmDesc[i] = NULL; + } + } + else { + smBase->pStates = NULL; + smDesc->esmDesc = NULL; + } + + if (nOfChoicePseudoStates > 0) { + smBase->cStates = (SmCState_t*)malloc(((FwSmCounterU4_t)(nOfChoicePseudoStates)) * sizeof(SmCState_t)); + if (smBase->cStates == NULL) { + return NULL; + } + for (i = 0; i < nOfChoicePseudoStates; i++) { + smBase->cStates[i].outTransIndex = 0; + } + } + else { + smBase->cStates = NULL; + } + + smBase->trans = (SmTrans_t*)malloc(((FwSmCounterU4_t)(nOfTrans)) * sizeof(SmTrans_t)); + if (smBase->trans == NULL) { + return NULL; + } + for (i = 0; i < nOfTrans; i++) { + smBase->trans[i].iTrAction = -1; + } + + smDesc->smActions = (FwSmAction_t*)malloc(((FwSmCounterU4_t)(nOfActions + 1)) * sizeof(FwSmAction_t)); + if (smDesc->smActions == NULL) { + return NULL; + } + smDesc->smActions[0] = &SmDummyAction; + for (i = 1; i <= nOfActions; i++) { + smDesc->smActions[i] = NULL; + } + + smDesc->smGuards = (FwSmGuard_t*)malloc(((FwSmCounterU4_t)(nOfGuards + 1)) * sizeof(FwSmGuard_t)); + if (smDesc->smGuards == NULL) { + return NULL; + } + smDesc->smGuards[0] = &SmDummyGuard; + for (i = 1; i <= nOfGuards; i++) { + smDesc->smGuards[i] = NULL; + } + + smBase->nOfCStates = nOfChoicePseudoStates; + smBase->nOfPStates = nOfStates; + smBase->nOfTrans = nOfTrans; + smDesc->smBase = smBase; + smDesc->curState = 0; + smDesc->smData = NULL; + smDesc->transCnt = 1; + smDesc->nOfActions = (FwSmCounterS1_t)(nOfActions + 1); + smDesc->nOfGuards = (FwSmCounterS1_t)(nOfGuards + 1); + smDesc->smExecCnt = 0; + smDesc->stateExecCnt = 0; + smDesc->errCode = smSuccess; + + return smDesc; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +FwSmDesc_t FwSmCreateDer(FwSmDesc_t smDesc) { + FwSmCounterS1_t i; + SmBaseDesc_t* smBase = smDesc->smBase; + FwSmDesc_t extSmDesc; + + /* Create descriptor for derived SM */ + extSmDesc = (FwSmDesc_t)malloc(sizeof(struct FwSmDesc)); + if (extSmDesc == NULL) { + return NULL; + } + + /* Create array of embedded state machines in the derived SM */ + if (smBase->nOfPStates > 0) { + extSmDesc->esmDesc = (struct FwSmDesc**)malloc(((FwSmCounterU4_t)(smBase->nOfPStates)) * sizeof(FwSmDesc_t)); + if (extSmDesc->esmDesc == NULL) { + return NULL; + } + } + else { + extSmDesc->esmDesc = NULL; + } + + /* Create array of actions in the derived SM */ + extSmDesc->smActions = (FwSmAction_t*)malloc(((FwSmCounterU4_t)(smDesc->nOfActions)) * sizeof(FwSmAction_t)); + if (extSmDesc->smActions == NULL) { + return NULL; + } + for (i = 0; i < smDesc->nOfActions; i++) { + extSmDesc->smActions[i] = smDesc->smActions[i]; + } + + /* Create array of guards in the derived SM */ + extSmDesc->smGuards = (FwSmGuard_t*)malloc(((FwSmCounterU4_t)(smDesc->nOfGuards)) * sizeof(FwSmGuard_t)); + if (extSmDesc->smGuards == NULL) { + return NULL; + } + for (i = 0; i < smDesc->nOfGuards; i++) { + extSmDesc->smGuards[i] = smDesc->smGuards[i]; + } + + /* Create embedded state machines */ + for (i = 0; i < smBase->nOfPStates; i++) { + if (smDesc->esmDesc[i] != NULL) { + extSmDesc->esmDesc[i] = FwSmCreateDer(smDesc->esmDesc[i]); + } + else { + extSmDesc->esmDesc[i] = NULL; + } + } + + extSmDesc->smBase = smBase; + extSmDesc->curState = 0; + extSmDesc->smData = NULL; + extSmDesc->transCnt = 0; + extSmDesc->nOfActions = smDesc->nOfActions; + extSmDesc->nOfGuards = smDesc->nOfGuards; + extSmDesc->errCode = smDesc->errCode; + extSmDesc->smExecCnt = 0; + extSmDesc->stateExecCnt = 0; + + return extSmDesc; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmRelease(FwSmDesc_t smDesc) { + SmBaseDesc_t* smBase; + + /* Release memory allocated to base descriptor */ + smBase = smDesc->smBase; + free(smBase->pStates); + free(smBase->cStates); + + /* Release pointer to transition array (note that the transition array is guaranteed to exist and to + * have at least one element, see operation FwSmCreate) */ + free(smBase->trans); + + /* Release memory allocated to base descriptor */ + free(smDesc->smBase); + + /* Release memory allocated to extension part of the state machine descriptor */ + FwSmReleaseDer(smDesc); + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmReleaseDer(FwSmDesc_t smDesc) { + + /* Release pointer to the action and guard arrays (note that both arrays are guaranteed to + * have non-zero length) */ + free(smDesc->smActions); + free(smDesc->smGuards); + free(smDesc->esmDesc); + + /* Release pointer to state machine descriptor */ + free(smDesc); + smDesc = NULL; + + return; +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmReleaseRec(FwSmDesc_t smDesc) { + FwSmCounterS1_t i; + + /* Release memory used by the embedded state machines */ + for (i = 0; i < smDesc->smBase->nOfPStates; i++) { + if (smDesc->esmDesc[i] != NULL) { + FwSmReleaseRec(smDesc->esmDesc[i]); + } + } + + /* Release memory used by the embedding state machine */ + FwSmRelease(smDesc); + + return; +} diff --git a/FwProfile/src/FwSmDCreate.h b/FwProfile/src/FwSmDCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..a9594589b9a15f42d08a1e3f8451c3a0e0f0c878 --- /dev/null +++ b/FwProfile/src/FwSmDCreate.h @@ -0,0 +1,235 @@ +/** + * @file + * @ingroup smGroup + * Declaration of the dynamical creation interface for a FW State Machine. + * A FW State Machine is described by a state machine descriptor. + * This interface declares the functions required to create and release + * a state machine descriptor dynamically. + * Dynamic creation and release of memory is done through calls to + * <code>malloc</code> and <code>free</code>. + * + * A state machine can be created in two ways: + * - It can be created from scratch, or + * - It can be created by extending an existing state machine. + * . + * The functions offered by this interface cover both creation of a new + * state machine descriptor from scratch (<code>::FwSmCreate</code>) and + * the extension of an existing state machine descriptor to create the + * descriptor for a derived state machine (<code>::FwSmCreateDer</code>). + * + * Both the creation and the extension functions create a new state machine + * descriptor and return a pointer to the newly created descriptor instance. + * The state machine descriptor returned by these functions is initialized + * (i.e. all its attributes have a well-defined value) but will normally + * need to be configured. + * Configuration can be done using the functions offered by the + * <code>FwSmConfig.h</code> file. + * + * The creation and the extension functions in this header file always check the + * success of calls to <code>malloc</code>. + * In case of failure, the caller aborts and returns a NULL pointer. + * + * Applications which do not wish to use dynamic memory allocation can + * create a state machine descriptor statically using the services offered + * by <code>FwSmSCreate.h</code>. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWSM_DCREATE_H_ +#define FWSM_DCREATE_H_ + +#include "FwSmCore.h" + +/** + * Create a new state machine descriptor. + * This function creates the state machine descriptor and its internal data structures + * dynamically through calls to <code>malloc</code>. + * If any of these calls fails, the function aborts and returns NULL. + * In this case, there may be a memory leak if part of the state machine descriptor memory + * had been allocated before the function was aborted. + * + * It is legal to create a state machine descriptor with no states or with no choice + * pseudo-states but it is not legal to create a state machine descriptor with no + * transitions. + * If the latter is attempted, the function is aborted and returns NULL. + * @param nOfStates the number of states in the new state machine (a non-negative number). + * @param nOfChoicePseudoStates the number of choice pseudo-states in the new state machine + * (a non-negative integer). + * @param nOfTrans the number of transitions in the new state machine (a + * positive integer). + * @param nOfActions the total number of actions (state actions + transition actions) which the + * user wishes to define for the state machine. + * The total number of actions must be a non-negative integer. + * If the same action appears more than once in a state machine, it is counted only once. + * @param nOfGuards the total number of transition guards which the + * user wishes to define for the state machine. + * The total number of guards must be a non-negative integer. + * If the same guard appears more than once in a state machine, it is counted only once. + * @return the descriptor of the new state machine (or NULL if creation of the + * data structures to hold the state machine descriptor failed or one of the + * function parameters had an illegal value). + */ +FwSmDesc_t FwSmCreate(FwSmCounterS1_t nOfStates, FwSmCounterS1_t nOfChoicePseudoStates, FwSmCounterS1_t nOfTrans, + FwSmCounterS1_t nOfActions, FwSmCounterS1_t nOfGuards); + +/** + * Create the descriptor of a derived state machine. + * A derived state machine is a state machine which is created by extending + * another state machine. + * The state machine which is thus extended is called base state machine. + * + * This function takes a state machine as an argument and creates a derived + * state machine from it. + * The function returns the descriptor of the newly created derived state machine. + * + * The base state machine should be fully and correctly configured (i.e. it should + * pass the configuration check implemented by <code>::FwSmCheck</code>). + * Compliance with this constraint is not checked by this function. + * If the constraint is not satisfied, the behaviour of the derived state machine + * is undefined. + * + * After being created, the derived state machine has the following characteristics: + * - It has the same number of states, choice pseudo-states and transitions as + * the base state machine. + * - Its states and choice pseudo-states are connected by the same transitions as + * the base state machine. + * - Its states have the same actions as the homologous states of the base state + * machine. + * - Its transitions have the same actions and guards and are triggered by the same + * transition commands as the homologous transitions of the base state machine. + * - States whose homologous states in the base state machine have an embedded + * state machine also have an embedded state machine: the derivation process + * is applied recursively to the embedded state machines (i.e. if state S1 in + * the base state machine has an embedded state machine SM1, then the homologous + * state in the derived state machine has an embedded state machine which is + * derived by extending SM1). + * . + * Thus, the derived state machine is a structural clone of its base state machine. + * + * The attributes of the derived state machine are initialized as + * follows: + * - The error code is the same as the error code of the base state machine. + * - No state machine data are associated to the derived state machine. + * - The state machine state is STOPPED. + * - The execution counters are equal to zero. + * - The <code>transCnt</code> field in the state machine descriptor is initialized + * to zero. + * . + * After being created, the derived state machine is fully configured because it + * inherits the configuration of its base state machine. + * The configuration of a derived state machine can be modified by: + * - loading its state machine data; + * - overriding some or all of its actions and guards; and + * - embedding state machines in some or all of its states which do not + * already hold embedded state machines. + * . + * The functions to perform these reconfiguration operations are defined in + * <code>FwSmConfig.h</code>. + * + * A state machine descriptor consists of two parts: the base descriptor and + * the extension descriptor (see <code>FwSmPrivate.h</code>). + * A derived state machine and its base state machine share the same base descriptor + * (which defines the topology of the state machine) but have different extension + * descriptors. + * The extension descriptor is linked to the base descriptor through a pointer. + * This function accordingly creates a new extension descriptor and links it to the + * base descriptor of the base state machine. + * @param smDesc the descriptor of the base state machine. The base state machine + * should be a fully and correctly configured state machine (i.e. it should pass + * the <code>::FwSmCheck</code> configuration check). + * @return the descriptor of the derived state machine (or NULL if creation of the + * data structures to hold the extended state machine descriptor failed). + */ +FwSmDesc_t FwSmCreateDer(FwSmDesc_t smDesc); + +/** + * Release the memory which was allocated when the state machine descriptor. + * After this operation is called, the state machine descriptor can no longer be used. + * + * This function releases the memory of both the base and the extension parts of the + * state machine descriptor. + * Hence, if the argument state machine descriptor acted as base for other state + * machine descriptors, the derived state machine descriptors are no longer usable + * after the function has been called. + * + * This function only releases the memory of the argument state machine. + * The memory allocated to embedded state machines is not affected. + * + * Use of this function is subject to the following constraints: + * - It should only be called on a state machine descriptor which was created using + * function <code>FwSmCreate</code>. + * - It should only be called once on the same state machine descriptor. + * - It should only be called on a state machine descriptor which is correctly + * configured. + * . + * Violation of any of the above constraints may result in memory corruption. + * + * @param smDesc the descriptor of the state machine. + */ +void FwSmRelease(FwSmDesc_t smDesc); + +/** + * Release the memory allocated to a derived state machine descriptor. + * After this operation is called, the argument state machine descriptor can no longer + * be used. + * The state machine descriptor of the base state machine is unaffected by this + * function. + * + * This function only releases the memory of the argument state machine. + * The memory allocated to embedded state machines is not affected. + * + * Use of this function is subject to the following constraints: + * - It should only be called on a state machine descriptor which was created using + * function <code>FwSmCreateDer</code>. + * - It should only be called once on the same state machine descriptor. + * - It should only be called on a state machine descriptor which is correctly + * configured. + * . + * Violation of any of the above constraints may result in memory corruption. + * @param smDesc the descriptor of the state machine. + */ +void FwSmReleaseDer(FwSmDesc_t smDesc); + +/** + * Recursively release the memory which was allocated when the state machine descriptor + * was created. + * After this operation is called, the state machine descriptor can no longer be used. + * This operation also (recursively) releases the memory of the state machines embedded + * in the argument state machine. + * + * The release of the memory for the state machine and its embedded state machines + * is done by means of function <code>FwSmRelease</code>. + * The same constraints defined for <code>FwSmRelease</code> therefore also apply + * to this function. + * + * As in the case of the <code>FwSmRelease</code>, both the the base and the extension + * parts of the argument state machine descriptor are released. + * Hence, if the argument state machine or any of its embedded state machines acted as + * bases for other state machines, the derived state machine descriptors are no longer + * usable after the function has been called. + * @param smDesc the descriptor of the state machine. + */ +void FwSmReleaseRec(FwSmDesc_t smDesc); + +#endif /* FWSM_DCREATE_H_ */ diff --git a/FwProfile/src/FwSmPrivate.h b/FwProfile/src/FwSmPrivate.h new file mode 100644 index 0000000000000000000000000000000000000000..c8f89f8f6e0e5fe9ccfc30cf8e841c9b1b9c45f0 --- /dev/null +++ b/FwProfile/src/FwSmPrivate.h @@ -0,0 +1,341 @@ +/** + * @file + * @ingroup smGroup + * Declaration of the internal data structures of the FW State Machine + * Module. + * Users should not normally be concerned with these data structures. + * + * The data structures declared in this header file are used to define the state + * machine descriptor. + * A state machine descriptor holds all the information related to a certain state + * machine. + * A state machine descriptor consists of two parts: the base descriptor and + * the extension descriptor. + * + * The base descriptor holds the information which is not changed when the state + * machine is extended. + * This consists of: + * - The list of states in the state machine + * - The list of choice pseudo-states in the state machine + * - The list of transitions in the state machine + * . + * + * The extension descriptor holds the information which may be overridden when the + * state machine is extended. + * This consists of: + * - The list of actions used in the state machine (both the state actions and the + * transition actions) + * - The list of transition guards used in the state machine + * - The list of state machines embedded in the state machine + * - The pointer to the state machine data (the data upon which the + * state machine actions and guards operate) + * - The current state of the state machine + * - The execution counters of the state machine + * - The error code for the state machine + * . + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWSM_PRIVATE_H_ +#define FWSM_PRIVATE_H_ + +#include "FwSmConstants.h" + +/** + * Enumerated type for the type of a state in a state machine. + */ +typedef enum { + /** + * A proper state in a state machine. + */ + properState = 1, + /** + * A choice pseudo-state in a state machine. + */ + choicePseudoState = 2, + /** + * Either the initial or the final pseudo-state. + */ + stoppedState = 3 +} StateType_t; + +/** + * Dummy action which returns without doing anything. + * This action is used where nothing is specified for a state machine action (i.e. a + * state entry action, or a state do-action, or a state exit action, or a transition + * action). + * @param smDesc state machine descriptor. This parameter is unused in this dummy action. + * The parameter is retained for compatibility with the <code>::FwSmAction_t</code> type. + */ +void SmDummyAction(FwSmDesc_t smDesc); + +/** + * Dummy guard which always returns true. + * This guard is used where no transition guard is specified. + * @param smDesc state machine descriptor. This parameter is unused in this dummy guard. + * The parameter is retained for compatibility with the <code>::FwSmGuard_t</code> type. + * @return always return 1 (to signify that the guard is true). + */ +FwSmBool_t SmDummyGuard(FwSmDesc_t smDesc); + +/** + * Structure representing a proper state in state machine. A proper state is characterized by: + * - the set of out-going transitions from the state + * - the state machine embedded in the state + * - the entry action for the state + * - the do-action for the state + * - the exit action for the state + * . + * The first item - the set of out-going transitions from the state - is defined as + * follows. + * Transitions which originate from the same state are located in adjacent locations in + * the transition array of the base descriptor (see <code>::SmBaseDesc_t</code>). + * Field <code>outTransIndex</code> identifies the first location of this set of adjacent + * locations. + * Thus, for instance, if a state has 3 out-going transitions and if its + * <code>outTransIndex</code> field has value 4, then the three out-going transitions + * are located in elements 4, 5 and 6 of the array of transitions. + * + * The state actions are integers which identify locations in the action array + * of the state machine descriptor where the action is stored. + * Thus, for instance, if the <code>iEntryAction</code> field for state S is equal to 5, + * then the entry action of state S is the one stored at location 5 of the + * action array of that state machine. + * If an action is not defined, a value of zero is used to point to the first + * location of the action array where the dummy action <code>::SmDummyAction</code> is stored + * which returns without doing anything. + * + * By convention, the implementation treats a state as uninitialized if its + * <code>outTransIndex</code> field is equal to zero. + */ +typedef struct { + /** index of first out-going transition in the transition array of <code>::SmBaseDesc_t</code> */ + FwSmCounterS1_t outTransIndex; + /** number of outgoing transitions */ + FwSmCounterS1_t nOfOutTrans; + /** the entry action for the state */ + FwSmCounterS1_t iEntryAction; + /** the do action for the state */ + FwSmCounterS1_t iDoAction; + /** the exit action for the state */ + FwSmCounterS1_t iExitAction; +} SmPState_t; + +/** + * Structure representing a choice pseudo state in a state machine. + * A choice pseudo-state is characterized by the set of its out-going transitions. + * The set of out-going transitions is defined as follows. + * Transitions which originate from the same choice pseudo-state are located in adjacent locations in + * the transition array of the base descriptor (see <code>::SmBaseDesc_t</code>). + * Field <code>outTransIndex</code> identifies the first location of this set of adjacent + * locations. + * Thus, for instance, if a choice pseudo-state has 3 out-going transitions and if its + * <code>outTransIndex</code> field has value 4, then the three out-going transitions + * are located in elements 4, 5 and 6 of the array of transitions. + * + * By convention, the implementation treats a choice pseudo-state as uninitialized if its + * <code>outTransIndex</code> field is equal to zero. + */ +typedef struct { + /** index of first out-going transition in transition array of <code>::SmBaseDesc_t</code> */ + FwSmCounterS1_t outTransIndex; + /** number of outgoing transitions from the choice pseudo-state */ + FwSmCounterS1_t nOfOutTrans; +} SmCState_t; + +/** + * Structure representing a transition. + * A transition is characterized by: + * - the destination of the transition + * - the name of the transition + * - the action associated to the transition + * - the guard associated to the transition + * . + * The destination of the transition may be either a proper state, or the final pseudo-state, + * or a choice pseudo-state. The type of the transition destination is identified as follows: + * - a value of zero means that the destination is the final pseudo-state + * - a positive value means that the destination is a proper state and the value of <code>dest</code> + * is the identifier of the target state + * - a negative value means that the destination is a choice pseudo state and the value of + * <code>-dest</code> is the identifier of the choice pseudo-state + * . + * The name of a transition is an non-negative integer. + * The value of zero is reserved for the pre-defined "Execute" transition (see + * #FW_TR_EXECUTE) and should not be used for user-defined transitions. + * The name of a transition is "don't care" in the case of transitions out of + * pseudo-states. + * + * The transition action is an integer which identifies the location in the + * action array of the state machine descriptor (see <code>FwSmDesc</code>) + * where the action is stored as a function pointer. + * If no action is associated to the transition, a value of zero is used to + * point to the first element of the action array which holds a dummy action + * which returns without doing anything. + * + * The guard is an integer which identifies the location in the + * guard array of the state machine descriptor (see <code>FwSmDesc</code>) + * where the guard is stored as a function pointer. + * If no guard is associated to the transition, a value of zero is used to + * point to the first element of the guard array which holds a dummy guard + * which always returns "true". + * + * By convention, the implementation treats a transition as uninitialized if its + * <code>trAction</code> field is equal to -1. + */ +typedef struct { + /** the index of the destination of the transition */ + FwSmCounterS1_t dest; + /** the identifier (the "name") of the transition */ + FwSmCounterU2_t id; + /** the index of the action associated to the transition */ + FwSmCounterS1_t iTrAction; + /** the index of the guard associated to the transition */ + FwSmCounterS1_t iTrGuard; +} SmTrans_t; + +/** + * Structure representing the base descriptor of a state machine. + * The base descriptor holds the information which is not changed when the state + * machine is extended. + * This consists of: + * - The list of states in the state machine (array <code>pStates</code>) + * - The list of choice pseudo-states in the state machine (array <code>cStates</code>) + * - The list of transitions in the state machine (array <code>trans</code>) + * . + * Array <code>pStates</code> holds the proper states in the state machine. + * The proper states are identified by an integer in the range [1,N] (N is the total + * number of proper states). + * The i-th state is stored in the (i-1)-th location of <code>pStates</code>. + * The number of states is stored in field <code>nOfPStates</code>. + * + * Array <code>cStates</code> holds the choice pseudo-states in the state machine. + * The choice pseudo-states are identified by an integer in the range [1,M] (M is the total + * number of choice pseudo-states). + * The i-th choice pseudo-state is stored in the (i-1)-th location of <code>cStates</code>. + * The number of choice pseudo-states is stored in field <code>nOfCStates</code>. + * + * Array <code>trans</code> holds the transitions in the state machine. + * The transition out of the initial pseudo-state is stored in the first location of + * array <code>trans</code>. + * The other transitions are stored in groups of adjacent locations where each group + * holds the transitions out of the same state or choice pseudo-state (see also + * <code>::SmPState_t</code> and <code>::SmPState_t</code>). + * The number of transitions is stored in field <code>nOfTrans</code>. + */ +typedef struct { + /** array holding the proper states in the state machine */ + SmPState_t* pStates; + /** array holding the choice pseudo-states in the state machine */ + SmCState_t* cStates; + /** array holding the transitions in the state machine */ + SmTrans_t* trans; + /** the number of states in the state machine */ + FwSmCounterS1_t nOfPStates; + /** the number of choice pseudo-states in the state machine */ + FwSmCounterS1_t nOfCStates; + /** the number of transitions in SM */ + FwSmCounterS1_t nOfTrans; +} SmBaseDesc_t; + +/** + * Structure representing a state machine descriptor. + * Field <code>smBase</code> points to the base descriptor for the state machine + * which holds the information about the states, choice pseudo-states and the + * transitions connecting them. + * + * Array <code>smActions</code> holds the list of all actions in the state machine + * (including both state and transition actions). + * The first element of the array holds a dummy action which returns without + * doing anything. + * Each distinct action only appears once in the action array. + * If the same action is used several times in a state machine, only one instance is + * registered in the action array. + * + * Array <code>smGuards</code> holds the list of all transition guards in the + * state machine. + * The first element of the array holds a dummy guard which always returns true. + * Each distinct guard only appears once in the guard array. + * If the same guard is used several times in a state machine, only one instance is + * registered in the guard array. + * + * The i-th element of array <code>esmDesc</code> holds the state machine embedded + * in the i-th state of the state machine (or NULL if no state machine is embedded). + * + * When a new state or choice pseudo-state is added to the state machine, field + * <code>transCnt</code> holds the position in the transition array where its + * first out-going transition will be stored. + * + * The identifier of the current state (which can only be a proper state) is + * stored in <code>curState</code>. + * If this is equal to zero, then the state machine is stopped. + * + * If during the creation, configuration or execution of the state machine, an error is + * encountered, the corresponding error code is stored in field <code>errCode</code>. + * This field is initialized to <code>#smSuccess</code> and should nominally remain + * unchanged throughout the life of the state machine. + * If the error code has a value other than <code>#smSuccess</code>, the behaviour of + * the state machine is undefined. + * + * There are two types of state machines: base state machines (i.e. + * state machines which are created from scratch using <code>::FwSmCreate</code> or + * <code>#FW_SM_INST</code>) and derived state machines (i.e. state + * machines which are created by extending a base state machine through calls + * to <code>::FwSmCreateDer</code> or <code>#FW_SM_INST_DER</code>). + * By convention, a derived state machine is characterized by field + * <code>transCnt</code> being equal to zero. + * + * Two counters are associated to a sttae machine: the State Machine Execution Counter + * and the State Execution Counter. + * The State Machine Execution Counter holds the number of execution cycles since + * the state machine was started and the State Execution Counter holds the number of cycle + * since the current state was entered. + */ +struct FwSmDesc { + /** pointer to the base descriptor */ + SmBaseDesc_t* smBase; + /** the state machine actions (state and transition actions) */ + FwSmAction_t* smActions; + /** the transition guards in the state machine */ + FwSmGuard_t* smGuards; + /** the state machines embedded in the state machine */ + struct FwSmDesc** esmDesc; + /** the number of actions (state actions + transition actions) in the state machine */ + FwSmCounterS1_t nOfActions; + /** the number of guards in the state machine */ + FwSmCounterS1_t nOfGuards; + /** the counter for the number of transitions added to the state machine */ + FwSmCounterS1_t transCnt; + /** the current state of the state machine */ + FwSmCounterS1_t curState; + /** the state machine execution counter */ + FwSmCounterU3_t smExecCnt; + /** the state execution counter */ + FwSmCounterU3_t stateExecCnt; + /** either 'success' or the code of the last error encountered by the state machine */ + FwSmErrCode_t errCode; + /** the pointer to the data manipulated by the state machine actions and guards */ + void* smData; +}; + +#endif /* FWSM_PRIVATE_H_ */ diff --git a/FwProfile/src/FwSmSCreate.c b/FwProfile/src/FwSmSCreate.c new file mode 100644 index 0000000000000000000000000000000000000000..8a217574133ddce5febab9f2239be81b44722797 --- /dev/null +++ b/FwProfile/src/FwSmSCreate.c @@ -0,0 +1,110 @@ +/** + * @file + * @ingroup smGroup + * Implements the static initialization functions for the FW + * State Machine Module. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#include "FwSmSCreate.h" +#include "FwSmPrivate.h" +#include <stdlib.h> + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmInit(FwSmDesc_t smDesc) { + + FwSmCounterS1_t i; + SmBaseDesc_t* smBase = smDesc->smBase; + + for (i = 0; i < smBase->nOfPStates; i++) { + smBase->pStates[i].outTransIndex = 0; + smDesc->esmDesc[i] = NULL; + } + + for (i = 0; i < smBase->nOfCStates; i++) { + smBase->cStates[i].outTransIndex = 0; + } + + for (i = 0; i < smBase->nOfTrans; i++) { + smBase->trans[i].iTrAction = -1; + } + + smDesc->smActions[0] = &SmDummyAction; + for (i = 1; i < smDesc->nOfActions; i++) { + smDesc->smActions[i] = NULL; + } + + smDesc->smGuards[0] = &SmDummyGuard; + for (i = 1; i < smDesc->nOfGuards; i++) { + smDesc->smGuards[i] = NULL; + } +} + +/* ----------------------------------------------------------------------------------------------------------------- */ +void FwSmInitDer(FwSmDesc_t smDesc, FwSmDesc_t smDescBase) { + FwSmCounterS1_t i; + SmBaseDesc_t* smBase = smDescBase->smBase; + + if (smDesc->nOfActions != smDescBase->nOfActions) { + smDesc->errCode = smWrongNOfActions; + return; + } + + if (smDesc->nOfGuards != smDescBase->nOfGuards) { + smDesc->errCode = smWrongNOfGuards; + return; + } + + smDesc->smBase = smBase; + + /* This cycle will always be executed at least once because + * the number of actions (nOfActions) is always greater than + * zero (since all state machines have at least the dummy + * action which returns without doing anything) + */ + for (i = 0; i < smDesc->nOfActions; i++) { + smDesc->smActions[i] = smDescBase->smActions[i]; + } + + /* This cycle will always be executed at least once because + * the number of guards (nOfGuards) is always greater than + * zero (since all state machines have at least the dummy + * guard which always returns TRUE) + */ + for (i = 0; i < smDesc->nOfGuards; i++) { + smDesc->smGuards[i] = smDescBase->smGuards[i]; + } + + for (i = 0; i < smBase->nOfPStates; i++) { + smDesc->esmDesc[i] = NULL; + } + + smDesc->errCode = smDescBase->errCode; + smDesc->smExecCnt = 0; + smDesc->stateExecCnt = 0; + smDesc->transCnt = 0; + smDesc->curState = 0; + + return; +} diff --git a/FwProfile/src/FwSmSCreate.h b/FwProfile/src/FwSmSCreate.h new file mode 100644 index 0000000000000000000000000000000000000000..6088f0ad46037e602c950bb7adfccf6cd0bbac66 --- /dev/null +++ b/FwProfile/src/FwSmSCreate.h @@ -0,0 +1,333 @@ +/** + * @file + * @ingroup smGroup + * Declaration of the static creation interface for a FW State Machine. + * A FW State Machine is described by a state machine descriptor. + * This interface allows a state machine descriptor to be created + * statically (i.e. without using dynamic memory allocation). + * In this sense, this interface is alternative to the dynamic creation + * interface defined in <code>FwSmDCreate.h</code>. + * + * A state machine can be created in two ways: + * - It can be created from scratch, or + * - It can be created by extending an existing state machine. + * . + * In both cases, creation of a state machine descriptor is done in two + * steps: + * - The state machine descriptor and its internal data structures are + * instantiated. + * - The state machine descriptor and its internal data structures are + * initialized. + * . + * Instantiation is done by means of the following macros. + * - <code>#FW_SM_INST</code> should be used to instantiate from scratch + * a descriptor for a state machine with one or more choice + * pseudo-states. + * - <code>#FW_SM_INST_NOCPS</code> should be used to instantiate from + * scratch a descriptor for a state machine with no choice pseudo-states. + * - <code>#FW_SM_INST_DER</code> should be used to instantiate a + * descriptor for a state machine which is derived by extending another + * state machine. + * . + * Initialization is done by means of the following functions: + * - <code>::FwSmInit</code> should be used to initialize a descriptor + * which has been created from scratch with either + * <code>#FW_SM_INST</code> or <code>#FW_SM_INST_NOCPS</code>. + * - <code>::FwSmInitDer</code> should be used to initialize a descriptor + * of a state machine which is derived by extending another state + * machine. + * . + * Function <code>::FwSmInitDer</code> only initializes a descriptor + * in full if the base state machine (i.e. the state machine which is + * being extended) has no embedded state machines. + * If the base state machine has embedded state machines, additional + * initialization actions are required as described in the function + * documentation. + * + * After a state machine descriptor has been instantiated and + * initialized, it will normally need to be configured. + * Configuration of a state machine descriptor can be done using the + * functions described in the <code>FwSmConfig.h</code> file. + * @author Vaclav Cechticky <vaclav.cechticky@pnp-software.com> + * @author Alessandro Pasetti <pasetti@pnp-software.com> + * @copyright P&P Software GmbH, 2016, All Rights Reserved + * @version 1.3.0_UniWien + * Licensed to: Roland Ottensamer, Institut für Astrophysik, Türkenschanzstr. 17, A-1180 Wien + * Software Licence Agreement PP-SUA-COR-0028 * + * This file is part of FW Profile. + * + * FW Profile is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * FW Profile is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FW Profile. If not, see <http://www.gnu.org/licenses/>. + * + * For information on alternative licensing, please contact P&P Software GmbH. + */ + +#ifndef FWSM_SCREATE_H_ +#define FWSM_SCREATE_H_ + +#include "FwSmCore.h" +#include "FwSmPrivate.h" + +/** + * Instantiate a state machine descriptor and its internal data structure. + * This macro compiles correctly only if the number of states NS, the number + * of choice pseudo-states NCPS and the number of transitions NTRANS is positive. + * If there is a need to define a state machine with zero choice pseudo-states, + * the <code>::FW_SM_INST_NOCPS</code> macro should be used. + * + * The macro generates code that does the following: + * - It defines an array of NS elements of type <code>SmPState_t</code> to + * represent the array holding the state machine states. + * - It defines an array of NS elements of to represent the array holding + * the state machines embedded in the NS states. + * - It defines an array of NCPS elements of type <code>SmCState_t</code> to + * represent the array holding the state machine choice pseudo-states. + * - It defines an array of NTRANS elements of type <code>SmTrans_t</code> to + * represent the array holding the state machine transitions. + * - It defines an array of (NA+1) elements of type <code>SmAction_t</code> to + * represent the array holding the state machine actions. + * - It defines an array of (NG+1) elements of type <code>SmGuard_t</code> to + * represent the array holding the state machine guards. + * - It defines and initializes a variable of type <code>FwSmDescBase_t</code> + * to represent the base part of the state machine descriptor. + * - It defines and initializes a variable with the name SM_DESC of type + * <code>struct FwSmDesc</code> to represent the state machine descriptor. + * . + * All variables defined by this macro are <code>static</code>. + * + * The state machine descriptor instantiated by the macro is only partially + * initialized. + * Full initialization is performed using function <code>::FwSmInit</code>. + * + * Since the macro includes the declaration of several variables, it should be located + * in the section of a c-file where variable declaration is legal. + * + * @param SM_DESC the variable holding the state machine descriptor + * @param NS a positive integer representing the number of states + * @param NCPS a positive integer the number of choice pseudo-states + * @param NTRANS a positive integer representing the number of transitions + * @param NA a non-negative integer representing the number of actions (i.e. the + * number of transition or state actions which are defined on the state machine) + * @param NG a non-negative integer representing the number of guards (i.e. the + * number of transition actions which are defined on the state machine) + */ +#define FW_SM_INST(SM_DESC, NS, NCPS, NTRANS, NA, NG) \ + static SmPState_t SM_DESC##_pState[(NS)]; \ + static SmCState_t SM_DESC##_cState[(NCPS)]; \ + static SmTrans_t SM_DESC##_trans[(NTRANS)]; \ + static FwSmAction_t SM_DESC##_actions[(NA) + 1]; \ + static FwSmGuard_t SM_DESC##_guards[(NG) + 1]; \ + static FwSmDesc_t SM_DESC##_esm[(NS)]; \ + static SmBaseDesc_t SM_DESC##_base = {(SM_DESC##_pState), (SM_DESC##_cState), (SM_DESC##_trans), NS, NCPS, NTRANS}; \ + static struct FwSmDesc(SM_DESC) = {&(SM_DESC##_base), \ + (SM_DESC##_actions), \ + (SM_DESC##_guards), \ + (SM_DESC##_esm), \ + (NA) + 1, \ + (NG) + 1, \ + 1, \ + 0, \ + 0, \ + 0, \ + smSuccess, \ + NULL}; + +/** + * Instantiate a state machine descriptor and its internal data structure. + * This macro compiles correctly only if the number of states NS and the number + * of transitions NTRANS is positive. + * This macro instantiates a descriptor for a state machine without choice + * pseudo-states. + * If there is a need to define a state machine with one or more choice + * pseudo-states, the <code>::FW_SM_INST</code> macro should be used. + * + * The macro generates code that does the following: + * - It defines an array of NS elements of type <code>SmPState_t</code> to + * represent the array holding the state machine states. + * - It defines an array of NS elements of to represent the array holding + * the state machines embedded in the NS states. + * - It defines an array of NTRANS elements of type <code>SmTrans_t</code> to + * represent the array holding the state machine transitions. + * - It defines an array of (NA+1) elements of type <code>SmAction_t</code> to + * represent the array holding the state machine actions. + * - It defines an array of (NG+1) elements of type <code>SmGuard_t</code> to + * represent the array holding the state machine guards. + * - It defines and initializes a variable of type <code>FwSmDescBase_t</code> + * to represent the base part of the state machine descriptor. + * - It defines and initializes a variable with the name SM_DESC of type + * <code>struct FwSmDesc</code> to represent the state machine descriptor. + * . + * All variables defined by this macro are <code>static</code>. + * + * The state machine descriptor instantiated by the macro is only partially + * initialized. + * Full initialization is performed using function <code>::FwSmInit</code>. + * + * Since the macro includes the declaration of several variables, it should be located + * in the section of a c-file where variable declaration is legal. + * + * @param SM_DESC the variable holding the state machine descriptor + * @param NS a positive integer representing the number of states + * @param NTRANS a positive integer representing the number of transitions + * @param NA a non-negative integer representing the number of actions (i.e. the + * number of transition or state actions which are defined on the state machine) + * @param NG a non-negative integer representing the number of guards (i.e. the + * number of transition actions which are defined on the state machine) + */ +#define FW_SM_INST_NOCPS(SM_DESC, NS, NTRANS, NA, NG) \ + static SmPState_t SM_DESC##_pState[(NS)]; \ + static SmTrans_t SM_DESC##_trans[(NTRANS)]; \ + static FwSmAction_t SM_DESC##_actions[(NA) + 1]; \ + static FwSmGuard_t SM_DESC##_guards[(NG) + 1]; \ + static FwSmDesc_t SM_DESC##_esm[(NS)]; \ + static SmBaseDesc_t SM_DESC##_base = {(SM_DESC##_pState), NULL, (SM_DESC##_trans), NS, 0, NTRANS}; \ + static struct FwSmDesc(SM_DESC) = {&(SM_DESC##_base), \ + (SM_DESC##_actions), \ + (SM_DESC##_guards), \ + (SM_DESC##_esm), \ + (NA) + 1, \ + (NG) + 1, \ + 1, \ + 0, \ + 0, \ + 0, \ + smSuccess, \ + NULL}; + +/** + * Instantiate a descriptor for a derived state machine. + * A derived state machine is a state machine which is created by extending + * another state machine. + * The state machine which is thus extended is called base state machine. + * + * A state machine descriptor consists of two parts: the base descriptor and + * the extension descriptor (see <code>FwSmPrivate.h</code>). + * A derived state machine and its base state machine share the same base descriptor + * (which defines the topology of the state machine) but have different extension + * descriptors. + * This macro accordingly only instantiates a new extension descriptor. + * More precisely, this macro generates code that does the following: + * - It defines an array of (NA+1) elements of type <code>SmAction_t</code> to + * represent the array holding the state machine actions. + * - It defines an array of (NG+1) elements of type <code>SmGuard_t</code> to + * represent the array holding the state machine guards. + * - It defines and initializes a variable with the name SM_DESC of type + * <code>struct FwSmDesc</code> to represent the state machine descriptor. + * . + * All variables defined by this macro are <code>static</code>. + * + * The state machine descriptor instantiated by the macro is only partially + * initialized. + * Full initialization is performed using function <code>::FwSmInitDer</code>. + * + * Since the macro includes the declaration of several variables, it should be located + * in the section of a c-file where variable declaration is legal. + * + * @param SM_DESC the variable holding the state machine descriptor + * @param NS a positive integer representing the number of states + * @param NA a non-negative integer representing the number of actions (i.e. the + * number of transition or state actions which are defined on the state machine) + * @param NG a non-negative integer representing the number of guards + */ +#define FW_SM_INST_DER(SM_DESC, NS, NA, NG) \ + static FwSmAction_t SM_DESC##_actions[(NA) + 1]; \ + static FwSmGuard_t SM_DESC##_guards[(NG) + 1]; \ + static FwSmDesc_t SM_DESC##_esm[(NS)]; \ + static struct FwSmDesc(SM_DESC) = \ + { \ + NULL, (SM_DESC##_actions), (SM_DESC##_guards), (SM_DESC##_esm), (NA) + 1, (NG) + 1, 1, 0, 0, 0, smSuccess, \ + NULL}; + +/** + * Initialize a state machine descriptor to represent an unconfigured state + * machine with no transitions, no actions, no guards and no embedded state + * machines. + * After this function has been executed, the argument state machine descriptor + * has the same content as a state machine descriptor which has been + * created by calling <code>::FwSmCreate</code>. + * + * This function is primarily intended to be used to initialize a state machine + * descriptor which has been statically instantiated with macro + * <code>#FW_SM_INST</code> or <code>#FW_SM_INST_NOCPS</code>. + * + * If the function is called upon a state machine descriptor that had already been + * initialized, the previous initialization values are lost. + * In such a case, a memory leak is possible due to the potential loss of the pointers + * to the arrays where the state machines states, choice pseudo-states, transitions and + * embedded state machines are stored. + * @param smDesc the state machine descriptor to be initialized. + */ +void FwSmInit(FwSmDesc_t smDesc); + +/** + * Initialize a state machine descriptor to extend another state machine (the + * base state machine). + * This function checks that the descriptor to be initialized satisfies + * the following constraints: + * - it has the same number of actions as the base state machine, and + * - it has the same number of guards as the base state machine. + * . + * If either constraint is not satisfied, the function reports an error + * by setting the error code of the descriptor to be initialized and then + * returns. + * If the first constraint is not satisfied, the function sets the error + * code to <code>#smWrongNOfActions</code>. + * If the second constraint is not satisfied, the function sets the error + * code to <code>#smWrongNOfGuards</code>. + * + * If both constraints are satisfied, this function initializes a descriptor + * as follows: + * - It links it to the descriptor of the base state machine. + * - It initializes its actions to be the same as the actions of the base state + * machine. + * - It initializes its guards to be the same as the guards of the base state + * machine. + * - It initializes its states to have no embedded state machines. + * - It initializes its error code to be the same as the error code of the base + * state machine. + * - It initializes its <code>transCnt</code> field to zero. + * - It sets its state to STOPPED. + * . + * Thus, if the base state machine has no embedded state machines, then this + * function initializes a descriptor to represent its derived state machine. + * In this case, the descriptor initialized by this function represents + * exactly the same state machine as the descriptor created by calling + * function <code>::FwSmCreateDer</code>. + * If, instead, the base state machine has one or more embedded state machines, + * then, in order to achieve the same effect as the <code>::FwSmCreateDer</code> + * function, the descriptor initialized by this function must be further + * configured as follows: + * - The state machines embedded in the base state machine are extended. + * The extension is done using, recursively, the <code>#FW_SM_INST_DER</code> + * macro and the <code>::FwSmInitDer</code> function. + * Let ESM(i) be the extension of the state machine embedded in the + * i-th state of the base state machine. + * - The ESM(i) state machine is embedded within the i-th state of the + * descriptor initialized by this function using the + * <code>::FwSmEmbed</code> function. + * . + * + * This function is primarily intended to be used to initialize a state machine + * descriptor which has been statically instantiated with macro + * <code>#FW_SM_INST_DER</code>. + * If the function is called upon a state machine descriptor that had already been + * initialized, the previous initialization values are lost. + * In such a case, a memory leak is possible due to the potential loss of the pointers + * to the arrays where the state machines states, choice pseudo-states, transitions and + * embedded state machines are stored. + * @param smDesc the state machine descriptor to be initialized. + * @param smDescBase the state machine descriptor of the base state machine. + */ +void FwSmInitDer(FwSmDesc_t smDesc, FwSmDesc_t smDescBase); + +#endif /* FWSM_SCREATE_H_ */ diff --git a/IBSW/.gitignore b/IBSW/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a35ea4d9eafb08ac035f38fd245f538bb4d09589 --- /dev/null +++ b/IBSW/.gitignore @@ -0,0 +1,6 @@ +*~ +[#]*[#] +./#* +*.o +*.lib +*.a diff --git a/IBSW/doc/Doxyfile b/IBSW/doc/Doxyfile new file mode 100644 index 0000000000000000000000000000000000000000..c73bc22b135588910593fd8050c8eb4cfb7d13c4 --- /dev/null +++ b/IBSW/doc/Doxyfile @@ -0,0 +1,2482 @@ +# Doxyfile 1.8.14 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "CHEOPS IBSW" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 1.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "CHEOPS Instrument Basic Software" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = "images/cheops-logo-with-additional3.png" + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = ../ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = ../ + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = YES + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = YES + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = "/bin/sh -c 'git log --pretty=\"format:%ci, author:%aN <%aE>, commit:%h\" -1 \"${1}\" || echo no git'" + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = YES + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../lib ../include ../test ./extradoc + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = ../example ../spin + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = images + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = customdoxygen.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when enabling USE_PDFLATEX this option is only used for generating +# bitmaps for formulas in the HTML output, but not in the Makefile that is +# written to the output directory. +# The default file is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's config +# file, i.e. a series of assignments. You only have to provide replacements, +# missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's config file. A template extensions file can be generated +# using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO, the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = ../include + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = __attribute__(x)=1 __SPW_ROUTING__=1 __sparc__=1 + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = YES + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = svg + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = YES + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = /opt/plantuml + +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/IBSW/doc/DoxygenLayout.xml b/IBSW/doc/DoxygenLayout.xml new file mode 100644 index 0000000000000000000000000000000000000000..7479687ef34ccb9d265a30c64f63b44943fceee6 --- /dev/null +++ b/IBSW/doc/DoxygenLayout.xml @@ -0,0 +1,194 @@ +<doxygenlayout version="1.0"> + <!-- Generated by doxygen 1.8.11 --> + <!-- Navigation index tabs for HTML output --> + <navindex> + <tab type="mainpage" visible="yes" title=""/> + <tab type="pages" visible="yes" title="" intro=""/> + <tab type="modules" visible="yes" title="" intro=""/> + <tab type="namespaces" visible="yes" title=""> + <tab type="namespacelist" visible="yes" title="" intro=""/> + <tab type="namespacemembers" visible="yes" title="" intro=""/> + </tab> + <tab type="classes" visible="yes" title=""> + <tab type="classlist" visible="yes" title="" intro=""/> + <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> + <tab type="hierarchy" visible="yes" title="" intro=""/> + <tab type="classmembers" visible="yes" title="" intro=""/> + </tab> + <tab type="files" visible="yes" title=""> + <tab type="filelist" visible="yes" title="" intro=""/> + <tab type="globals" visible="yes" title="" intro=""/> + </tab> + <tab type="examples" visible="yes" title="" intro=""/> + </navindex> + + <!-- Layout definition for a class page --> + <class> + <briefdescription visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <inheritancegraph visible="$CLASS_GRAPH"/> + <collaborationgraph visible="$COLLABORATION_GRAPH"/> + <detaileddescription title=""/> + <memberdecl> + <nestedclasses visible="yes" title=""/> + <publictypes title=""/> + <services title=""/> + <interfaces title=""/> + <publicslots title=""/> + <signals title=""/> + <publicmethods title=""/> + <publicstaticmethods title=""/> + <publicattributes title=""/> + <publicstaticattributes title=""/> + <protectedtypes title=""/> + <protectedslots title=""/> + <protectedmethods title=""/> + <protectedstaticmethods title=""/> + <protectedattributes title=""/> + <protectedstaticattributes title=""/> + <packagetypes title=""/> + <packagemethods title=""/> + <packagestaticmethods title=""/> + <packageattributes title=""/> + <packagestaticattributes title=""/> + <properties title=""/> + <events title=""/> + <privatetypes title=""/> + <privateslots title=""/> + <privatemethods title=""/> + <privatestaticmethods title=""/> + <privateattributes title=""/> + <privatestaticattributes title=""/> + <friends title=""/> + <related title="" subtitle=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <services title=""/> + <interfaces title=""/> + <constructors title=""/> + <functions title=""/> + <related title=""/> + <variables title=""/> + <properties title=""/> + <events title=""/> + </memberdef> + <allmemberslink visible="yes"/> + <usedfiles visible="$SHOW_USED_FILES"/> + <authorsection visible="yes"/> + </class> + + <!-- Layout definition for a namespace page --> + <namespace> + <briefdescription visible="yes"/> + <detaileddescription title=""/> + <memberdecl> + <nestednamespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <classes visible="yes" title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection visible="yes"/> + </namespace> + + <!-- Layout definition for a file page --> + <file> + <briefdescription visible="yes"/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <includegraph visible="$INCLUDE_GRAPH"/> + <includedbygraph visible="$INCLUDED_BY_GRAPH"/> + <sourcelink visible="yes"/> + <detaileddescription title=""/> + <memberdecl> + <classes visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection/> + </file> + + <!-- Layout definition for a group page --> + <group> + <briefdescription visible="yes"/> + <groupgraph visible="$GROUP_GRAPHS"/> + <detaileddescription title=""/> + <memberdecl> + <nestedgroups visible="yes" title=""/> + <dirs visible="yes" title=""/> + <files visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <classes visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <pagedocs/> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + </memberdef> + <authorsection visible="yes"/> + </group> + + <!-- Layout definition for a directory page --> + <directory> + <briefdescription visible="yes"/> + <directorygraph visible="yes"/> + <memberdecl> + <dirs visible="yes"/> + <files visible="yes"/> + </memberdecl> + <detaileddescription title=""/> + </directory> +</doxygenlayout> diff --git a/IBSW/doc/Makefile b/IBSW/doc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..533632bab1e780f0839d5c17dc46494eb128c7cd --- /dev/null +++ b/IBSW/doc/Makefile @@ -0,0 +1,16 @@ +CSSFILES = $(shell ls *.css) +JSFILES = $(shell ls *.js) +HTFILES = header.html footer.html + +.PHONY: all + +all: + @which plantuml + @test -d html || mkdir html + doxygen + cp $(CSSFILES) $(JSFILES) $(HTFILES) html/ + +.PHONY: clean +clean: + rm -rf html + diff --git a/IBSW/doc/README b/IBSW/doc/README new file mode 100644 index 0000000000000000000000000000000000000000..34dd87372f00db333f02cbbb9f97b8947be17902 --- /dev/null +++ b/IBSW/doc/README @@ -0,0 +1,5 @@ + +be sure to copy the .js and .css files to the html/ directory or they will not be found by the browser + + +doxygen requires plantuml to be installed in the current configuration diff --git a/IBSW/doc/bootstrap.min.css b/IBSW/doc/bootstrap.min.css new file mode 100644 index 0000000000000000000000000000000000000000..4cf729e4342a51d8b300e8d43f2f78b0a6faf403 --- /dev/null +++ b/IBSW/doc/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/IBSW/doc/bootstrap.min.js b/IBSW/doc/bootstrap.min.js new file mode 100644 index 0000000000000000000000000000000000000000..e79c065134f2cfcf3e44a59cffcb5f090232f98f --- /dev/null +++ b/IBSW/doc/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active"); +d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/IBSW/doc/customdoxygen.css b/IBSW/doc/customdoxygen.css new file mode 100644 index 0000000000000000000000000000000000000000..6a32ca7cc14ef237589954afbe62418891459d9e --- /dev/null +++ b/IBSW/doc/customdoxygen.css @@ -0,0 +1,306 @@ +/* +h1, .h1, h2, .h2, h3, .h3{ + font-weight: 200 !important; +} +*/ + +h1,.h1 { + font-size: 24px; +} + +h2,.h2 { + font-size: 20px; +} + +h3,.h3 { + font-size: 16px; +} + +h4,.h4 { + font-size: 14px; +} + +h5,.h5 { + font-size: 12px; +} + +h6,.h6 { + font-size: 10px; +} + + + +#navrow1, #navrow2, #navrow3, #navrow4, #navrow5{ + border-bottom: 1px solid #706d6e; +} + +.adjust-right { +margin-left: 30px !important; +font-size: 1.15em !important; +} +.navbar{ + border: 0px solid #222 !important; +} + + +/* Sticky footer styles +-------------------------------------------------- */ +html, +body { + height: 100%; + /* The html and body elements cannot have any padding or margin. */ +} + +img { +max-width:100%; +max-height:100%; +} + +/* Wrapper for page content to push down footer */ +#wrap { + min-height: 100%; + height: auto; + /* Negative indent footer by its height */ + margin: 0 auto -60px; + /* Pad bottom by footer height */ + padding: 0 0 60px; +} + +/* Set the fixed height of the footer here */ +#footer { + font-size: 0.9em; + padding: 8px 0px; + background-color: #f5f5f5; +} + +.footer-row { + line-height: 44px; +} + +#footer > .container { + padding-left: 15px; + padding-right: 15px; +} + +.footer-follow-icon { + margin-left: 3px; + text-decoration: none !important; +} + +.footer-follow-icon img { + width: 20px; +} + +.footer-link { + padding-top: 5px; + display: inline-block; + color: #999999; + text-decoration: none; +} + +.footer-copyright { + text-align: center; +} + + +@media (min-width: 992px) { + .footer-row { + text-align: left; + } + + .footer-icons { + text-align: right; + } +} +@media (max-width: 991px) { + .footer-row { + text-align: center; + } + + .footer-icons { + text-align: center; + } +} + +/* DOXYGEN Code Styles +----------------------------------- */ + + +div.ingroups { + font-size: 16pt; + width: 50%; + text-align: left; + padding-top: 10px; +} + +a.qindex { + font-size: 8pt; +} + +a.qindexHL { + font-size: 9pt; + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 8pt; + line-height: 125%; + font-family: monospace, fixed; +} + +div.navtab { + text-align: left; + padding-left: 5px; + margin-right: 5px; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +.caption { + font-weight: bold; + padding-top: 10px; + padding-bottom: 20px; +} +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + diff --git a/IBSW/doc/doxy-boot.js b/IBSW/doc/doxy-boot.js new file mode 100644 index 0000000000000000000000000000000000000000..f045d16f2b2aa6bded9165c8ad19f1a04eb3c9da --- /dev/null +++ b/IBSW/doc/doxy-boot.js @@ -0,0 +1,121 @@ +$( document ).ready(function() { + + $("div.headertitle").addClass("page-header"); + $("div.title").addClass("h1"); + + $('li > a[href="index.html"] > span').before("<i class='fa fa-cog'></i> "); + $('li > a[href="index.html"] > span').text("CHEOPS IBSW"); + $('li > a[href="modules.html"] > span').before("<i class='fa fa-square'></i> "); + $('li > a[href="namespaces.html"] > span').before("<i class='fa fa-bars'></i> "); + $('li > a[href="annotated.html"] > span').before("<i class='fa fa-list-ul'></i> "); + $('li > a[href="classes.html"] > span').before("<i class='fa fa-book'></i> "); + $('li > a[href="inherits.html"] > span').before("<i class='fa fa-sitemap'></i> "); + $('li > a[href="functions.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_func.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_vars.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_enum.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_eval.html"] > span').before("<i class='fa fa-list'></i> "); + $('img[src="ftv2ns.png"]').replaceWith('<span class="label label-danger">N</span> '); + $('img[src="ftv2cl.png"]').replaceWith('<span class="label label-danger">C</span> '); + + $("ul.tablist").addClass("nav nav-pills nav-justified"); + $("ul.tablist").css("margin-top", "0.5em"); + $("ul.tablist").css("margin-bottom", "0.5em"); + $("li.current").addClass("active"); + $("iframe").attr("scrolling", "yes"); + + $("#nav-path > ul").addClass("breadcrumb"); + + $("table.params").addClass("table"); + $("div.ingroups").wrapInner("<small></small>"); + $("div.levels").css("margin", "0.5em"); + $("div.levels > span").addClass("btn btn-default btn-xs"); + $("div.levels > span").css("margin-right", "0.25em"); + + $("table.directory").addClass("table table-striped"); + $("div.summary > a").addClass("btn btn-default btn-xs"); + $("table.fieldtable").addClass("table"); + $(".fragment").addClass("well"); + $(".memitem").addClass("panel panel-default"); + $(".memproto").addClass("panel-heading"); + $(".memdoc").addClass("panel-body"); + $("span.mlabel").addClass("label label-info"); + + $("table.memberdecls").addClass("table"); + $("[class^=memitem]").addClass("active"); + + $("div.ah").addClass("btn btn-default"); + $("span.mlabels").addClass("pull-right"); + $("table.mlabels").css("width", "100%") + $("td.mlabels-right").addClass("pull-right"); + + $("div.ttc").addClass("panel panel-primary"); + $("div.ttname").addClass("panel-heading"); + $("div.ttname a").css("color", 'white'); + $("div.ttdef,div.ttdoc,div.ttdeci").addClass("panel-body"); + + $('#MSearchBox').parent().remove(); + + $('div.fragment.well div.line:first').css('margin-top', '15px'); + $('div.fragment.well div.line:last').css('margin-bottom', '15px'); + + $('table.doxtable').removeClass('doxtable').addClass('table table-striped table-bordered').each(function(){ + $(this).prepend('<thead></thead>'); + $(this).find('tbody > tr:first').prependTo($(this).find('thead')); + + $(this).find('td > span.success').parent().addClass('success'); + $(this).find('td > span.warning').parent().addClass('warning'); + $(this).find('td > span.danger').parent().addClass('danger'); + }); + + + + if($('div.fragment.well div.ttc').length > 0) + { + $('div.fragment.well div.line:first').parent().removeClass('fragment well'); + } + + $('table.memberdecls').find('.memItemRight').each(function(){ + $(this).contents().appendTo($(this).siblings('.memItemLeft')); + $(this).siblings('.memItemLeft').attr('align', 'left'); + }); + + function getOriginalWidthOfImg(img_element) { + var t = new Image(); + t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src; + return t.width; + } + + $('div.dyncontent').find('img').each(function(){ + if(getOriginalWidthOfImg($(this)[0]) > $('#content>div.container').width()) + $(this).css('width', '100%'); + }); + + $(".memitem").removeClass('memitem'); + $(".memproto").removeClass('memproto'); + $(".memdoc").removeClass('memdoc'); + $("span.mlabel").removeClass('mlabel'); + $("table.memberdecls").removeClass('memberdecls'); + $("[class^=memitem]").removeClass('memitem'); + $("span.mlabels").removeClass('mlabels'); + $("table.mlabels").removeClass('mlabels'); + $("td.mlabels-right").removeClass('mlabels-right'); + $(".navpath").removeClass('navpath'); + $("li.navelem").removeClass('navelem'); + $("a.el").removeClass('el'); + $("div.ah").removeClass('ah'); + $("div.header").removeClass("header"); + + $('.mdescLeft').each(function(){ + if($(this).html()==" ") { + $(this).siblings('.mdescRight').attr('colspan', 2); + $(this).remove(); + } + }); + $('td.memItemLeft').each(function(){ + if($(this).siblings('.memItemRight').html()=="") { + $(this).attr('colspan', 2); + $(this).siblings('.memItemRight').remove(); + } + }); +}); diff --git a/IBSW/doc/extradoc/mainpage.dox b/IBSW/doc/extradoc/mainpage.dox new file mode 100644 index 0000000000000000000000000000000000000000..ae248834b02aaefb75bfda766cbcc02853109b61 --- /dev/null +++ b/IBSW/doc/extradoc/mainpage.dox @@ -0,0 +1,58 @@ +/** + +@mainpage + +@section iaswdoc IBSW Documentation + +The documentation of the IBSW is provided in part externally and in part (especially the detailed design of the science data processing) +through this Doxygen. If this is what you are interested in, <b>go to the <a href="modules.html">Modules</a> section</b>. + +@section sec_sources Source Code + +The source code may be found in the subdirectories _lib_ and _include_ in the +topmost level of the source tree. +A set of examples demonstrating the use of the various components may be found +in the _examples_ subdirectory. + +@section sec_files Files + +The files and data structures can be browsed following these links: <a href="files.html">Files</a>, <a href="annotated.html">Data Structures</a>. + +@subsection sec_test_suite_prerequisites Prerequisites + +To build and run the test suite, you need the following prerequisities: + + - gnu make + + - a recent enough version of gcc capable of building 32 bit binaries + (https://gcc.gnu.org/install/download.html) + - a 32 bit version of CUnit + (http://cunit.sourceforge.net/) + - gcov (see https://gcc.gnu.org/onlinedocs/gcc/Gcov.html; ususally packaged + with gcc) + - to generate gcov html output, you need lcov + (http://ltp.sourceforge.net/coverage/lcov.php) + +@subsection sec_test_suite_build_run Building and Running the Tests + +To build and run the test suite, enter the *test* subdirectory in the topmost +level of the source tree. + + - if you have lcov installed: + - issue the command _make coverage_ + - the test suite will be compiled and executed + - to view the lcov-generated html report, open the file _index.html_ in + the _out_ subdirectory in a web browser if it did not open + automatically + + - if you do not have lcov installed: + - issue the command _make_ + - execute the file _unittest_ and dump the output into a logfile + - to generate a coverage report, run + gcov -s *subdirectory* *test_file.c* for each of the tests. + + + + + +*/ diff --git a/IBSW/doc/footer.html b/IBSW/doc/footer.html new file mode 100644 index 0000000000000000000000000000000000000000..f2fa20497a366600145ea79809f6250cf08f2704 --- /dev/null +++ b/IBSW/doc/footer.html @@ -0,0 +1,26 @@ +<!-- HTML footer for doxygen 1.8.8--> +<!-- start footer part --> +<!--BEGIN GENERATE_TREEVIEW--> +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> + <ul> + $navpath + <li class="footer">$generatedby + <a href="http://www.doxygen.org/index.html"> + <img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li> + </ul> +</div> +<!--END GENERATE_TREEVIEW--> +</div> +</div> +</div> +</div> +</div> +<!--BEGIN !GENERATE_TREEVIEW--> +<hr class="footer"/><address class="footer"><small> +$generatedby  <a href="http://www.doxygen.org/index.html"> +<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/> +</a> $doxygenversion +</small></address> +<!--END !GENERATE_TREEVIEW--> +</body> +</html> diff --git a/IBSW/doc/header.html b/IBSW/doc/header.html new file mode 100644 index 0000000000000000000000000000000000000000..d4b85eb86c9df8e6cc1f10c931e7e3626d0e4cf1 --- /dev/null +++ b/IBSW/doc/header.html @@ -0,0 +1,47 @@ +<!-- HTML header for doxygen 1.8.8--> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <!-- For Mobile Devices --> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> + <meta name="generator" content="Doxygen $doxygenversion"/> + + <script type="text/javascript" src="jquery.js"></script> + + <!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME--> + <!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME--> + <!--<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>--> + <script type="text/javascript" src="$relpath^dynsections.js"></script> + $treeview + $search + $mathjax + <link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" /> + + <link rel="stylesheet" href="$relpath^bootstrap.min.css"> + + $extrastylesheet + + <script src="$relpath^bootstrap.min.js"></script> + <script type="text/javascript" src="$relpath^doxy-boot.js"></script> + </head> + <body> + + <nav class="navbar navbar-default" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <a class="navbar-brand"> + <img alt="Logo" align="left" style="margin-right: 1em;" src=$projectlogo/> + $projectname $projectnumber</a> + </div> + </div> + </nav> + <div id="top"><!-- do not remove this div, it is closed by doxygen! --> + <div class="content" id="content"> + <div class="container"> + <div class="row"> + <div class="col-sm-12 panel panel-default" style="padding-bottom: 15px;"> + <div style="margin-bottom: 15px;"> +<!-- end header part --> diff --git a/IBSW/doc/images/cheops-logo-with-additional3.png b/IBSW/doc/images/cheops-logo-with-additional3.png new file mode 100644 index 0000000000000000000000000000000000000000..20e1b7978b60d6a269645f9fc35a4abb07c6107a Binary files /dev/null and b/IBSW/doc/images/cheops-logo-with-additional3.png differ diff --git a/IBSW/doc/images/core1553brm_as250/irq_handler.graphml b/IBSW/doc/images/core1553brm_as250/irq_handler.graphml new file mode 100644 index 0000000000000000000000000000000000000000..42898864c9874fab01815ec707b3768763e41ae9 --- /dev/null +++ b/IBSW/doc/images/core1553brm_as250/irq_handler.graphml @@ -0,0 +1,1669 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.2--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="60.0" width="60.0" x="170.0" y="820.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="126.28515625" x="-33.142578125" y="83.91562499999998">MIL-STD-1553 IRQ<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="23.915624999999977" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_SIGNAL"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="297.9208984375" y="829.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="100.84375" x="6.177656670026863" y="5.0">Iterate Interrupt +Log List</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="140.158203125" x="454.9208984375" y="829.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="107.171875" x="16.4931640625" y="11.984375">Select next entry</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="68.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="502.5" y="652.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="140.158203125" x="247.4208984375" y="654.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="127.890625" x="6.1337890625" y="5.0">Check Flags in +Pending IRQ register</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="68.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="170.0" y="652.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="-20.727564560602474" y="654.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="100.580078125" x="1.7890625" y="5.0">Call +Fault Handler(s)</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="16.351537001897526" y="735.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="44.5703125" x="-7.28515625" y="44.472987975045044">Return<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="14.4729879750451" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="472.9208984375" y="579.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="99.068359375" x="2.544921875" y="11.984375">Invalidate Entry</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="-136.7016822076613" y="506.85183823529405"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="66.337890625" x="18.91015625" y="5.0">Extract +Descriptor</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="502.5" y="502.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="73.9375" width="108.158203125" x="470.9208984375" y="413.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="69.173828125" x="19.4921875" y="21.0">Check IRQ +Fault Flags</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="52.0791015625" y="34.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="668.4591397849463" y="652.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n13"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="115.44055606617644" x="633.238861751858" y="829.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="100.580078125" x="7.430238970588221" y="5.0">Call +Fault Handler(s)</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="55.72027803308822" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n14"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="-11.701682207661293" y="345.11746323529405"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="92.3125" x="5.9228515625" y="5.0">Extract +Address Offset</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n15"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="-11.701682207661293" y="431.85183823529405"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="79.251953125" x="12.453125" y="-1.984375">Extract +Word Count/ +Mode Code</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n16"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="-136.7016822076613" y="106.85183823529405"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="58.568359375" x="22.794921875" y="5.0">Identify +IRQ Type</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n17"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="17.877419354838707" y="105.32058823529405"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n18"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="802.5" y="102.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n19"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="802.5" y="277.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n20"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="802.5" y="352.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n21"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="-11.701682207661293" y="270.11746323529405"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="75.490234375" x="14.333984375" y="5.0">Identify +Input Buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n22"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="148.8227526767156" y="150.32058823529405"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.16310440049034" y="24.441406250000057">DD +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n23"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="144.14210707720594" y="431.85183823529405"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="66.90625" x="18.6259765625" y="11.984375">Copy Data</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n24"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="938.7626953125" y="104.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="86.1015625" x="9.0283203125" y="5.0">Identify +Output Buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n25"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="953.4993934993752" y="589.3188235294118"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="44.224609375" x="25.286151275490283" y="24.441406250000114">AD +Packet +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n26"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="149.27648269489225" x="926.2596081149193" y="483.5990255376345"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="125.921875" x="11.677303847446183" y="5.0">Move up to 1kiB in +packets to ADB SAs</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="72.63824134744618" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n27"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="609.3009366599463" y="279.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="81.6484375" x="11.2548828125" y="5.0">Get optional +data word</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n28"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="472.9208984375" y="279.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="71.23046875" x="16.4638671875" y="5.0">Handle +Mode Code</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n29"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="971.3778876848116" y="354.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="59.1953125" x="22.4814453125" y="11.984375">[ignored]</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n30"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="477.6015440370097" y="921.8172967069892"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="57.02734375" x="18.88478408799034" y="24.441406250000114">Interrupt +Log +List</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n31"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="146.04408602150613" x="750.2155220934131" y="483.59902553763453"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="120.16796875" x="12.938058635753123" y="5.0">Set up Acquisition +Transfer Descriptor</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="71.02204301075312" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n32"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="86.8595330752687" width="322.392366795699" x="-33.70168220766129" y="944.7468261317206"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="263.2421875" x="29.575089647849495" y="14.24226653763435">AD ... Acquisition Data +DD ... Distribution Data +ADB ... Acquisition Data Buffer +ATR ... Acquisition Transfer Request</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="159.1961833978495" y="41.42976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n33"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="149.27648269489248" x="278.30031020220594" y="431.85183823529405"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="135.677734375" x="6.799374159946183" y="5.0">Set up Distribution +Transfer Confirmation</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="72.63824134744618" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n34"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="1076.453156502016" y="104.03125"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="30.0" sy="-0.0" tx="-56.59953167002686" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n30" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="56.59953167002686" sy="-0.0" tx="-70.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n2" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="-0.0" tx="70.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="79.22265625" x="-84.19461059570312" y="-8.984375">invalid entry<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="34.416129032257906" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n4" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-70.0791015625" sy="-0.0" tx="22.5" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n5" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="-0.0" tx="52.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="31.9375" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="57.390625" x="-62.348358154296875" y="-15.96875">Fault(s) +detected<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n6" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-15.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n5" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="15.0" ty="-0.0"> + <y:Point x="192.5" y="750.0"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="60.28515625" x="-85.64552056155124" y="43.515625">No Faults<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n3" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-22.5" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n8" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n10" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="-0.0" tx="52.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="99.384765625" x="-317.1814685452369" y="-7.574263987821723">Subaddress IRQ<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_DEFAULT_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e12" source="n10" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-22.5" tx="0.0" ty="36.96875000000001"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e13" source="n12" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-8.984402695522476" anchorY="5.0" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="1.0" upY="1.8369701987210297E-16" visible="true" width="106.720703125" x="-8.984402695522496" y="5.0">Fault(s) detected<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e14" source="n11" target="n12"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="54.07910156249999" sy="-0.0" tx="0.0" ty="-22.50244140625"> + <y:Point x="690.9591397849463" y="450.0"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e15" source="n13" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-57.72027803308823" sy="-0.0" tx="70.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e16" source="n14" target="n15"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e17" source="n9" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e18" source="n16" target="n17"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="52.0791015625" sy="-0.0" tx="-22.5" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e19" source="n17" target="n18"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="-0.0" tx="-22.5" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e20" source="n18" target="n19"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e21" source="n19" target="n20"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e22" source="n17" target="n21"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-8.984374163227692" anchorY="33.38574326459093" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="1.0" upY="1.8369701987210297E-16" visible="true" width="53.025390625" x="-8.9843741632277" y="33.38574326459093">Data RX<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e23" source="n21" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e24" source="n23" target="n22"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="47.39453125"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e25" source="n15" target="n23"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="52.0791015625" sy="-0.0" tx="-52.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e26" source="n33" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="74.67837017325945" sy="0.0" tx="-54.10141429227957" ty="2.8205882352940534"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e27" source="n18" target="n24"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="-0.0" tx="-52.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="52.017578125" x="5.0" y="-8.984375">Data TX<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e28" source="n25" target="n26"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="20.958343505859375"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e29" source="n19" target="n27"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="-0.0" tx="52.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="31.9375" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="55.09375" x="-60.05029296875" y="-15.96875">Mode +Code RX<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e30" source="n27" target="n28"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-52.0791015625" sy="-0.0" tx="52.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e31" source="n28" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-36.96875000000001"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e32" source="n20" target="n29"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="-0.0" tx="-52.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="90.595703125" x="5.0" y="-8.984375">Mode Code TX<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e33" source="n20" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="-0.0" tx="25.960078006338012" ty="-36.96875000000001"> + <y:Point x="550.0" y="375.0"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e34" source="n29" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="54.07910156249999" ty="-22.038002980625937"> + <y:Point x="1023.4569892473116" y="427.96199701937405"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e35" source="n12" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="66.59301075268809" ty="-20.913365255376334"> + <y:Point x="591.5930107526881" y="675.0"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_DEFAULT_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e36" source="n24" target="n34"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e37" source="n34" target="n26"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1098.953156502016" y="504.5677755376345"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e38" source="n23" target="n33"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e39" source="n26" target="n31"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="1.61619833669306" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e40" source="n31" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="54.113318014705555" ty="-12.169999999999845"> + <y:Point x="823.2375651041662" y="437.83000000000015"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/core1553brm_as250/irq_handler.png b/IBSW/doc/images/core1553brm_as250/irq_handler.png new file mode 100644 index 0000000000000000000000000000000000000000..54c72025ca669ea005561648bb3db58c64646428 Binary files /dev/null and b/IBSW/doc/images/core1553brm_as250/irq_handler.png differ diff --git a/IBSW/doc/images/core1553brm_as250/split_packetstreams.graphml b/IBSW/doc/images/core1553brm_as250/split_packetstreams.graphml new file mode 100644 index 0000000000000000000000000000000000000000..c02b15598f87b007805ecf98b7ef5fa0e886163e --- /dev/null +++ b/IBSW/doc/images/core1553brm_as250/split_packetstreams.graphml @@ -0,0 +1,1221 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.1--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="60.0" width="60.0" x="826.6959602414554" y="674.8593750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="126.28515625" x="-156.3385383664554" y="21.015625">MIL-STD-1553 IRQ<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="-30.053382116455396" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_SIGNAL"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="800.0964285714285" y="591.9218750000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="80.458984375" x="16.370039482526863" y="11.984375">Peek Header</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="794.2975042784651" y="0.0"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490283" y="24.441406250000057">DD +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="742.5963570668522" y="501.9218750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="176.40085013079093" y="509.4218750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="44.5703125" x="-58.039994959677415" y="8.03125">Return<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="-13.469682459677415" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="153.19906334005373" x="688.4968253968253" y="439.9843750000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="137.03125" x="8.083906670026863" y="11.984375">Inspect Packet Source</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="74.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="742.5963570668522" y="374.9843750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="255.29937759835755" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="94.099609375" x="9.549726982526863" y="11.984375">Migrate packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="901.6960317460317" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="94.099609375" x="9.549726982526863" y="11.984375">Migrate packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="708.4968253968253" y="256.7265625000001"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="91.3984375" x="10.900312920026863" y="11.984375">Extract packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="230.40124695618775" y="213.2578125000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.16310440049034" y="24.441406250000057">GND +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="876.7979011038619" y="213.2578125000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490283" y="24.441406250000057">OBC +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="54.90286249777373" y="213.2578125000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="59.962890625" x="17.417010650490333" y="24.441406250000057">GND Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n13"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="1076.5963138022748" y="213.2578125000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="58.50390625" x="18.146502837990283" y="24.441406250000057">OBC Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n14"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="138.19906334005373" x="33.2017867907372" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="116.916015625" x="10.641523857526863" y="5.0">Register in Ground +packet size buffer </y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="67.09953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n15"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="138.19906334005373" x="1054.8952380952383" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="115.3046875" x="11.447187920026863" y="5.0">Register in OBC +packet size buffer </y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="67.09953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n16"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.19906334005373" x="554.2977620567716" y="256.7265625000001"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="114.244140625" x="3.477461357526863" y="11.984375">Check packet CRC</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="58.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n17"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="592.3972937267985" y="139.7890625000001"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n18"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.19906334005373" x="371.04853407527645" y="141.3203125000001"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="103.580078125" x="8.809492607526863" y="5.0">Undefined state, +drop DD buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="58.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n19"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.19906334005373" x="130.80131846076407" y="141.3203125000001"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="70.0" x="25.599531670026863" y="11.984375">Raise error</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="58.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n20"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.19906334005373" x="705.4968253968253" y="184.7890625000001"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="70.0" x="25.599531670026863" y="11.984375">Raise error</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="58.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n21"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="70.8595330752687" width="216.392366795699" x="976.701934639593" y="638.7468261317206"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="198.431640625" x="8.980363085349381" y="6.24226653763435">Note: This function must +be chained to the 1553 IRQ +so that it is executed +AFTER the 1553 driver ISR</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="106.19618339784938" y="33.42976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n22"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="81.8595330752687" width="278.392366795699" x="255.29937759835758" y="633.2468261317206"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="71.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="263.2421875" x="7.575089647849495" y="4.94539153763435">AD ... Acquisition Data +DD ... Distribution Data +ATR ... Acquisition Transfer Request +GND ... Ground +OBC ... On-Board Computer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="137.1961833978495" y="38.92976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-30.0" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n2" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="37.91876477039227" sy="28.425781250000057" tx="45.27962533602147" ty="-20.96875"> + <y:Point x="879.6147250118477" y="109.78906250000011"/> + <y:Point x="1208.0943729398682" y="109.78906250000011"/> + <y:Point x="1208.0943729398682" y="554.4218750000002"/> + <y:Point x="901.9755855774769" y="554.4218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.639812668010748" sy="-20.96875" tx="22.50244140625" ty="0.0"> + <y:Point x="834.0561475734446" y="524.4218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="0.0" tx="15.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="82.9140625" x="-102.2245872781125" y="-8.984374999999773">Buffer empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.03235691986891812" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n3" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-22.5" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_DEFAULT_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n5" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n6" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="0.0" tx="56.59953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.40234375" x="-71.14019057040707" y="-8.98437499999983">Ground<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.056331115252694915" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n6" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="-56.59953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="30.056640625" x="22.999982555133442" y="-8.984374999999773">OBC<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.2431018694726752" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n6" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-22.5" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="8.984357555133442" anchorY="-19.12402343749983" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" visible="true" width="38.072265625" x="-8.984392444866558" y="-57.19628906249983">Other<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n2" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-37.91876477039227" sy="30.363281250000057" tx="28.29976583501343" ty="-20.96875"> + <y:Point x="803.7771954710631" y="109.78906250000011"/> + <y:Point x="340.19851244298764" y="109.78906250000011"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n2" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="18.959382385196136" sy="43.61328125000006" tx="28.29976583501343" ty="-20.96875"> + <y:Point x="860.6553426266515" y="124.78906250000011"/> + <y:Point x="986.5951665906617" y="124.78906250000011"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n2" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="47.39453125000006" tx="56.616105780037515" ty="0.0"> + <y:Point x="841.6959602414554" y="277.6953125000001"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e12" source="n7" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-34.09920634920633" sy="-20.992187500000227" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e13" source="n8" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-34.09920634920638" sy="-20.945312500000227" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e14" source="n7" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-56.59953167002686" sy="0.0" tx="69.09953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e15" source="n8" target="n15"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="56.59953167002686" sy="0.0" tx="-69.09953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e16" source="n15" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e17" source="n14" target="n12"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e18" source="n14" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="-45.27962533602147" ty="-20.96875"> + <y:Point x="102.30131846076407" y="433.4531250000002"/> + <y:Point x="240.29930609378127" y="433.4531250000002"/> + <y:Point x="240.29930609378127" y="576.9218750000002"/> + <y:Point x="811.4163349054339" y="576.9218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e19" source="n15" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="22.63981266801079" ty="-20.96875"> + <y:Point x="1123.9947697652651" y="539.4218750000002"/> + <y:Point x="879.3357729094662" y="539.4218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e20" source="n9" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-56.57291956685219" sy="0.0" tx="60.5680552462095" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e21" source="n16" target="n17"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e22" source="n17" target="n18"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="0.0" tx="60.59953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="43.884765625" x="-71.96832591331076" y="-8.984374999999886">Invalid<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e23" source="n18" target="n19"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-60.59953167002686" sy="0.0" tx="60.59953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e24" source="n19" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-15.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e25" source="n17" target="n20"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="0.0" ty="-20.958343505859375"> + <y:Point x="766.0963570668522" y="162.2890625000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="33.84765625" x="16.728159094160446" y="-8.984374999999886">Valid<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.10983954449523646" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e26" source="n20" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="60.5680552462095" sy="0.0" tx="0.0" ty="-20.96875"> + <y:Point x="856.6959602414554" y="205.7578125000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e27" source="n2" target="n18"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-18.959382385196136" sy="44.55078125000006" tx="0.0" ty="-20.96875"> + <y:Point x="822.7365778562593" y="124.78906250000011"/> + <y:Point x="431.6480657453033" y="124.78906250000011"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/core1553brm_as250/split_packetstreams_direct_buffer_drop.graphml b/IBSW/doc/images/core1553brm_as250/split_packetstreams_direct_buffer_drop.graphml new file mode 100644 index 0000000000000000000000000000000000000000..b74aef3f8078af1bc07347ab40d532d688406b9d --- /dev/null +++ b/IBSW/doc/images/core1553brm_as250/split_packetstreams_direct_buffer_drop.graphml @@ -0,0 +1,1034 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.1--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="60.0" width="60.0" x="826.6959602414554" y="663.8593750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="126.28515625" x="-156.3385383664554" y="21.015625">MIL-STD-1553 IRQ<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="-30.053382116455396" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_SIGNAL"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="800.0964285714285" y="591.9218750000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="80.458984375" x="16.370039482526863" y="11.984375">Peek Header</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="794.2975042784651" y="19.234375"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490283" y="24.441406250000057">DD +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="742.5963570668522" y="501.9218750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="510.2976905521954" y="509.4218750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="44.5703125" x="-58.039994959677415" y="8.03125">Return<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="-13.469682459677415" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="153.19906334005373" x="688.4968253968253" y="439.9843750000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="137.03125" x="8.083906670026863" y="11.984375">Inspect Packet Source</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="74.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="742.5963570668522" y="374.9843750000002"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="575.2977620567716" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="94.099609375" x="9.549726982526863" y="11.984375">Migrate packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="113.19906334005373" x="871.695888736879" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="94.099609375" x="9.549726982526863" y="11.984375">Migrate packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="54.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="550.3996314146018" y="232.4921875000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.16310440049034" y="24.441406250000057">GND +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="908.7977580947093" y="232.4921875000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490283" y="24.441406250000057">OBC +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="388.79970291917823" y="232.4921875000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="59.962890625" x="17.417010650490333" y="24.441406250000057">GND Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="1037.4996620744523" y="232.4921875000001"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="58.50390625" x="18.146502837990283" y="24.441406250000057">OBC Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n13"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="138.19906334005373" x="367.09862721214165" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="116.916015625" x="10.641523857526863" y="5.0">Register in Ground +packet size buffer </y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="67.09953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n14"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="138.19906334005373" x="1015.7985863674157" y="376.5156250000002"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="115.3046875" x="11.447187920026863" y="5.0">Register in OBC +packet size buffer </y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="67.09953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n15"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.19906334005373" x="704.4968253968253" y="160.5546875000001"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="103.580078125" x="8.809492607526863" y="5.0">Undefined state, +drop DD buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="58.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n16"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.19906334005373" x="464.6981588821685" y="160.5546875000001"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="74.25390625" x="23.472578545026863" y="5.0">Create +error report</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="58.59953167002686" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n17"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="70.8595330752687" width="216.392366795699" x="937.6052829117705" y="652.8593750000002"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="58.375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="198.431640625" x="8.980363085349381" y="6.24226653763435">Note: This function must +be chained to the 1553 IRQ +so that it is executed +AFTER the 1553 driver ISR</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="106.19618339784938" y="33.42976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n18"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="81.8595330752687" width="278.392366795699" x="367.0986272121416" y="641.9998419247315"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="71.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="263.2421875" x="7.575089647849495" y="4.94539153763435">AD ... Acquisition Data +DD ... Distribution Data +ATR ... Acquisition Transfer Request +GND ... Ground +OBC ... On-Board Computer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="137.1961833978495" y="38.92976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-30.0" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n2" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="37.91876477039227" sy="28.425781250000057" tx="45.27962533602147" ty="-20.96875"> + <y:Point x="879.6147250118477" y="129.0234375000001"/> + <y:Point x="1168.9977212120457" y="129.0234375000001"/> + <y:Point x="1168.9977212120457" y="554.4218750000002"/> + <y:Point x="901.9755855774769" y="554.4218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.639812668010748" sy="-20.96875" tx="22.50244140625" ty="0.0"> + <y:Point x="834.0561475734446" y="524.4218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="0.0" tx="15.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="82.9140625" x="-91.40405137045582" y="-8.984374999999773">Buffer empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.03235691986891812" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n3" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-22.5" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_DEFAULT_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n5" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n6" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="0.0" tx="56.59953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.40234375" x="-51.280858047476386" y="-8.98437499999983">Ground<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.056331115252694915" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n6" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="-56.59953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="30.056640625" x="15.706891705160842" y="-8.984374999999773">OBC<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.2431018694726752" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n6" target="n15"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-22.5" tx="0.0" ty="20.958343505859375"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="9.103856529624977" anchorY="-34.24735361486239" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="-0.9999802378229391" upY="0.00628680869584734" visible="true" width="38.072265625" x="-9.103891419357819" y="-72.318866849008">Other<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="-0.006286850109850306" distance="30.0" distanceToCenter="true" position="center" ratio="0.23437313702842366" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n2" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-37.91876477039227" sy="30.363281250000057" tx="28.29976583501343" ty="-20.96875"> + <y:Point x="803.7771954710631" y="129.0234375000001"/> + <y:Point x="660.1968969014017" y="129.0234375000001"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n2" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="18.959382385196136" sy="43.61328125000006" tx="-30.408633193554465" ty="-20.97604371076477"> + <y:Point x="860.6553426266515" y="144.0234375000001"/> + <y:Point x="897.8867872133515" y="144.0234375000001"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n7" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-34.09920634920633" sy="-20.992187500000227" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e12" source="n8" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="27.900793650793617" sy="-20.960937500000227" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e13" source="n7" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-56.59953167002686" sy="0.0" tx="69.09953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e14" source="n8" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="56.59953167002686" sy="0.0" tx="-69.09953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e15" source="n14" target="n12"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e16" source="n13" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e17" source="n13" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="-45.27962533602147" ty="-20.96875"> + <y:Point x="436.1981588821685" y="433.4531250000002"/> + <y:Point x="560.2976905521954" y="433.4531250000002"/> + <y:Point x="560.2976905521954" y="576.9218750000002"/> + <y:Point x="811.4163349054339" y="576.9218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e18" source="n14" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="22.63981266801079" ty="-20.96875"> + <y:Point x="1084.8981180374426" y="539.4218750000002"/> + <y:Point x="879.3357729094662" y="539.4218750000002"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e19" source="n15" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-60.59953167002686" sy="0.0" tx="60.59953167002686" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e20" source="n16" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-15.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e21" source="n2" target="n15"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-18.959382385196136" sy="44.55078125000006" tx="0.0" ty="-20.96875"> + <y:Point x="822.7365778562593" y="144.0234375000001"/> + <y:Point x="765.0963570668522" y="144.0234375000001"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/core1553brm_as250/split_packetstreams_direct_buffer_drop.png b/IBSW/doc/images/core1553brm_as250/split_packetstreams_direct_buffer_drop.png new file mode 100644 index 0000000000000000000000000000000000000000..93f29e054fb64150b9b20335962dfe80474aff6b Binary files /dev/null and b/IBSW/doc/images/core1553brm_as250/split_packetstreams_direct_buffer_drop.png differ diff --git a/IBSW/doc/images/cpus_buffer/cpus_get_free.graphml b/IBSW/doc/images/cpus_buffer/cpus_get_free.graphml new file mode 100644 index 0000000000000000000000000000000000000000..6a1d3b6a7ef39444332ee458a83d5604df47cac0 --- /dev/null +++ b/IBSW/doc/images/cpus_buffer/cpus_get_free.graphml @@ -0,0 +1,559 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.16--> + <key attr.name="Description" attr.type="string" for="graph" id="d0"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key for="graphml" id="d7" yfiles.type="resources"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d0"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="-118.76230158730158" y="330.4375"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="18.0" y="18.0"/> + <y:StyleProperties> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="-113.76230158730158" y="14.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="136.45703125" x="-53.228515625" y="-31.184375000000045">Return (1024 - usage)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-13.215625000000045" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.158203125" x="3.421161954365047" y="112.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="82.708984375" x="19.224609375" y="11.984375">usage - 1024</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="58.5791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="121.158203125" x="-159.34140314980158" y="222.0"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="105.21484375" x="7.9716796875" y="11.984375">Get buffer usage</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="58.5791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="-121.26230158730158" y="110.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="29.78245315338438" y="195.57421874999994"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="44.224609375" x="25.286151275490333" y="31.425781250000057">Packet +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="41.50026351686505" y="6.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="211.76282862103167" y="14.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="56.01953125" x="-13.009765625" y="-31.184375000000045">Return 0<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-13.215625000000045" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.009765625" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n5" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-47.39296339522297" sy="0.0" tx="60.59646205242229" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.958343505859375" tx="0.0" ty="22.50244140625"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n4" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-22.50244140625" tx="0.0" ty="14.990234375"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n2" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n6" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n4" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.50244140625" sy="0.0" tx="-60.5964620524223" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="48.408203125" x="4.997555590432796" y="-8.984375">≥ 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n6" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.502441406250014" sy="0.0" tx="-14.990234375" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="48.408203125" x="38.42473607138976" y="-8.984375">≥ 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d7"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/cpus_buffer/cpus_get_free.png b/IBSW/doc/images/cpus_buffer/cpus_get_free.png new file mode 100644 index 0000000000000000000000000000000000000000..bbb82ed0c362320f0be9358e1abf474247cc754c Binary files /dev/null and b/IBSW/doc/images/cpus_buffer/cpus_get_free.png differ diff --git a/IBSW/doc/images/cpus_buffer/sliding_window_buffer.graphml b/IBSW/doc/images/cpus_buffer/sliding_window_buffer.graphml new file mode 100644 index 0000000000000000000000000000000000000000..433a82547071a0420cdb777043a2d8041f8689d7 --- /dev/null +++ b/IBSW/doc/images/cpus_buffer/sliding_window_buffer.graphml @@ -0,0 +1,880 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.3--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="241.23769841269842" y="0.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="216.9375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="105.21484375" x="19.4716796875" y="11.984375">Get buffer usage</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="381.84375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="135.689453125" x="4.234375" y="11.984375">(2048 - buffer usage)</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="238.73769841269842" y="446.72047057526834"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="585.3628906249999"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="100.26953125" x="21.9443359375" y="5.0">Add packet +to packet buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="238.73769841269842" y="288.875"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="375.8757936507937" y="454.22047057526834"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="78.109375" x="-24.054687499999943" y="43.552734375">Return Error<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="1.887379141862766E-15" nodeRatioY="0.5" offsetX="0.0" offsetY="13.552734375" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="375.8757936507937" y="591.3316406249999"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="96.689453125" x="-33.3447265625" y="42.533862500000055">Return Success<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="12.533862500000055" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="68.36328125000006" width="144.158203125" x="23.669112723214297" y="572.1499999999999"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="106.919921875" x="18.619140625" y="11.228515625">Add empty +segment to next +frame boundary</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="32.181640625"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="-3.885780586188048E-16" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="15.000263516865076" y="381.84375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="131.875" x="6.1416015625" y="11.984375">(1024 - buffer usage)</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="64.57936507936508" y="482.07207031249993"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="70.0"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="96.888671875" x="23.634765625" y="11.984375">Get packet size</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="238.73769841269842" y="141.9375"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n13"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="32.68090911637474" y="99.51328124999998"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="44.224609375" x="25.286151275490333" y="31.425781250000057">Packet +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <edge id="e0" source="n0" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n13" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="42.628443124857554" sy="0.0" tx="-72.0791015625" ty="0.0"> + <y:Point x="189.15859685019842" y="146.90781250000003"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n5" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="0.0" ty="-15.0"> + <y:Point x="390.8757936507937" y="311.375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="43.966993834480434" y="-8.984375">≥ 2048<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n5" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="-24.204104565817204" y="5.0">≥ 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n2" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n3" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="-15.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="58.474609375" x="4.999996996682796" y="-8.984363409106606">< packet<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="1.9999999999997726" distanceToCenter="false" position="center" ratio="0.0" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n4" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.958343505859375" tx="-47.39296339522298" ty="0.0"> + <y:Point x="261.2376984126985" y="717.9078125"/> + <y:Point x="-4.9997364831349245" y="717.9078125"/> + <y:Point x="-4.9997364831349245" y="146.90781250000003"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n4" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="72.0997576713562" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n8" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-8.668849206349222" sy="34.186718749999955" tx="-46.4160080003421" ty="11.081423338993375"> + <y:Point x="87.07936507936508" y="711.445945866667"/> + <y:Point x="2.524263516865048" y="711.445945866667"/> + <y:Point x="2.524263516865048" y="157.9892358389934"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n8" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="72.09975767135622" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e12" source="n5" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="0.0" tx="0.0" ty="-20.96875"> + <y:Point x="87.07936507936508" y="311.375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="-114.5982889326792" y="-8.984375">< 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="1.9999999999998863" distanceToCenter="false" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e13" source="n9" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e14" source="n10" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.50244140625" tx="-8.668849206349222" ty="-5.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="58.474609375" x="-29.237308199443518" y="4.997546386718682">< packet<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="20.697265624999737" distanceToCenter="false" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e15" source="n11" target="n12"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e16" source="n12" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e17" source="n12" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="15.0" ty="0.0"> + <y:Point x="427.01979365079376" y="164.4375"/> + <y:Point x="427.01979365079376" y="469.22047057526834"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="16.674159277459523" y="-8.984375">> 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.10233491933575473" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e18" source="n10" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.50244140625" sy="0.0" tx="-13.0" ty="-20.93215059166596"> + <y:Point x="248.23769841269842" y="504.57207031249993"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/cpus_buffer/sliding_window_buffer.png b/IBSW/doc/images/cpus_buffer/sliding_window_buffer.png new file mode 100644 index 0000000000000000000000000000000000000000..1347b5dba653fda11fd063165ec4559c1fb6ad49 Binary files /dev/null and b/IBSW/doc/images/cpus_buffer/sliding_window_buffer.png differ diff --git a/IBSW/doc/images/ibsw_interface/GetLinkCapacity.graphml b/IBSW/doc/images/ibsw_interface/GetLinkCapacity.graphml new file mode 100644 index 0000000000000000000000000000000000000000..03afc67e3929ab3f220fb0e3380f80c3c790c539 --- /dev/null +++ b/IBSW/doc/images/ibsw_interface/GetLinkCapacity.graphml @@ -0,0 +1,592 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.2--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="255.0" y="405.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="187.1640625" x="72.41796875" y="11.015625">CrIbMilBusGetLinkCapacity<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="0.0" offsetX="32.41796875" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="202.9208984375" y="329.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="105.21484375" x="19.4716796875" y="11.984375">Get buffer usage</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="439.60154403700966" y="302.60546874999994"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.16310440049034" y="24.441406250000057">AD +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="252.5" y="227.39453125000006"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="569.0" y="140.39453125000006"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="56.01953125" x="-13.009765625" y="-27.378906250000057">Return 0<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-9.410156250000057" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="377.9208984375" y="230.66796874999994"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="75.080078125" x="34.5390625" y="11.984375">usage-1024</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="36.8595330752687" width="211.2752849603495" x="323.1231710026408" y="445.0"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.59375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="169.626953125" x="20.824165917674748" y="9.63289153763435">AD ... Acquisition Data</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="103.63764248017475" y="16.42976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="260.0" y="140.39453125000006"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="136.45703125" x="-53.228515625" y="-31.378906250000057">Return (1024 - usage)<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-13.410156250000057" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="427.5" y="132.89453125000006"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.0" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n3" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="-0.0" tx="-72.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="1.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="5.0" y="-8.351715807185087">≥ 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="20.556479708812905" distanceToCenter="false" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_DEFAULT_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n2" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n1" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n3" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n5" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n8" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="24.07080078125" y="-8.984374999999943">≥ 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n8" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/ibsw_interface/GetLinkCapacity.png b/IBSW/doc/images/ibsw_interface/GetLinkCapacity.png new file mode 100644 index 0000000000000000000000000000000000000000..11fc08aa0de4d463b044f7b4a9fa7837b253dd7f Binary files /dev/null and b/IBSW/doc/images/ibsw_interface/GetLinkCapacity.png differ diff --git a/IBSW/doc/images/ibsw_logical_model.graphml b/IBSW/doc/images/ibsw_logical_model.graphml new file mode 100644 index 0000000000000000000000000000000000000000..43b153f786dcb10e8ee44d44c7005b10f1013542 --- /dev/null +++ b/IBSW/doc/images/ibsw_logical_model.graphml @@ -0,0 +1,951 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.16.1--> + <key attr.name="Description" attr.type="string" for="graph" id="d0"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key for="graphml" id="d7" yfiles.type="resources"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d0"/> + <node id="n0"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="1406.0085199004977" y="319.95454545454555"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#DCBA00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="103.703125" x="-36.8515625" y="-21.96875">IFSW Entry Point<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_INTERMEDIATE_CATCHING"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="1062.237165363658" y="287.909090909091"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="59.875" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="72.853515625" x="35.019137709888014" y="17.107954545454547">Syncpulse +and +Notification +Timers</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="603.5609748874674" y="287.909090909091"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="34.5390625" x="54.17636427238807" y="31.07670454545456">1553 +Link</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n3"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="106.0909090909091" width="124.89179104477611" x="650.815873015873" y="885.9545454545455"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#DCBA00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="35.23046875" x="44.830661147388014" y="44.061079545454504">IASW</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="185.0909090909091" width="181.0" x="1159.8751243781096" y="445.0000000000001"/> + <y:Fill color="#FFFFFFE6" color2="#FFCC00" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="49.2109375" x="65.89453125" y="76.5767045454545">IBSW +(CPU 0)</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="1082.5998637763564" y="801.6558922558925"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#DCBA00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="71.1484375" x="35.871676772388014" y="31.076704545454504">Event +Translation</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="458.92380952380955" y="490.5000000000001"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#DCBA00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="57.724609375" x="42.58359083488807" y="31.07670454545456">IBSW +Interface</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="756.4530383795309" y="287.909090909091"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="31.099609375" x="55.896090834888014" y="31.076704545454547">SpW +Link</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="909.3451018715946" y="287.909090909091"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="57.724609375" x="42.583590834888014" y="31.076704545454547">SysCtl +Interface</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="68.0909090909091" width="98.89179104477611" x="344.875" y="339.659090909091"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#CC99FF" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="51.578125" x="23.65683302238807" y="11.092329545454561">Sliding +Window +Buffer</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n10"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="68.0909090909091" width="98.89179104477611" x="423.7670634920635" y="339.659090909091"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#CC99FF" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="44.224609375" x="27.33359083488807" y="11.092329545454561">PUS +Packet +Buffer</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n11"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="976.9831971096899" y="490.5000000000001"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="51.25" x="45.820895522388014" y="24.09232954545456">EDAC +Error +Handler</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n12"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="865.8455668088134" y="490.5000000000001"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="58.3046875" x="42.293551772388014" y="31.07670454545456">Memory +Scrubber</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n13"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="1357.0713545368399" y="741.0909090909092"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="45.291015625" x="48.80038770988813" y="31.076704545454504">FLASH +Access</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n14"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="641.8158730158732" y="490.5000000000001"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="64.703125" x="39.094333022388014" y="24.09232954545456">Time +and +Watchdog</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n15"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="1215.1292288557215" y="287.909090909091"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="56.705078125" x="43.09335645988813" y="31.076704545454547">IRQ +Dispatch</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n16"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="77.0909090909091" width="107.0" x="853.1538320303248" y="900.4545454545455"/> + <y:Fill color="#FFFFFFE6" color2="#FFCC00" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="58.955078125" x="24.0224609375" y="22.576704545454504">Cyclical +Activities</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n17"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="77.0909090909091" width="107.0" x="853.1538320303248" y="807.0227272727273"/> + <y:Fill color="#FFFFFFE6" color2="#FFCC00" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.18359375" x="23.908203125" y="22.576704545454504">Error Log +to FLASH</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n18"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="77.0909090909091" width="107.0" x="853.1538320303248" y="713.5909090909092"/> + <y:Fill color="#FFFFFFE6" color2="#FFCC00" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.71875" x="21.640625" y="22.576704545454504">FBF +Operation</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n19"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="753.8307199123433" y="490.5000000000001"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="33.724609375" x="54.583590834888014" y="24.09232954545456">RAM +Error +Log</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n20"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="1235.4919272684199" y="741.0909090909092"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="60.80078125" x="41.04550489738813" y="24.092329545454504">Memory +Partitions +Allocator</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n21"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="116.03905723905724" width="100.0" x="971.3768479033406" y="790.6818181818182"/> + <y:Fill color="#FFFFFFE6" color2="#FFCC00" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="35.25390625" x="32.373046875" y="35.066403619528614">IBSW +Main +Loop</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n22"> + <data key="d5"/> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="94.0909090909091" width="142.8917910447761" x="1349.5626243781096" y="412.0000000000001"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="35.25390625" x="53.81894239738813" y="31.07670454545456">IBSW +Init</y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n23"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="1406.008519900498" y="568.1363636363637"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="67.134765625" x="-18.5673828125" y="44.472987975045044">DPU Reset<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="14.4729879750451" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n1" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="47.04545454545455" tx="0.0" ty="-90.5142045454545"> + <y:Point x="1133.6830608860462" y="397.5000000000001"/> + <y:Point x="1250.3751243781096" y="397.5000000000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n2" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-26.68213064143538" sy="38.75" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n3" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-53.04068270596599" tx="0.0" ty="47.04545454545456"> + <y:Point x="713.1378227908081" y="792.0"/> + <y:Point x="530.3697050461976" y="792.0"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n4" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="33.9375" sy="83.9517045454545" tx="0.0" ty="-47.04545454545455"> + <y:Point x="1284.3126243781096" y="725.5909090909092"/> + <y:Point x="1154.0457592987445" y="725.5909090909092"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n4" target="n19"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-56.5625" sy="70.6392045454545" tx="0.0" ty="47.04545454545455"> + <y:Point x="1193.8126243781096" y="661.5909090909092"/> + <y:Point x="825.2766154347312" y="661.5909090909092"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n4" target="n15"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="36.200000000000045" sy="-82.9517045454545" tx="0.0" ty="47.04545454545455"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n4" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-33.9375" sy="83.9517045454545" tx="0.0" ty="47.04545454545455"> + <y:Point x="1216.4376243781096" y="677.5909090909092"/> + <y:Point x="713.2617685382611" y="677.5909090909092"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n4" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-11.3125" sy="89.8267045454545" tx="33.467006398670605" ty="33.05586381392027"> + <y:Point x="1239.0626243781096" y="693.5909090909092"/> + <y:Point x="578.000302061123" y="693.5909090909092"/> + <y:Point x="578.000302061123" y="584.5909090909092"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n4" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-72.40000000000009" sy="-54.326704545454504" tx="19.894621111472247" ty="42.6142271948936"> + <y:Point x="1177.9751243781095" y="429.5000000000001"/> + <y:Point x="847.7935550133911" y="429.5000000000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n4" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-36.200000000000045" sy="-82.9517045454545" tx="35.72294776119395" ty="30.63920454545456"> + <y:Point x="1214.1751243781096" y="413.5000000000001"/> + <y:Point x="1016.5139451551768" y="413.5000000000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n4" target="n20"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="56.56246084253894" sy="70.63920454548975" tx="0.0" ty="-47.045454545454504"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n4" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-90.5" sy="0.0" tx="47.03964552238803" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e12" source="n4" target="n12"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-79.1875" sy="43.826704545454504" tx="0.0" ty="47.04545454545455"> + <y:Point x="1171.1876243781096" y="645.5909090909092"/> + <y:Point x="937.2914623312013" y="645.5909090909092"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e13" source="n4" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="79.1875" sy="43.826704545454504" tx="0.0" ty="-47.04545454545455"> + <y:Point x="1329.5626243781096" y="645.5909090909092"/> + <y:Point x="1428.517250059228" y="645.5909090909092"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e14" source="n4" target="n21"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="11.3125" sy="89.8267045454545" tx="0.0" ty="-31.88316498316499"> + <y:Point x="1261.6876243781096" y="709.5909090909092"/> + <y:Point x="1021.3768479033406" y="709.5909090909092"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e15" source="n4" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-81.14579683361887" sy="-40.07701779000598" tx="0.0" ty="47.045787464488626"> + <y:Point x="1169.2293275444908" y="440.6666666666668"/> + <y:Point x="675.0068704098553" y="440.6666666666668"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e16" source="n5" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="47.04545454545455" tx="0.0" ty="53.04068270596599"> + <y:Point x="1154.0457592987445" y="1035.4133522727273"/> + <y:Point x="713.2617685382611" y="1035.4133522727273"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e17" source="n6" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-47.046139845207506" sy="0.0" tx="0.0" ty="34.02339311079541"> + <y:Point x="394.32089552238807" y="537.5454545454547"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e18" source="n6" target="n18"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.50987793557431" sy="41.28579466901431" tx="-38.540283203125" ty="0.0"> + <y:Point x="552.8795829817719" y="752.1363636363637"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e19" source="n7" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-19.918171653741297" sy="42.60859472978407" tx="-20.010593562357144" ty="-42.6063560554399"> + <y:Point x="792.175986140725" y="397.5000000000001"/> + <y:Point x="501.79134683724243" y="397.5000000000001"/> + <y:Point x="501.79134683724243" y="476.8181818181819"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e20" source="n8" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-35.722947761194064" sy="30.63920454545456" tx="0.0" ty="-47.04545454545455"> + <y:Point x="945.0680496327884" y="413.5000000000001"/> + <y:Point x="530.3697050461976" y="413.5000000000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e21" source="n9" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="394.32089552238807" y="334.95454545454555"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e22" source="n10" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="34.04545454545455" tx="-36.309027372900914" ty="-29.88580877130653"> + <y:Point x="473.2129886282872" y="490.5000000000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e23" source="n12" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-47.04545454545455" tx="28.578358208955137" ty="-37.389204545454504"> + <y:Point x="937.2914623312013" y="459.0000000000001"/> + <y:Point x="558.9480632551529" y="459.0000000000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e24" source="n14" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-47.03964552238813" sy="0.0" tx="47.039645522388014" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e25" source="n16" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e26" source="n19" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-47.04545454545455" tx="36.30902737290137" ty="-29.88580877130653"> + <y:Point x="825.2766154347312" y="475.0000000000001"/> + <y:Point x="587.5264214641081" y="475.0000000000001"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e27" source="n21" target="n17"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e28" source="n21" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e29" source="n21" target="n18"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="none"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e30" source="n0" target="n22"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e31" source="n4" target="n23"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e32" source="n22" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d7"> + <y:Resources/> + </data> +</graphml> diff --git a/IBSW/doc/images/ibsw_logical_model.png b/IBSW/doc/images/ibsw_logical_model.png new file mode 100644 index 0000000000000000000000000000000000000000..2ffd6d8a1c7ca276d6b5f0cc975f64bdcccfa9bb Binary files /dev/null and b/IBSW/doc/images/ibsw_logical_model.png differ diff --git a/IBSW/doc/images/irq_dispatch/irq_dispatch.graphml b/IBSW/doc/images/irq_dispatch/irq_dispatch.graphml new file mode 100644 index 0000000000000000000000000000000000000000..1d6abded76bd166693e4123f342da6652c1a1dde --- /dev/null +++ b/IBSW/doc/images/irq_dispatch/irq_dispatch.graphml @@ -0,0 +1,2138 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.3--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Artifact.withShadow"> + <y:Geometry height="55.0" width="60.0" x="1594.5936507936508" y="637.234375"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#333333" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="94.8671875" x="-17.43359375" y="-30.499370155038832">IRL Queue Pool<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-12.530620155038832" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ARTIFACT_TYPE_DATA_STORE"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Artifact.withShadow"> + <y:Geometry height="55.0" width="60.0" x="557.7158730158731" y="257.8125"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#333333" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="106.36328125" x="-23.181640625" y="-28.804840970611053">IRL Callback Pool<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-10.836090970611053" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ARTIFACT_TYPE_DATA_STORE"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="104.0" width="80.0" x="1592.027380952381" y="374.78125"/> + <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B7C9E3" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="34.01171875" x="22.994140625" y="4.0">IRL 1</y:NodeLabel> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="73.84375" modelName="custom" textColor="#000000" visible="true" width="54.2265625" x="2.0" y="29.96875">IRQ1_0 +IRQ1_1 +IRQ1_2 +.... +IRQ1_14<y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="104.0" width="80.0" x="1057.8630952380952" y="374.78125"/> + <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B7C9E3" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="34.01171875" x="22.994140625" y="4.0">IRL 2</y:NodeLabel> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="73.84375" modelName="custom" textColor="#000000" visible="true" width="54.2265625" x="2.0" y="29.96875">IRQ2_0 +IRQ2_1 +IRQ2_2 +.... +IRQ2_31<y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="727.691533358135" y="264.34375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="64.005859375" x="20.076171875" y="11.984375">Fetch Slot</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="757.270634920635" y="163.90625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="65.388671875" x="49.0" y="-15.96875">IRL Slot +Available?<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="-0.5" offsetX="4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="660.4638068461354" y="171.40625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="24.923828125" x="-39.57042435602261" y="8.03125">Fail<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="-14.646596231022613" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_TERMINATE"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="727.691533358135" y="335.078125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="67.5625" x="18.2978515625" y="11.984375">Map to IRL</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="1248.7400793650793" y="374.78125"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="63.396484375" x="49.0" y="-8.984375">Select IRL<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="-0.5" offsetX="4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="1452.5805555555555" y="163.90625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="71.88671875" x="-75.88671875" y="0.0">Identify IRL<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="-0.5" nodeRatioX="-0.5" nodeRatioY="-0.5" offsetX="-4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1856.1859778025794" y="643.765625"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="54.91796875" x="24.6201171875" y="5.0">Execute +Callback</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1722.027644469246" y="643.765625"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="70.234375" x="16.9619140625" y="5.0">Fetch +Queue Slot</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="1751.606746031746" y="547.765625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="54.91796875" x="-58.91796875" y="-22.93077097834555">Callback +Priority?<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.21798891517324614" nodeRatioX="-0.5" nodeRatioY="-0.5" offsetX="-4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n13"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="1617.027380952381" y="555.265625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="44.5703125" x="-55.105947875235415" y="8.03125">Return<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="-10.535635375235415" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n14"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="86.33367139959432" width="62.1906693711976" x="98.1546653144012" y="482.6403206227087"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#FF6600" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="98.154296875" x="-98.154296875" y="50.39617139959432">Low Priority +Callback Queue<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="0.0" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_TIMER"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n15"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1722.027644469246" y="744.4324606997972"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="59.037109375" x="22.560546875" y="5.0">Attach to +Queue</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n16"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1722.027644469246" y="405.8125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="87.982421875" x="8.087890625" y="5.0">Iterate +Callback Slots</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n17"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1219.1609778025793" y="549.296875"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="54.91796875" x="24.6201171875" y="5.0">Execute +Callback</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n18"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1423.0014539930555" y="643.765625"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="70.234375" x="16.9619140625" y="5.0">Fetch +Queue Slot</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n19"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="1452.5805555555555" y="547.765625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="54.91796875" x="-54.91796875" y="-15.96875">Callback +Priority?<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="-0.5" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n20"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="1366.4391554972829" y="270.3125"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="44.5703125" x="-57.39614048746989" y="8.03125">Return<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="-12.825827987469893" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n21"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1423.0014539930555" y="744.4324606997972"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="59.037109375" x="22.560546875" y="5.0">Attach to +Queue</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n22"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="1423.0014539930555" y="405.8125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="87.982421875" x="8.087890625" y="5.0">Iterate +Callback Slots</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n23"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="1452.5805555555555" y="262.8125"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="71.76953125" x="49.0" y="-8.984375">More IRQs?<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="-0.5" offsetX="4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n24"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="861.8498666914683" y="405.8125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="46.884765625" x="28.63671875" y="5.0">Detach +Slot</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n25"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="535.6367714533731" y="485.63357499198474"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="73.90234375" x="15.1279296875" y="4.999999999999943">Reattach to +Pool</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n26"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="861.8498666914683" y="264.34375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="76.322265625" x="13.91796875" y="5.0">Identify Slot +by Callback</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n27"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="419.565873015873" y="262.8125"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="76.486328125" x="-80.486328125" y="-35.9375">Iterate +Queue Slots<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="-0.5" offsetX="-4.0" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n28"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="210.3458984375" y="504.8384063225059"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="63.47265625" x="20.3427734375" y="11.984375">Re-Queue</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n29"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="419.565873015873" y="503.3071563225059"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="54.91796875" x="-39.300495441917576" y="-35.9375">Execute +Callback<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.2156217962252578" labelRatioY="0.5" nodeRatioX="-0.5" nodeRatioY="-0.5" offsetX="0.0" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n30"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="389.986771453373" y="700.6664804949104"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="73.90234375" x="15.1279296875" y="5.0">Reattach to +Pool</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n31"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="389.986771453373" y="603.8643126450118"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="46.884765625" x="28.63671875" y="5.0">Detach +Slot</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n32" yfiles.foldertype="group"> + <data key="d6"> + <y:ProxyAutoBoundsNode> + <y:Realizers active="0"> + <y:GenericGroupNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="236.09832655038775" width="336.0257936507933" x="966.2142857142858" y="-17.754576550387753"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#123EA2" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="166.01289682539664" y="4.0"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.MarkerTypeEnum" name="com.yworks.bpmn.marker1" value="BPMN_MARKER_OPEN"/> + </y:StyleProperties> + <y:State autoResize="true" closed="false" closedHeight="55.0" closedWidth="85.0"/> + <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> + <y:BorderInsets bottom="1" bottomF="0.96875" left="1" leftF="1.0003720238094047" right="1" rightF="0.9999999999997726" top="0" topF="0.0"/> + </y:GenericGroupNode> + <y:GenericGroupNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="55.0" width="85.0" x="852.6209302325583" y="-148.75503875968997"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#123EA2" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="40.5" y="25.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.MarkerTypeEnum" name="com.yworks.bpmn.marker1" value="BPMN_MARKER_CLOSED"/> + </y:StyleProperties> + <y:State autoResize="true" closed="true" closedHeight="55.0" closedWidth="85.0"/> + <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/> + <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/> + </y:GenericGroupNode> + </y:Realizers> + </y:ProxyAutoBoundsNode> + </data> + <graph edgedefault="directed" id="n32:"> + <node id="n32::n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="71.59106976744192" width="71.59106976744192" x="1214.6490095976374" y="37.84643023255808"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="25.322265625" x="23.134402071220848" y="-40.60100678294583">IRQ<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="-22.63225678294583" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_SIGNAL"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n32::n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="1082.8630952380952" y="79.4375"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="80.0546875" x="-95.71313666251376" y="-5.9375">Register +IRQ Callback<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="-0.31409001956947163" nodeRatioX="-0.5" nodeRatioY="-0.5" offsetX="-15.658449162513762" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n32::n2"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="1082.8630952380952" y="171.40625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="80.0546875" x="-94.72287309662238" y="-0.96875">De-Register +IRQ Callback<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="-14.66818559662238" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n32::n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="1082.8630952380952" y="0.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="custom" textColor="#000000" visible="true" width="96.6484375" x="-100.6484375" y="0.0">Execute +Delayed Queue<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.4393346379647749" nodeRatioX="-0.5" nodeRatioY="0.5" offsetX="-4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + </graph> + </node> + <node id="n33"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="28.893347284898766" width="42.64620155038756" x="1360.116054722089" y="873.5680463995943"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#993300" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="4.0" x="19.32310077519378" y="4.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="2.0" y="16.0"> + <y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n34"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="104.158203125" x="389.986771453373" y="405.8125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="82.169921875" x="10.994140625" y="5.0">Fetch +Queued Item</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="50.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n35"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="104.0" width="153.50263565891464" x="660.4638068461354" y="636.1890249839695"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#993300" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="91.720703125" x="30.89096626695732" y="4.0">IRLVectorElem</y:NodeLabel> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="59.875" modelName="custom" textColor="#000000" visible="true" width="111.560546875" x="2.0" y="29.96875">(*callback)() +enum priority +void *userdata +list_head cb_node<y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n36"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="28.893347284898766" width="42.64620155038756" x="1020.601252167246" y="736.7930114161444"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#993300" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="4.0" x="19.32310077519378" y="4.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="2.0" y="16.0"> + <y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n37"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="28.893347284898766" width="42.64620155038756" x="923.3618682660807" y="696.8850224903762"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#993300" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="4.0" x="19.32310077519378" y="4.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="2.0" y="16.0"> + <y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n38"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="28.893347284898766" width="42.64620155038756" x="831.3802696902253" y="750.9545370573478"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#993300" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="4.0" x="19.32310077519378" y="4.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="2.0" y="16.0"> + <y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n39"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="28.893347284898766" width="42.64620155038756" x="831.3802696902253" y="837.7188518297969"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#993300" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="4.0" x="19.32310077519378" y="4.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="2.0" y="16.0"> + <y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n40"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.entityRelationship.big_entity"> + <y:Geometry height="28.893347284898766" width="42.64620155038756" x="750.2675823240448" y="896.6121991146956"/> + <y:Fill color="#FF6600" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#993300" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="4.0" x="19.32310077519378" y="4.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="2.0" y="16.0"> + <y:LabelModel> + <y:ErdAttributesNodeLabelModel/> + </y:LabelModel> + <y:ModelParameter> + <y:ErdAttributesNodeLabelModelParameter/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n41"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="203.05963012256706" y="270.3125"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="44.5703125" x="-7.28515625" y="50.768195895129224">Return<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="20.768195895129224" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n32::n1" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1097.8630952380952" y="119.4375"/> + <y:Point x="779.770634920635" y="119.4375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n5" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="22.421875" x="-27.43578597780254" y="-8.984375">NO<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n5" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-8.984369962177425" anchorY="14.463348388671875" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="1.0" upY="1.8369701987210297E-16" visible="true" width="26.529296875" x="-8.98436996217743" y="14.463348388671875">YES<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_DEFAULT_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n1" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="-52.0791015625" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="10.154654754154308" y="-2.0"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n4" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n7" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="52.0791015625" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1271.2400793650793" y="356.046875"/> + </y:Path> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="10.125005037822461" y="-2.0"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n8" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.50244140625" sy="0.0" tx="-39.98653021765631" ty="-29.5"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="center_slider" preferredPlacement="anywhere" ratio="0.25" textColor="#000000" visible="true" width="34.01171875" x="71.12892136346727" y="-8.984375">IRL 1<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n8" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="39.97583747652175" ty="-29.5"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="center_slider" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="30.197265625" x="-70.53215293278777" y="-8.984375">IRL2<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n32::n0" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1271.2400793650793" y="119.4375"/> + <y:Point x="1475.0805555555555" y="119.4375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n12" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="-34.719401041666664" ty="-20.96875"> + <y:Point x="1873.545634920635" y="570.265625"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" ratio="0.5" textColor="#000000" visible="true" width="34.287109375" x="5.01946575830857" y="-8.984375">NOW<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="8.984375000000012" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="relative_to_edge_flow" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n12" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="21.07232220362107" anchorY="4.997802734375" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.2246467991473532E-16" upY="1.0" visible="true" width="42.14453125" x="-21.072209046378934" y="4.997802734374995">LATER<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="7.853981633974483" distance="8.984375" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="relative_to_edge_flow" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n0" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="-52.0791015625" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.08333333333333333" textColor="#000000" visible="true" width="4.0" x="13.703669472346292" y="-2.0"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e12" source="n12" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e13" source="n11" target="n15"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e14" source="n15" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="-15.5476673427994" ty="0.0"> + <y:Point x="1774.106746031746" y="833.5680463995943"/> + <y:Point x="113.7023326572006" y="833.5680463995943"/> + </y:Path> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0194852237040677" textColor="#000000" visible="true" width="4.0" x="-1.99994342137893" y="42.19811231756307"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e15" source="n9" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"> + <y:Point x="1774.106746031746" y="186.40625"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="34.01171875" x="132.2383041139633" y="-8.984375">IRL 1<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="8.984374999999993" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e16" source="n16" target="n12"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e17" source="n15" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="34.71940104166674" sy="-20.96875" tx="41.663281249999955" ty="20.96875"> + <y:Point x="1808.8261470734128" y="695.703125"/> + <y:Point x="1975.3444444444444" y="695.703125"/> + <y:Point x="1975.3444444444444" y="462.75"/> + <y:Point x="1815.770027281746" y="462.75"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e18" source="n10" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="20.83164062500009" ty="20.96875"> + <y:Point x="1908.2650793650794" y="472.75"/> + <y:Point x="1794.9383866567462" y="472.75"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e19" source="n2" target="n16"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="-52.0791015625" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="10.090735444568509" y="-2.0"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e20" source="n19" target="n17"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="52.053335543033654" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-47.4932469928076" anchorY="8.984375" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" ratio="0.5" rotationAngle="90.0" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" visible="true" width="34.287109375" x="-81.7803563678076" y="-8.984375000000002">NOW<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="7.853981633974483" distance="8.984375" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="relative_to_edge_flow" angleRotationOnRightSide="co" distance="-1.0" placement="anywhere" side="left|right" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e21" source="n19" target="n18"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="21.07225477430552" anchorY="4.997802734375" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.2246467991473532E-16" upY="1.0" visible="true" width="42.14453125" x="-21.072276475694483" y="4.997802734374995">LATER<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="7.853981633974483" distance="8.984375" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="relative_to_edge_flow" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e22" source="n0" target="n18"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="52.0791015625" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="-14.105079675099205" y="-2.0"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e23" source="n23" target="n20"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-4.95838487413198" anchorY="-8.984375" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="-1.2246467991473532E-16" upY="1.0" visible="true" width="22.421875" x="-27.38025987413198" y="-8.984375000000004">NO<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e24" source="n18" target="n21"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e25" source="n21" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="15.5476673427994" ty="0.0"> + <y:Point x="1475.0805555555555" y="823.5680463995943"/> + <y:Point x="144.7976673427994" y="823.5680463995943"/> + </y:Path> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.01750383315175686" textColor="#000000" visible="true" width="4.0" x="-2.00001085069448" y="32.19811231756307"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e26" source="n22" target="n19"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e27" source="n21" target="n22"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-52.106433391571045" sy="0.0" tx="-14.879743303571331" ty="20.96875"> + <y:Point x="1364.29126984127" y="765.4012106997972"/> + <y:Point x="1364.29126984127" y="508.78125"/> + <y:Point x="1460.2008122519842" y="508.78125"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e28" source="n17" target="n22"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="-29.75948660714289" ty="20.96875"> + <y:Point x="1271.2400793650793" y="498.78125"/> + <y:Point x="1445.3210689484126" y="498.78125"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e29" source="n9" target="n23"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="34.01171875" x="-17.005870225694252" y="18.012008666992188">IRL 2<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="17.005859375" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e30" source="n23" target="n22"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-8.98438585069448" anchorY="35.7298583984375" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="1.0" upY="1.8369701987210297E-16" visible="true" width="26.529296875" x="-8.984385850694485" y="35.7298583984375">YES<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e31" source="n19" target="n23"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1542.1599206349206" y="570.265625"/> + <y:Point x="1542.1599206349206" y="285.3125"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e32" source="n3" target="n22"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="39.990234375" sy="0.0" tx="-52.106433391571045" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.9500000000000001" textColor="#000000" visible="true" width="4.0" x="257.9438524615575" y="-2.0"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e33" source="n24" target="n25"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="19.204831330521188" tx="52.106433391571045" ty="0.0"> + <y:Point x="913.9289682539683" y="506.60232499198474"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e34" source="n32::n2" target="n26"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"> + <y:Point x="1097.8630952380952" y="228.34375"/> + <y:Point x="913.9289682539683" y="228.34375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e35" source="n3" target="n24"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-39.990234375" sy="0.0" tx="52.0791015625" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="-14.089907691592316" y="-2.0"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e36" source="n25" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="-2.0000083317831923" y="-14.076080769734006"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e37" source="n26" target="n24"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e38" source="n32::n3" target="n27"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1097.8630952380952" y="41.9375"/> + <y:Point x="442.065873015873" y="41.9375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e39" source="n14" target="n34"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="-52.106433391571045" ty="0.0"> + <y:Point x="129.25" y="426.78125"/> + </y:Path> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.1566439481693563" textColor="#000000" visible="true" width="4.0" x="-2.0" y="-66.93524169921875"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e40" source="n27" target="n34"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.958343505859375"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-8.984389435298851" anchorY="17.3441162109375" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="1.0" upY="1.8369701987210297E-16" visible="true" width="63.296875" x="-8.984389435298864" y="17.3441162109375">Next Item<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e41" source="n28" target="n27"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="-10.674747139281635" ty="11.844272971727435"> + <y:Point x="262.425" y="297.15677297172743"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e42" source="n28" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-52.0791015625" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#000000" visible="true" width="4.0" x="-14.085406494140614" y="-1.9999725837441247"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e43" source="n31" target="n30"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.958343505859375" tx="0.0" ty="-20.958343505859375"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e44" source="n29" target="n28"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="39.61820651822592" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="center_on_edge" ratio="0.5" textColor="#000000" visible="true" width="29.3359375" x="-56.55343638124975" y="-8.984347583744125">FAIL<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.33845992176542405" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="relative_to_edge_flow" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="on_edge" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e45" source="n30" target="n27"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="52.106433391571045" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="509.1452380952381" y="721.6352304949104"/> + <y:Point x="509.1452380952381" y="285.3125"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e46" source="n30" target="n0"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.958343505859375" tx="0.0" ty="0.0"> + <y:Point x="442.065873015873" y="853.5680463995943"/> + <y:Point x="1624.5936507936508" y="853.5680463995943"/> + </y:Path> + <y:LineStyle color="#808080" type="dashed" width="1.0"/> + <y:Arrows source="transparent_circle" target="white_delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" hasText="false" height="4.0" modelName="center_slider" preferredPlacement="anywhere" ratio="0.1120480288739841" textColor="#000000" visible="true" width="4.0" x="59.82637445359006" y="108.94737989568807"> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_MESSAGE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e47" source="n35" target="n36"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="905.3323974609375" y="643.5370483398438"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:Arc height="77.79100799560547" ratio="1.0" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e48" source="n37" target="n39"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="822.3097534179688" y="731.8602905273438"/> + </y:Path> + <y:LineStyle color="#1266AC" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#1266AC" visible="true" width="71.201171875" x="-184.02154141109963" y="58.901081259692205">Bridge Gap<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="56.86133079356006" distanceToCenter="true" position="right" ratio="0.3954847698112248" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:Arc height="-91.23286437988281" ratio="-2.169492483139038" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e49" source="n37" target="n38"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="880.39404296875" y="707.234619140625"/> + </y:Path> + <y:LineStyle color="#339966" type="dotted" width="2.0"/> + <y:Arrows source="delta" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#339966" visible="true" width="46.884765625" x="-48.02153088995078" y="25.329840870029216">Detach<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="left" ratio="0.5283378724964316" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:Arc height="-36.11214828491211" ratio="-1.353827953338623" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e50" source="n39" target="n40"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="826.870361328125" y="901.890380859375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:Arc height="25.059547424316406" ratio="1.0" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e51" source="n40" target="n35"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="698.6854858398438" y="808.2178344726562"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:Arc height="56.37633514404297" ratio="1.0" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e52" source="n36" target="n37"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="983.3276977539062" y="755.5955200195312"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:Arc height="26.277523040771484" ratio="1.0" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e53" source="n38" target="n33"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1124.8521728515625" y="793.1549682617188"/> + </y:Path> + <y:LineStyle color="#FF0000" type="dashed_dotted" width="2.0"/> + <y:Arrows source="delta" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#FF0000" visible="true" width="53.236328125" x="224.1798095703125" y="18.89227294921875">Chain In<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:Arc height="34.443363189697266" ratio="0.2538354992866516" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e54" source="n33" target="n0"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1628.5328369140625" y="913.0631713867188"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:Arc height="-185.5752410888672" ratio="-2.2485899925231934" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e55" source="n38" target="n0"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="1272.187744140625" y="972.23974609375"/> + </y:Path> + <y:LineStyle color="#FF0000" type="dashed_dotted" width="2.0"/> + <y:Arrows source="delta" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#FF0000" visible="true" width="53.236328125" x="315.7693752943253" y="186.0041821233832">Chain In<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="right" ratio="0.8762555541432071" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:Arc height="-259.349853515625" ratio="-1.3326870203018188" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e56" source="n1" target="n35"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="689.1243286132812" y="476.85821533203125"/> + </y:Path> + <y:LineStyle color="#808080" type="dashed_dotted" width="1.0"/> + <y:Arrows source="delta" target="delta"/> + <y:Arc height="28.435083389282227" ratio="0.2646845877170563" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e57" source="n38" target="n39"> + <data key="d10"> + <y:ArcEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="874.3944702148438" y="808.7833251953125"/> + </y:Path> + <y:LineStyle color="#339966" type="dotted" width="2.0"/> + <y:Arrows source="delta" target="delta"/> + <y:Arc height="21.691085815429688" ratio="1.0" type="fixedRatio"/> + </y:ArcEdge> + </data> + </edge> + <edge id="e58" source="n29" target="n31"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="442.065873015873" y="576.9878576952823"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-8.984389435298851" anchorY="17.981998320282287" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="1.0" upY="1.8369701987210297E-16" visible="true" width="21.314453125" x="-8.984389435298855" y="17.981998320282287">OK<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="1.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e59" source="n34" target="n29"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e60" source="n27" target="n41"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.50244140625" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" anchorX="-28.692381638879795" anchorY="-8.984374999999943" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="-1.0106430996148606E-15" upY="1.0" visible="true" width="85.931640625" x="-114.62402226387981" y="-8.98437500000003">Queue Empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="true" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="8.881784197001252E-16" distance="28.859678864126106" distanceToCenter="false" position="center" ratio="0.26160543923384416" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources/> + </data> +</graphml> diff --git a/IBSW/doc/images/irq_dispatch/irq_dispatch.png b/IBSW/doc/images/irq_dispatch/irq_dispatch.png new file mode 100644 index 0000000000000000000000000000000000000000..899be673a85e60a5b7e90a4274f090152bdbb2b7 Binary files /dev/null and b/IBSW/doc/images/irq_dispatch/irq_dispatch.png differ diff --git a/IBSW/doc/images/packet_tracker/CrIbGndPcktCollect.graphml b/IBSW/doc/images/packet_tracker/CrIbGndPcktCollect.graphml new file mode 100644 index 0000000000000000000000000000000000000000..8d84bcfdabfa32d602d9ffda23563166ee88bd5f --- /dev/null +++ b/IBSW/doc/images/packet_tracker/CrIbGndPcktCollect.graphml @@ -0,0 +1,601 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.1--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="765.8983301313199" y="648.9453125000003"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="134.65234375" x="57.57976810515879" y="11.015625">CrIbGndPcktCollect<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="0.0" offsetX="17.57976810515879" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="721.8192285688199" y="563.0078125000003"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="113.08984375" x="7.5341796875" y="5.0">Check GND +Packet Size Buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="583.7966602626398" y="536.5820312500002"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="59.962890625" x="17.417010650490283" y="24.44140625">GND Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="763.3983301313199" y="474.00781250000034"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="893.2030880740194" y="481.50781250000034"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="79.609375" x="-24.8046875" y="44.50781249999966">Return False<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="14.507812499999659" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="770.8983301313199" y="228.13281250000034"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="75.63671875" x="-88.71668950631988" y="6.015625">Return True<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="-13.07997075631988" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="721.8192285688199" y="388.07031250000034"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="75.21484375" x="26.4716796875" y="5.0">Get size of +next packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="721.8192285688199" y="302.13281250000034"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="84.408203125" x="21.875" y="5.0">Extract to +packet buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="583.7966602626398" y="275.7070312500003"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490283" y="24.441406250000057">GND +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n2" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="42.6953125" x="5.015761771944881" y="-8.984374999999659">Empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n2" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="631.3758876568102" y="409.03906250000034"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n3" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n6" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n7" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n8" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/packet_tracker/CrIbGndPcktCollect.png b/IBSW/doc/images/packet_tracker/CrIbGndPcktCollect.png new file mode 100644 index 0000000000000000000000000000000000000000..ca3ca19f57af71fcb2439dc6c148cb242ad5724d Binary files /dev/null and b/IBSW/doc/images/packet_tracker/CrIbGndPcktCollect.png differ diff --git a/IBSW/doc/images/packet_tracker/CrIbIsGrdPcktAvail.graphml b/IBSW/doc/images/packet_tracker/CrIbIsGrdPcktAvail.graphml new file mode 100644 index 0000000000000000000000000000000000000000..6978d7b9e893451e4aad9480606f4639c9a6cada --- /dev/null +++ b/IBSW/doc/images/packet_tracker/CrIbIsGrdPcktAvail.graphml @@ -0,0 +1,480 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.1--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="719.0" y="530.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="132.349609375" x="57.57976810515879" y="11.015625">CrIbIsObcPcktAvail<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="0.0" offsetX="17.57976810515879" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="674.9208984375" y="444.0625"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="113.08984375" x="7.5341796875" y="5.0">Check OBC +Packet Size Buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="536.8983301313199" y="417.63671874999994"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="58.50390625" x="18.146502837990283" y="24.441406250000057">OBC Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="716.5" y="355.0625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="846.3047579426994" y="362.5625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="79.609375" x="48.89055455730056" y="4.0">Return False<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="-0.5" nodeRatioX="0.5" nodeRatioY="-0.5" offsetX="18.89055455730056" offsetY="4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="724.0" y="281.0625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="75.63671875" x="46.71484375" y="4.0">Return True<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="-0.5" nodeRatioX="0.5" nodeRatioY="-0.5" offsetX="16.71484375" offsetY="4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n2" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n3" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="42.6953125" x="5.0157470703125" y="-8.984375">Empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/packet_tracker/CrIbIsGrdPcktAvail.png b/IBSW/doc/images/packet_tracker/CrIbIsGrdPcktAvail.png new file mode 100644 index 0000000000000000000000000000000000000000..a3736cffbae357d2df073e93a6ab404b2384e118 Binary files /dev/null and b/IBSW/doc/images/packet_tracker/CrIbIsGrdPcktAvail.png differ diff --git a/IBSW/doc/images/packet_tracker/CrIbIsObcPcktAvail.graphml b/IBSW/doc/images/packet_tracker/CrIbIsObcPcktAvail.graphml new file mode 100644 index 0000000000000000000000000000000000000000..762b8675116421f3b92f1a40d7dc7458b0afbd27 --- /dev/null +++ b/IBSW/doc/images/packet_tracker/CrIbIsObcPcktAvail.graphml @@ -0,0 +1,480 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.1--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="719.0" y="530.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="132.349609375" x="57.57976810515879" y="11.015625">CrIbIsObcPcktAvail<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="0.0" offsetX="17.57976810515879" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="674.9208984375" y="444.0625"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="113.08984375" x="7.5341796875" y="5.0">Check OBC +Packet Size Buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="536.8983301313199" y="417.63671874999994"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="58.50390625" x="18.146502837990283" y="24.441406250000057">OBC Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="716.5" y="355.0625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="846.3047579426994" y="362.5625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="79.609375" x="34.0" y="21.015625">Return False<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="0.5" offsetX="4.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="724.0" y="281.0625"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="75.63671875" x="24.181640625" y="-21.96875">Return True<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.42307493673501007" labelRatioY="0.5" nodeRatioX="0.5" nodeRatioY="-0.5" offsetX="0.0" offsetY="-4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n2" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n3" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="42.6953125" x="5.0157470703125" y="-8.984375">Empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/packet_tracker/CrIbIsObcPcktAvail.png b/IBSW/doc/images/packet_tracker/CrIbIsObcPcktAvail.png new file mode 100644 index 0000000000000000000000000000000000000000..a36350b2d43bd8d336c9daebcb60f1c990993519 Binary files /dev/null and b/IBSW/doc/images/packet_tracker/CrIbIsObcPcktAvail.png differ diff --git a/IBSW/doc/images/packet_tracker/CrIbMilBusPckHandover_1kbuf.graphml b/IBSW/doc/images/packet_tracker/CrIbMilBusPckHandover_1kbuf.graphml new file mode 100644 index 0000000000000000000000000000000000000000..63ebf169e833f5618fc18fa78f7d6743cc3e43b5 --- /dev/null +++ b/IBSW/doc/images/packet_tracker/CrIbMilBusPckHandover_1kbuf.graphml @@ -0,0 +1,745 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.2--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="255.0" y="405.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="171.80078125" x="57.57976810515879" y="11.015625">CrIbMilBusPcktHandover<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="0.0" offsetX="17.57976810515879" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="202.9208984375" y="329.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="134.2421875" x="4.9580078125" y="5.0">Clear 1kiB acquisition +data buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="202.9208984375" y="254.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="139.7265625" x="2.2158203125" y="5.0">Copy Packet to +acquisition data buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="-9.0791015625" y="104.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="120.16796875" x="11.9951171875" y="5.0">Set Acquisition +Transfer Descriptor</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="202.9208984375" y="179.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="135.75390625" x="4.2021484375" y="5.0">Fragment Acquisition +Data packets</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="15.60154403700966" y="-22.394531250000057"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490333" y="24.441406250000057">AD +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="15.60154403700966" y="177.60546874999994"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490333" y="24.441406250000057">ATR +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="252.5" y="102.5"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="377.9208984375" y="4.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="103.38671875" x="20.3857421875" y="5.0">Insert into 1553 +packet structure</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="202.9208984375" y="4.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="113.212890625" x="15.47265625" y="11.984375">Copy 1553 packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="-77.0" y="110.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="44.5703125" x="-7.28515625" y="44.015625">Return<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="14.015625" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="377.9208984375" y="104.03125"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="130.404296875" x="6.876953125" y="11.984375">Fetch 32 1553 words</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="36.8595330752687" width="278.392366795699" x="-76.1961833978495" y="406.57023346236565"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.1875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="263.2421875" x="7.575089647849495" y="2.8360165376343502">AD ... Acquisition Data +ATR ... Acquisition Transfer Request</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="137.1961833978495" y="16.42976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.0" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n1" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n9" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-72.0791015625" sy="-0.0" tx="47.39845596299034" ty="-0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n2" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n3" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-47.39453125000006"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n4" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n7" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="-0.0" tx="-72.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_DEFAULT_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n11" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="-20.96875" tx="0.0" ty="20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n8" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-72.0791015625" sy="-0.0" tx="72.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n7" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="-0.0" tx="72.0791015625" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="82.9140625" x="-87.88539123535156" y="-8.984375">Buffer empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n9" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n3" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-72.0791015625" sy="-0.0" tx="15.0" ty="-0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/packet_tracker/CrIbMilBusPcktHandover.graphml b/IBSW/doc/images/packet_tracker/CrIbMilBusPcktHandover.graphml new file mode 100644 index 0000000000000000000000000000000000000000..7335b5cbefe8dae4674a7f753f465e1f31b8f538 --- /dev/null +++ b/IBSW/doc/images/packet_tracker/CrIbMilBusPcktHandover.graphml @@ -0,0 +1,914 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.2--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="241.23769841269842" y="0.0"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="171.80078125" x="-183.80536823769842" y="4.0">CrIbMilBusPcktHandover<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="-0.5" nodeRatioX="-0.5" nodeRatioY="-0.5" offsetX="-12.004586987698417" offsetY="4.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="216.9375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="105.21484375" x="19.4716796875" y="11.984375">Get buffer usage</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="381.84375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="135.689453125" x="4.234375" y="11.984375">(2048 - buffer usage)</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="238.73769841269842" y="446.72047057526834"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="585.3628906249999"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="100.26953125" x="21.9443359375" y="5.0">Add packet +to packet buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="36.8595330752687" width="186.2752849603495" x="273.1917225991903" y="682.1092169247313"/> + <y:Fill hasColor="false" transparent="false"/> + <y:BorderStyle color="#999999" type="line" width="1.0"/> + <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Liberation Mono" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.59375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="169.626953125" x="8.324165917674748" y="9.63289153763435">AD ... Acquisition Data</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="91.13764248017475" y="16.42976653763435"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="238.73769841269842" y="288.875"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="375.8757936507937" y="454.22047057526834"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="78.109375" x="-24.054687499999943" y="43.552734375">Return Error<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="1.887379141862766E-15" nodeRatioY="0.5" offsetX="0.0" offsetY="13.552734375" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="375.8757936507937" y="591.3316406249999"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="96.689453125" x="-7.887799413293692" y="42.533862500000055">Return Success<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.848564238306877" nodeRatioY="0.5" offsetX="0.0" offsetY="12.533862500000055" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n9"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="68.36328125000006" width="144.158203125" x="23.669112723214297" y="572.1499999999999"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="106.919921875" x="18.619140625" y="11.228515625">Add empty +segment to next +frame boundary</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="32.181640625"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="-3.885780586188048E-16" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n10"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="15.000263516865076" y="381.84375"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="131.875" x="6.1416015625" y="11.984375">(1024 - buffer usage)</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n11"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="64.57936507936508" y="482.07207031249993"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n12"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="144.158203125" x="189.15859685019842" y="70.0"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="96.888671875" x="23.634765625" y="11.984375">Get packet size</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="70.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n13"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="238.73769841269842" y="141.9375"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n14"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="32.68090911637474" y="99.51328124999998"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="44.224609375" x="25.286151275490333" y="24.44140625">AD +Packet +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <edge id="e0" source="n0" target="n12"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n14" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="42.628443124857554" sy="0.0" tx="-72.0791015625" ty="0.0"> + <y:Point x="189.15859685019842" y="146.90781250000003"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n6" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="0.0" ty="-15.0"> + <y:Point x="390.8757936507937" y="311.375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="43.966993834480434" y="-8.984375">≥ 2048<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n6" target="n2"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="-24.204104565817204" y="5.0">≥ 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n2" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n3" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="-15.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="58.474609375" x="4.999996996682796" y="-8.984363409106606">< packet<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="1.9999999999997726" distanceToCenter="false" position="center" ratio="0.0" segment="-1"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n4" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.958343505859375" tx="-47.39296339522298" ty="0.0"> + <y:Point x="261.2376984126985" y="717.9078125"/> + <y:Point x="-4.9997364831349245" y="717.9078125"/> + <y:Point x="-4.9997364831349245" y="146.90781250000003"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e9" source="n4" target="n8"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="72.0997576713562" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e10" source="n9" target="n14"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-8.668849206349222" sy="34.186718749999955" tx="-46.4160080003421" ty="11.081423338993375"> + <y:Point x="87.07936507936508" y="711.445945866667"/> + <y:Point x="2.524263516865048" y="711.445945866667"/> + <y:Point x="2.524263516865048" y="157.9892358389934"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e11" source="n9" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="72.09975767135622" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e12" source="n6" target="n10"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="-22.5" sy="0.0" tx="0.0" ty="-20.96875"> + <y:Point x="87.07936507936508" y="311.375"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="-114.5982889326792" y="-8.984375">< 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="1.9999999999998863" distanceToCenter="false" position="center" ratio="0.5" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e13" source="n10" target="n11"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e14" source="n11" target="n9"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.50244140625" tx="-8.668849206349222" ty="-5.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="58.474609375" x="-29.237308199443518" y="4.997546386718682">< packet<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="20.697265624999737" distanceToCenter="false" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e15" source="n12" target="n13"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="20.96875" tx="0.0" ty="-22.5"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e16" source="n13" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="22.5" tx="0.0" ty="-20.96875"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="skewed_dash" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e17" source="n13" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.5" sy="0.0" tx="15.0" ty="0.0"> + <y:Point x="427.01979365079376" y="164.4375"/> + <y:Point x="427.01979365079376" y="469.22047057526834"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="48.408203125" x="16.674159277459523" y="-8.984375">> 1024<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="2.0" distanceToCenter="false" position="center" ratio="0.10233491933575473" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e18" source="n11" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="22.50244140625" sy="0.0" tx="-13.0" ty="-20.93215059166596"> + <y:Point x="248.23769841269842" y="504.57207031249993"/> + </y:Path> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/packet_tracker/CrIbMilBusPcktHandover.png b/IBSW/doc/images/packet_tracker/CrIbMilBusPcktHandover.png new file mode 100644 index 0000000000000000000000000000000000000000..87a388b50acd2838dfdc03db13e2c78ae0ad55af Binary files /dev/null and b/IBSW/doc/images/packet_tracker/CrIbMilBusPcktHandover.png differ diff --git a/IBSW/doc/images/packet_tracker/CrIbObcPcktCollect.graphml b/IBSW/doc/images/packet_tracker/CrIbObcPcktCollect.graphml new file mode 100644 index 0000000000000000000000000000000000000000..6b4b566f05da839381aee9bca99522537c9e02a4 --- /dev/null +++ b/IBSW/doc/images/packet_tracker/CrIbObcPcktCollect.graphml @@ -0,0 +1,601 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.1--> + <key for="graphml" id="d0" yfiles.type="resources"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key attr.name="Description" attr.type="string" for="graph" id="d7"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d7"/> + <node id="n0"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="40.0" width="40.0" x="765.8983301313199" y="648.9453125000003"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#27AE27" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="133.57421875" x="57.57976810515879" y="11.015625">CrIbObcPcktCollect<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="0.5" nodeRatioY="0.0" offsetX="17.57976810515879" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_START"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n1"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="721.8192285688199" y="563.0078125000003"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="113.08984375" x="7.5341796875" y="5.0">Check OBC +Packet Size Buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n2"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="583.7966602626398" y="536.5820312500002"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="58.50390625" x="18.146502837990283" y="24.441406250000057">OBC Size +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <node id="n3"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Gateway.withShadow"> + <y:Geometry height="45.0" width="45.0" x="763.3983301313199" y="474.00781250000034"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#E38B00" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="4.0" x="20.5" y="20.5"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="GATEWAY_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n4"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="893.2030880740194" y="481.50781250000034"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="79.609375" x="-24.8046875" y="44.50781249999966">Return False<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="14.507812499999659" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n5"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Event.withShadow"> + <y:Geometry height="30.0" width="30.0" x="770.8983301313199" y="228.13281250000034"/> + <y:Fill color="#FFFFFFE6" color2="#D4D4D4CC" transparent="false"/> + <y:BorderStyle color="#B11F1F" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="75.63671875" x="-88.71668950631988" y="6.015625">Return True<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="-13.07997075631988" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="EVENT_TYPE_PLAIN"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + <y:Property class="com.yworks.yfiles.bpmn.view.EventCharEnum" name="com.yworks.bpmn.characteristic" value="EVENT_CHARACTERISTIC_END"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n6"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="721.8192285688199" y="388.07031250000034"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="75.21484375" x="26.4716796875" y="5.0">Get size of +next packet</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n7"> + <data key="d6"> + <y:GenericNode configuration="com.yworks.bpmn.Activity.withShadow"> + <y:Geometry height="41.9375" width="128.158203125" x="721.8192285688199" y="302.13281250000034"/> + <y:Fill color="#C7E5F9" transparent="false"/> + <y:BorderStyle color="#1266AC" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="31.9375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="84.408203125" x="21.875" y="5.0">Extract to +packet buffer</y:NodeLabel> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="62.0791015625" y="18.96875"> + <y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="ACTIVITY_TYPE"/> + <y:Property class="com.yworks.yfiles.bpmn.view.ActivityTypeEnum" name="com.yworks.bpmn.activityType" value="ACTIVITY_TYPE_TASK"/> + <y:Property class="com.yworks.yfiles.bpmn.view.TaskTypeEnum" name="com.yworks.bpmn.taskType" value="TASK_TYPE_ABSTRACT"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.line.color" value="#000000"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill" value="#ffffffe6"/> + <y:Property class="java.awt.Color" name="com.yworks.bpmn.icon.fill2" value="#d4d4d4cc"/> + </y:StyleProperties> + </y:GenericNode> + </data> + </node> + <node id="n8"> + <data key="d6"> + <y:SVGNode> + <y:Geometry height="94.78906250000011" width="94.79691192598067" x="583.7966602626398" y="275.7070312500003"/> + <y:Fill color="#CCCCFF" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="45.90625" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="50.470703125" x="22.163104400490283" y="24.441406250000057">OBC +Circular +Buffer</y:NodeLabel> + <y:SVGNodeProperties usingVisualBounds="true"/> + <y:SVGModel svgBoundsPolicy="0"> + <y:SVGContent refid="1"/> + </y:SVGModel> + </y:SVGNode> + </data> + </node> + <edge id="e0" source="n0" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e1" source="n2" target="n1"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e2" source="n1" target="n3"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e3" source="n3" target="n4"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:EdgeLabel alignment="center" backgroundColor="#FFFFFF" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasLineColor="false" height="17.96875" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="42.6953125" x="5.015761771944881" y="-8.984374999999659">Empty<y:LabelModel> + <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.0" segment="0"/> + </y:ModelParameter> + <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/> + </y:EdgeLabel> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e4" source="n2" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"> + <y:Point x="631.3758876568102" y="409.03906250000034"/> + </y:Path> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e5" source="n3" target="n6"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e6" source="n6" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e7" source="n7" target="n5"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="line" width="1.0"/> + <y:Arrows source="none" target="delta"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + <edge id="e8" source="n8" target="n7"> + <data key="d10"> + <y:GenericEdge configuration="com.yworks.bpmn.Connection"> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#808080" type="dotted" width="2.0"/> + <y:Arrows source="none" target="concave"/> + <y:StyleProperties> + <y:Property class="com.yworks.yfiles.bpmn.view.BPMNTypeEnum" name="com.yworks.bpmn.type" value="CONNECTION_TYPE_SEQUENCE_FLOW"/> + </y:StyleProperties> + </y:GenericEdge> + </data> + </edge> + </graph> + <data key="d0"> + <y:Resources> + <y:Resource id="1"><?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="181.51503" + height="181.50002" + id="svg6241" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="circular_buffer.svg"> + <defs + id="defs6243" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4" + inkscape:cx="-191.78859" + inkscape:cy="95.848443" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:window-width="1920" + inkscape:window-height="1014" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata6246"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-745.67177,-616.55345)"> + <text + xml:space="preserve" + style="font-size:21.79795456px;font-style:normal;font-weight:normal;line-height:125%;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Verdana;-inkscape-font-specification:Verdana" + x="383.44809" + y="710.9231" + id="text6873" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6875" + x="383.44809" + y="710.9231" + style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#404040;fill-opacity:1;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold" /></text> + <path + transform="matrix(-0.94718199,-0.01879329,0.01879329,-0.94718199,929.26064,803.90098)" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + sodipodi:ry="80" + sodipodi:rx="80" + sodipodi:cy="100" + sodipodi:cx="100" + id="path6939-8-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + d="m 190,100 a 90,90 0 1 1 -180,0 90,90 0 1 1 180,0 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path4706-7-4" + style="fill:#f8f8f8;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:type="arc" + style="fill:#89acf3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5917-9-6" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="90" + sodipodi:ry="90" + d="M 10,99.999996 A 90,90 0 1 1 145,177.94229 L 100,100 z" + sodipodi:start="3.1415927" + sodipodi:end="7.3303829" /> + <path + transform="translate(736.42177,607.30346)" + sodipodi:end="7.3303829" + sodipodi:start="5.2359878" + d="m 145,22.057716 a 90,90 0 0 1 0,155.884574 L 100,100 z" + sodipodi:ry="90" + sodipodi:rx="90" + sodipodi:cy="100" + sodipodi:cx="100" + id="path3653-6-2" + style="fill:#fbecd5;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + sodipodi:type="arc" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,78" + id="path5943-6-2" /> + <path + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 45,-78" + id="path5953-2-0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 746.42177,707.30345 180,0" + id="path5921-6-0" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,797.30345 0,-180" + id="path5923-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,63" + id="path5925-7-9" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,-63" + id="path5927-9-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 63,-63" + id="path5929-2-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -63,63" + id="path5931-8-6" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,23" + id="path5933-1-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,45" + id="path5935-6-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,78" + id="path5937-5-4" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,87" + id="path5939-0-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,87" + id="path5941-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,45" + id="path5945-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,23" + id="path5947-8-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 87,-23" + id="path5949-9-7" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 78,-45" + id="path5951-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 23,-87 0,0" + id="path5955-5-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -23,-87" + id="path5957-0-5" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -45,-78" + id="path5959-8-3" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -78,-45" + id="path5961-4-1" + inkscape:connector-curvature="0" /> + <path + style="opacity:0.30449829;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.66528931;stroke-dasharray:none;display:inline" + d="m 836.42177,707.30345 -87,-23" + id="path5963-6-8" + inkscape:connector-curvature="0" /> + <path + sodipodi:type="arc" + style="fill:#c7e5f9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" + id="path5919-8-8" + sodipodi:cx="100" + sodipodi:cy="100" + sodipodi:rx="80" + sodipodi:ry="80" + d="m 180,100 a 80,80 0 1 1 -160,0 80,80 0 1 1 160,0 z" + transform="matrix(0.90092879,0,0,0.90092879,746.3289,617.21058)" /> + <g + transform="translate(230.43873,464.77132)" + id="g8379" + style="fill:#1166ad;fill-opacity:1;stroke:none;display:inline"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#1166ad;fill-opacity:1;stroke:none;stroke-width:3.95015383;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 525.52266,251.41302 a 2.0002,2.0002 0 0 0 -1.89866,2.31003 c 5.92694,43.90653 45.35328,75.43234 89.49019,71.57949 a 2.001176,2.001176 0 1 0 -0.34809,-3.98718 C 570.71635,324.986 533.25785,295.01535 527.61119,253.1851 a 2.0002,2.0002 0 0 0 -2.08853,-1.77208 z" + id="path7578-8-2" + inkscape:connector-curvature="0" /> + <path + style="fill:#1166ad;fill-opacity:1;fill-rule:evenodd;stroke:none" + d="m 617.54256,322.91708 -6.54593,4.58663 -0.6957,-7.9697 7.24163,3.38307 z" + id="path8385" + inkscape:connector-curvature="0" /> + </g> + <flowRoot + xml:space="preserve" + id="flowRoot3243" + style="font-size:8px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" + transform="translate(264.88555,551.83968)"><flowRegion + id="flowRegion3245"><rect + id="rect3247" + width="219.28572" + height="286.42856" + x="419.28571" + y="53.187862" /></flowRegion><flowPara + id="flowPara3249"></flowPara></flowRoot> </g> +</svg> +</y:Resource> + </y:Resources> + </data> +</graphml> diff --git a/IBSW/doc/images/packet_tracker/CrIbObcPcktCollect.png b/IBSW/doc/images/packet_tracker/CrIbObcPcktCollect.png new file mode 100644 index 0000000000000000000000000000000000000000..38e62eba958001589a4f1b99375e5b8df8004912 Binary files /dev/null and b/IBSW/doc/images/packet_tracker/CrIbObcPcktCollect.png differ diff --git a/IBSW/include/ahb.h b/IBSW/include/ahb.h new file mode 100644 index 0000000000000000000000000000000000000000..fb7f0bf642ad438a8f5b11c75693cd78afd398de --- /dev/null +++ b/IBSW/include/ahb.h @@ -0,0 +1,40 @@ +/** + * @file ahb.h + * @ingroup ahb + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date March, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef AHB_H +#define AHB_H + +#include <stdint.h> + +/** + * @see GR712-UM v2.3 p. 71 + */ +#define AHB_STATUS_HSIZE 0x00000007 +#define AHB_STATUS_HMASTER 0x00000078 +#define AHB_STATUS_HWRITE 0x00000080 +#define AHB_STATUS_NE 0x00000100 +#define AHB_STATUS_CE 0x00000200 + + +void ahbstat_clear_new_error(void); +uint32_t ahbstat_get_status(void); +uint32_t ahbstat_new_error(void); +uint32_t ahbstat_correctable_error(void); +uint32_t ahbstat_get_failing_addr(void); + +#endif /* AHB_H */ diff --git a/IBSW/include/asm/leon.h b/IBSW/include/asm/leon.h new file mode 100644 index 0000000000000000000000000000000000000000..311934f9616105c3190efcd8e90a89e89bd3c567 --- /dev/null +++ b/IBSW/include/asm/leon.h @@ -0,0 +1,208 @@ +/** + * @file asm/leon.h + * + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date 2015 + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief assembly functions for the leon3 target + * + */ + +#ifndef ASM_LEON_H +#define ASM_LEON_H + +#include <stdint.h> + +#if (__sparc__) + + +#define ASI_LEON3_SYSCTRL 0x02 + +#define ASI_LEON3_SYSCTRL_CCR 0x00 +#define ASI_LEON3_SYSCTRL_ICFG 0x08 +#define ASI_LEON3_SYSCTRL_DCFG 0x0c + + + + +__attribute__((unused)) +static uint32_t leon3_asr17() +{ + uint32_t asr17; + + __asm__ __volatile__ ( + "rd %%asr17, %0 \n\t" + :"=r" (asr17) + ); + + return asr17; +} + +__attribute__((unused)) +static uint32_t leon3_cpuid() +{ + uint32_t cpuid; + + __asm__ __volatile__ ( + "rd %%asr17, %0 \n\t" + "srl %0, 28, %0 \n\t" + :"=r" (cpuid) + : + :"l1"); + return cpuid; +} + +__attribute__((unused)) +static void leon3_powerdown_safe(uint32_t phys_memaddr) +{ + __asm__ __volatile__( + "wr %%g0, %%asr19 \n\t" + "lda [%0] 0x1c, %%g0 \n\t" + : + :"r" (phys_memaddr) + :"memory"); +} + +__attribute__((unused)) +static void leon3_flush() +{ + __asm__ __volatile__( + "flush \n\t" + "set 0x81000f, %%g1 \n\t" + "sta %%g1, [%0] %1 \n\t" + : + : "r" (ASI_LEON3_SYSCTRL_CCR), + "i" (ASI_LEON3_SYSCTRL) + : "g1"); +} + +__attribute__((unused)) +static void leon3_enable_icache() +{ + __asm__ __volatile__( + "lda [%0] %1, %%l1 \n\t" + "set 0x3, %%l2 \n\t" + "or %%l2, %%l1, %%l2 \n\t" + "sta %%l2, [%0] %1 \n\t" + : + : "r" (ASI_LEON3_SYSCTRL_CCR), + "i" (ASI_LEON3_SYSCTRL) + : "l1", "l2"); +} + +__attribute__((unused)) +static void leon3_enable_dcache() +{ + __asm__ __volatile__( + "lda [%0] %1, %%l1 \n\t" + "set 0xc, %%l2 \n\t" + "or %%l2, %%l1, %%l2 \n\t" + "sta %%l2, [%0] %1 \n\t" + : + : "r" (ASI_LEON3_SYSCTRL_CCR), + "i" (ASI_LEON3_SYSCTRL) + : "l1", "l2"); +} + + +__attribute__((unused)) +static void leon3_enable_snooping() +{ + __asm__ __volatile__( + "lda [%0] %1, %%l1 \n\t" + "set 0x800000, %%l2 \n\t" + "or %%l2, %%l1, %%l2 \n\t" + "sta %%l2, [%0] %1 \n\t" + : + : "r" (ASI_LEON3_SYSCTRL_CCR), + "i" (ASI_LEON3_SYSCTRL) + : "l1", "l2"); +} + +__attribute__((unused)) +static void leon3_enable_fault_tolerant() +{ + __asm__ __volatile__( + "lda [%0] %1, %%l1 \n\t" + "set 0x80000, %%l2 \n\t" + "or %%l2, %%l1, %%l2 \n\t" + "sta %%l2, [%0] %1 \n\t" + : + : "r" (ASI_LEON3_SYSCTRL_CCR), + "i" (ASI_LEON3_SYSCTRL) + : "l1", "l2"); +} + + + + +__attribute__((unused)) +static void leon_set_sp(uint32_t stack_addr) +{ + __asm__ __volatile__( + "mov %0, %%sp\n\t" + : + :"r"(stack_addr) + :"memory"); +} + +__attribute__((unused)) +static void leon_set_fp(uint32_t stack_addr) +{ + __asm__ __volatile__( + "mov %0, %%fp\n\t" + : + :"r" (stack_addr) + :"memory"); +} + +__attribute__((unused)) +static void leon_reg_win_flush(void) +{ + __asm__ __volatile__("ta 3"); +} + +#else /* dummy functions */ + +#if (__unused__) +__attribute__((unused)) +static uint32_t leon3_asr17() +{ + return 0; +} +#endif + +__attribute__((unused)) +static uint32_t leon3_cpuid() +{ + return 0; +} + +#if (__unused__) +__attribute__((unused)) +static void leon3_powerdown_safe(__attribute__((unused)) uint32_t phys_memaddr) +{ +} +#endif + +__attribute__((unused)) +static void leon_reg_win_flush(void) +{ +} + + +#endif + + +#endif /* ASM_LEON_H */ diff --git a/IBSW/include/byteorder.h b/IBSW/include/byteorder.h new file mode 100644 index 0000000000000000000000000000000000000000..b0397059a8dfb1f632f2df24db380ec1d46beab9 --- /dev/null +++ b/IBSW/include/byteorder.h @@ -0,0 +1,273 @@ +/** + * @file byteorder.h + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * This is a set of macros for consistent endianess conversion. They work + * for both little and big endian cpus. + * + * conversion of XX-bit integers (16- or 32-) between native CPU format + * and little/big endian format: + * cpu_to_[bl]eXX(uintXX_t x) + * [bl]eXX_to_cpu(uintXX_t x) + * + * the same, but change in situ: + * cpu_to_[bl]eXXs(uintXX_t x) + * [bl]eXX_to_cpus(uintXX_t x) + * + * + * This is based on the byte order macros from the linux kernel, see: + * include/linux/byteorder/generic.h + * include/uapi/linux/swab.h + * include/uapi/linux/byteorder/big_endian.h + * include/uapi/linux/byteorder/little_endian.h + * by @author Linus Torvalds et al. + * + */ +#ifndef BYTEORDER_H +#define BYTEORDER_H + +#include <stdint.h> + + + +#ifdef __BIG_ENDIAN +#undef __BIG_ENDIAN +#endif + +#ifdef __LITTLE_ENDIAN +#undef __LITTLE_ENDIAN +#endif + +#if (__sparc__) +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif +#endif + +#if (__i386__ || __x86_64__) +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#endif + + +#define ___constant_swab16(x) ((uint16_t)( \ + (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ + (((uint16_t)(x) & (uint16_t)0xff00U) >> 8))) + +#define ___constant_swab32(x) ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))) + + +#ifdef USE_BUILTIN_BSWAP +#if GCC_VERSION >= 40400 +#define __HAVE_BUILTIN_BSWAP32__ +#endif +#if GCC_VERSION >= 40800 +#define __HAVE_BUILTIN_BSWAP16__ +#endif +#endif /* USE_BUILTIN_BSWAP */ + + +static inline __attribute__((const)) uint16_t __fswab16(uint16_t val) +{ +#ifdef __HAVE_BUILTIN_BSWAP16__ + return __builtin_bswap16(val); +#else + return ___constant_swab16(val); +#endif +} + + +static inline __attribute__((const)) uint32_t __fswab32(uint32_t val) +{ +#ifdef __HAVE_BUILTIN_BSWAP32__ + return __builtin_bswap32(val); +#else + return ___constant_swab32(val); +#endif +} + + +/** + * @brief return a byteswapped 16-bit value + * @param x value to byteswap + */ + +#define __swab16(x) \ + (__builtin_constant_p((uint16_t)(x)) ? \ + ___constant_swab16(x) : \ + __fswab16(x)) + + +/** + * @brief return a byteswapped 32-bit value + * @param x a value to byteswap + */ + +#define __swab32(x) \ + (__builtin_constant_p((uint32_t)(x)) ? \ + ___constant_swab32(x) : \ + __fswab32(x)) + + +/** + * @brief return a byteswapped 16-bit value from a pointer + * @param p a pointer to a naturally-aligned 16-bit value + */ +static inline uint16_t __swab16p(const uint16_t *p) +{ + return __swab16(*p); +} + + +/** + * @brief return a byteswapped 32-bit value from a pointer + * @param p a pointer to a naturally-aligned 32-bit value + */ +static inline uint32_t __swab32p(const uint32_t *p) +{ + return __swab32(*p); +} + + +/** + * @brief byteswap a 16-bit value in-place + * @param p a pointer to a naturally-aligned 16-bit value + */ + +static inline void __swab16s(uint16_t *p) +{ + *p = __swab16p(p); +} + + +/** + * @brief byteswap a 32-bit value in-place + * @param p a pointer to a naturally-aligned 32-bit value + */ + +static inline void __swab32s(uint32_t *p) +{ + *p = __swab32p(p); +} + + + +#ifdef __BIG_ENDIAN + +#define __cpu_to_le16(x) ((uint16_t)__swab16((x))) +#define __cpu_to_le32(x) ((uint32_t)__swab32((x))) + +#define __cpu_to_le16s(x) __swab16s((x)) +#define __cpu_to_le32s(x) __swab32s((x)) + +#define __cpu_to_be16(x) ((uint16_t)(x)) +#define __cpu_to_be32(x) ((uint32_t)(x)) + +#define __cpu_to_be16s(x) { (void)(x); } +#define __cpu_to_be32s(x) { (void)(x); } + + + +#define __le16_to_cpu(x) __swab16((uint16_t)(x)) +#define __le32_to_cpu(x) __swab32((uint32_t)(x)) + +#define __le16_to_cpus(x) __swab16s((x)) +#define __le32_to_cpus(x) __swab32s((x)) + +#define __be16_to_cpu(x) ((uint16_t)(x)) +#define __be32_to_cpu(x) ((uint32_t)(x)) + +#define __be16_to_cpus(x) { (void)(x); } +#define __be32_to_cpus(x) { (void)(x); } + +#endif /* __BIG_ENDIAN */ + + +#ifdef __LITTLE_ENDIAN + +#define __cpu_to_le16(x) ((uint16_t)(x)) +#define __cpu_to_le32(x) ((uint32_t)(x)) + +#define __cpu_to_le16s(x) { (void)(x); } +#define __cpu_to_le32s(x) { (void)(x); } + +#define __cpu_to_be16(x) ((uint16_t)__swab16((x))) +#define __cpu_to_be32(x) ((uint32_t)__swab32((x))) + +#define __cpu_to_be16s(x) __swab16s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) + + + +#define __le16_to_cpu(x) ((uint16_t)(x)) +#define __le32_to_cpu(x) ((uint32_t)(x)) + +#define __le32_to_cpus(x) { (void)(x); } +#define __le16_to_cpus(x) { (void)(x); } + +#define __be16_to_cpu(x) __swab16((uint16_t)(uint16_t)(x)) +#define __be32_to_cpu(x) __swab32((uint32_t)(uint32_t)(x)) + +#define __be16_to_cpus(x) __swab16s((x)) +#define __be32_to_cpus(x) __swab32s((x)) + +#endif /* __LITTLE_ENDIAN */ + + + +/** these are the conversion macros */ + +/** convert cpu order to little endian */ +#define cpu_to_le16 __cpu_to_le16 +#define cpu_to_le32 __cpu_to_le32 + +/** in-place convert cpu order to little endian */ +#define cpu_to_le16s __cpu_to_le16s +#define cpu_to_le32s __cpu_to_le32s + +/** convert cpu order to big endian */ +#define cpu_to_be16 __cpu_to_be16 +#define cpu_to_be32 __cpu_to_be32 + +/** in-place convert cpu order to big endian */ +#define cpu_to_be16s __cpu_to_be16s +#define cpu_to_be32s __cpu_to_be32s + + +/* same, but in reverse */ + +/** convert little endian to cpu order*/ +#define le16_to_cpu __le16_to_cpu +#define le32_to_cpu __le32_to_cpu + +/** in-place convert little endian to cpu order*/ +#define le16_to_cpus __le16_to_cpus +#define le32_to_cpus __le32_to_cpus + +/** convert big endian to cpu order*/ +#define be16_to_cpu __be16_to_cpu +#define be32_to_cpu __be32_to_cpu + +/** in-place convert big endian to cpu order*/ +#define be16_to_cpus __be16_to_cpus +#define be32_to_cpus __be32_to_cpus + + + +#endif /* BYTEORDER_H */ diff --git a/IBSW/include/circular_buffer16.h b/IBSW/include/circular_buffer16.h new file mode 100644 index 0000000000000000000000000000000000000000..0bd045b2b2367e3f674f5e9952c2cc19f663301d --- /dev/null +++ b/IBSW/include/circular_buffer16.h @@ -0,0 +1,45 @@ +/** + * @file circular_buffer16.h + * @ingroup circular_buffer16 + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date October, 2013 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef CIRCULAR_BUFFER16_H +#define CIRCULAR_BUFFER16_H + +#include <stdint.h> + +struct circular_buffer16 { + uint16_t *p_buf_start; + uint32_t num_elem; + uint32_t read_pos; + uint32_t write_pos; +}; + +int32_t cbuf_init16(struct circular_buffer16 *p_buf, uint16_t* p_buf_start, uint32_t buffer_size); +void cbuf_reset16(struct circular_buffer16 *p_buf); + +uint32_t cbuf_read16 (struct circular_buffer16 *p_buf, uint16_t* dest, uint32_t elem); +uint32_t cbuf_write16(struct circular_buffer16 *p_buf, uint16_t* src, uint32_t elem); +uint32_t cbuf_peek16 (struct circular_buffer16 *p_buf, uint16_t* dest, uint32_t elem); + +uint32_t cbuf_get_used16(struct circular_buffer16 *p_buf); +uint32_t cbuf_get_free16(struct circular_buffer16 *p_buf); + +uint32_t cbuf_forward16(struct circular_buffer16 *p_buf, uint32_t elem); + + + +#endif diff --git a/IBSW/include/circular_buffer8.h b/IBSW/include/circular_buffer8.h new file mode 100644 index 0000000000000000000000000000000000000000..c18bec89044082ce04c5b3e5f07e3b04a9ef7a98 --- /dev/null +++ b/IBSW/include/circular_buffer8.h @@ -0,0 +1,45 @@ +/** + * @file circular_buffer8.h + * @ingroup circular_buffer8 + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date October, 2013 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef CIRCULAR_BUFFER8_H +#define CIRCULAR_BUFFER8_H + +#include <stdint.h> + +struct circular_buffer8 { + uint8_t *p_buf_start; + uint32_t num_elem; + uint32_t read_pos; + uint32_t write_pos; +}; + +int32_t cbuf_init8(struct circular_buffer8 *p_buf, uint8_t* p_buf_start, uint32_t buffer_size); +void cbuf_reset8(struct circular_buffer8 *p_buf); + +uint32_t cbuf_read8 (struct circular_buffer8 *p_buf, uint8_t* dest, uint32_t elem); +uint32_t cbuf_write8(struct circular_buffer8 *p_buf, uint8_t* src, uint32_t elem); +uint32_t cbuf_peek8 (struct circular_buffer8 *p_buf, uint8_t* dest, uint32_t elem); + +uint32_t cbuf_get_used8(struct circular_buffer8 *p_buf); +uint32_t cbuf_get_free8(struct circular_buffer8 *p_buf); + +uint32_t cbuf_forward8(struct circular_buffer8 *p_buf, uint32_t elem); + + + +#endif diff --git a/IBSW/include/clkgate.h b/IBSW/include/clkgate.h new file mode 100644 index 0000000000000000000000000000000000000000..bc629cef99273b7a0892c4eb8f43a7b6766a5ca2 --- /dev/null +++ b/IBSW/include/clkgate.h @@ -0,0 +1,50 @@ +/** + * @file clkgate.h + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief description of the clock gating register on the GR712RC + */ + +#ifndef CLKGATE_H +#define CLKGATE_H + + + +#define CLKGATE_GRETH 0x00000001 +#define CLKGATE_GRSPW0 0x00000002 +#define CLKGATE_GRSPW1 0x00000004 +#define CLKGATE_GRSPW2 0x00000008 +#define CLKGATE_GRSPW3 0x00000010 +#define CLKGATE_GRSPW4 0x00000020 +#define CLKGATE_GRSPW5 0x00000040 +#define CLKGATE_CAN 0x00000080 + +/* bit 8 is proprietary */ + +#define CLKGATE_CCSDS_TM 0x00000200 +#define CLKGATE_CCSDS_TC 0x00000400 +#define CLKGATE_1553BRM 0x00000800 + +#define CLKGATE_BASE 0x80000D00 + +__attribute__((unused)) +static struct gr712_clkgate { + uint32_t unlock; + uint32_t clk_enable; + uint32_t core_reset; +} *clkgate = (struct gr712_clkgate *) CLKGATE_BASE; + + + +#endif diff --git a/IBSW/include/compiler.h b/IBSW/include/compiler.h new file mode 100644 index 0000000000000000000000000000000000000000..7bf73afa39daf2f0de032d92479217142f525715 --- /dev/null +++ b/IBSW/include/compiler.h @@ -0,0 +1,46 @@ +/** + * @file compiler.h + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief a collection of preprocessor macros + */ + + +#ifndef COMPILER_H +#define COMPILER_H + + +/** + * Compile time check usable outside of function scope. + * Stolen from Linux (hpi_internal.h) + */ +#define compile_time_assert(cond, msg) typedef char ASSERT_##msg[(cond) ? 1 : -1] + + +/** + * same with the stuff below + */ + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +/* optimisation barrier */ +#define barrier() __asm__ __volatile__("": : :"memory") + +#define cpu_relax() barrier() + +#endif diff --git a/IBSW/include/core1553brm_as250.h b/IBSW/include/core1553brm_as250.h new file mode 100644 index 0000000000000000000000000000000000000000..3c2dc7762f65fc3ed7c274f8014947455edebf84 --- /dev/null +++ b/IBSW/include/core1553brm_as250.h @@ -0,0 +1,766 @@ +/** + * @file core1553brm_as250.h + * @ingroup core1553brm_as250 + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef CORE_1553_AS250_BRM_H +#define CORE_1553_AS250_BRM_H + + + +/* compile time check usable outside of function scope + * stolen from Linux (hpi_internal.h) + */ +#define compile_time_assert(cond, msg)\ + typedef char ASSERT_##msg[(cond) ? 1 : -1] + + + +/* + * AS250 protocol related + */ + + +#define AS250_TRANSFER_FRAME_SIZE 1024 + + +#define AS250_INITIALIZATION_COMPLETE 0x0001 +#define AS250_RT_NOT_SYNCHRIONIZED 0x0800 + +#define AS250_MC_RESET_RT 8 +#define AS250_MC_SYNC_W_DWORD 17 + +/* RX SA assignment */ +#define AS250_SA_RX_TERMCFG 1 +#define AS250_SA_RX_DDB_01 11 +#define AS250_SA_RX_DDB_02 12 +#define AS250_SA_RX_DDB_03 13 +#define AS250_SA_RX_DDB_04 14 +#define AS250_SA_RX_DDB_05 15 +#define AS250_SA_RX_DDB_06 16 +#define AS250_SA_RX_DDB_07 17 +#define AS250_SA_RX_DDB_08 18 +#define AS250_SA_RX_DDB_09 19 +#define AS250_SA_RX_DDB_10 20 +#define AS250_SA_RX_DDB_11 21 +#define AS250_SA_RX_DDB_12 22 +#define AS250_SA_RX_DDB_13 23 +#define AS250_SA_RX_DDB_14 24 +#define AS250_SA_RX_DDB_15 25 +#define AS250_SA_RX_DDB_16 26 +#define AS250_SA_RX_DTD 27 +#define AS250_SA_RX_TIME 29 +#define AS250_SA_RX_DWRAP 30 + +/* TX SA assignment */ +#define AS250_SA_TX_HLTHMON 1 +#define AS250_SA_TX_ADB_01 11 +#define AS250_SA_TX_ADB_02 12 +#define AS250_SA_TX_ADB_03 13 +#define AS250_SA_TX_ADB_04 14 +#define AS250_SA_TX_ADB_05 15 +#define AS250_SA_TX_ADB_06 16 +#define AS250_SA_TX_ADB_07 17 +#define AS250_SA_TX_ADB_08 18 +#define AS250_SA_TX_ADB_09 19 +#define AS250_SA_TX_ADB_10 20 +#define AS250_SA_TX_ADB_11 21 +#define AS250_SA_TX_ADB_12 22 +#define AS250_SA_TX_ADB_13 23 +#define AS250_SA_TX_ADB_14 24 +#define AS250_SA_TX_ADB_15 25 +#define AS250_SA_TX_ADB_16 26 +#define AS250_SA_TX_DTC 27 +#define AS250_SA_TX_ATR 28 +#define AS250_SA_TX_DWRAP 30 + +/* mode codes */ +#define BRM_MC_DYNAMIC_BUS_CONTROL 0b00000 +#define BRM_MC_SYNCHRONIZE 0b00001 +#define BRM_MC_TRANSMIT_STATUS_WORD 0b00010 +#define BRM_MC_INITIATE_SELF_TEST 0b00011 +#define BRM_MC_TRANSMITTER_SHUTDOWN 0b00100 +#define BRM_MC_OVERRIDE_TRANSMITTER_SHUTDOWN 0b00101 +#define BRM_MC_INHIBIT_TERMINAL_FLAG_BIT 0b00110 +#define BRM_MC_OVERRIDE_INHIBIT_TERMINAL_FLAG_BIT 0b00111 +#define BRM_MC_RESET_REMOTE_TERMINAL 0b01000 + +#define BRM_MC_TRANSMIT_VECTOR_WORD 0b10000 +#define BRM_MC_SYNCHRONIZE_WITH_DATA_WORD 0b10001 +#define BRM_MC_TRANSMIT_LAST_COMMAND_WORD 0b10010 +#define BRM_MC_TRANSMIT_BUILTIN_TEST_WORD 0b10011 +#define BMR_MC_SELECTED_TRANSMITTER_SHUTDOWN 0b10100 +#define BRM_MC_OVERRIDE_SLECTED_TRANSMITTER_SHUTDOWN 0b10101 + +/* + * + * NOTE: can't safely use sizeof() for memcpy here, use the define + */ + +#define TIME_PACKET_BYTES 10 + +__extension__ +#define AS250_SA_TX_ADB_01 11 +#define AS250_SA_TX_ADB_02 12 +#define AS250_SA_TX_ADB_03 13 +#define AS250_SA_TX_ADB_04 14 +#define AS250_SA_TX_ADB_05 15 +#define AS250_SA_TX_ADB_06 16 +#define AS250_SA_TX_ADB_07 17 +#define AS250_SA_TX_ADB_08 18 +#define AS250_SA_TX_ADB_09 19 +#define AS250_SA_TX_ADB_10 20 +#define AS250_SA_TX_ADB_11 21 +#define AS250_SA_TX_ADB_12 22 +#define AS250_SA_TX_ADB_13 23 +#define AS250_SA_TX_ADB_14 24 +#define AS250_SA_TX_ADB_15 25 +#define AS250_SA_TX_ADB_16 26 +#define AS250_SA_TX_DTC 27 +#define AS250_SA_TX_ATR 28 +#define AS250_SA_TX_DWRAP 30 + + +struct time_packet { + union { + uint16_t word0; + struct { + uint8_t null_field; + union { + struct { + uint8_t extension :1; + uint8_t time_code_id :3; + uint8_t num_bytes_coarse_time_min_1 :2; + uint8_t num_bytes_fine_time :2; + }; + uint8_t p_field; /*always 0b00101111 or 0x2f*/ + }; + }; + }; + + union { + struct { + uint16_t word1; + uint16_t word2; + }; + uint32_t coarse_time; + }; + + union { + uint32_t fine_time32; + uint16_t word3; + uint16_t word4; + struct { + uint32_t fine_time :24; + uint8_t unused; /* always 0x0*/ + }; + }; +}__attribute__((packed)); + + +/* see DIV.SP.00030.T.ASTR Issue 1 Rev 1, p34 */ +#define AS250_TIME_PACKET_SIZE 10 + +compile_time_assert((sizeof(struct time_packet) + == AS250_TIME_PACKET_SIZE), + TIME_PACKET_STRUCT_WRONG_SIZE); + + + +#define swap_time(x) ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 16) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 16) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 16) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 16))) + + +/* + * AS250 p.36 + */ + +#define AS250_TRANSFER_DESCRIPTOR_SIZE 0x4 /* 2x 16 bit words */ + +__extension__ +struct transfer_descriptor { + + union{ + struct { + uint16_t unused :4; + uint16_t transfer_size :12; + }; + uint16_t word0; + }; + + union{ + struct { + uint8_t qos_err :1; + uint8_t reset :1; + uint8_t mode :1; + uint8_t subaddress :5; + uint8_t block_counter; + }; + uint16_t word1; + }; + +}; + +/* + * check whether the descriptor structure was actually aligned + * to be the same size + */ +compile_time_assert((sizeof(struct transfer_descriptor) + == AS250_TRANSFER_DESCRIPTOR_SIZE), + TRANSFER_DESC_STRUCT_WRONG_SIZE); + + + +/** + * BRM related + */ + + +#define BRM_RTA_BITS 0x1F /* the RTA is at most 5 bits */ +#define BRM_WCMC_BITS 0x1F /* the WC/MC field is at most 5 bits */ +#define BRM_WCMC_SHIFT 0x0B /* the WC/MC field starts at bit 11 */ + + +/* + * memory structure in RT mode (see Core1553BRM v4.0 Handbook, pp.54) + * 128k mode + */ +/* NOTE: eventually make this configurable by mode and number of + * buffers used (requires custome determination of log list position) + * (for CHEOPS we'll just use it in this predetermined form) */ +/* 20 kiB is just enough with 2 buffers per SA, we waste only ~1.6kiB + * (along with the 128 needed for alignment */ +#define BRM_MEM_BLOCK_SIZE_KBYTES 20 + +#define BRM_MEM_BLOCK_SIZE_BYTES (BRM_MEM_BLOCK_SIZE_KBYTES * 1024) + +/* brm memory must be aligned to a boundary of 128 kiB + * (see GR712RC UM p. 160 */ +#define BRM_MEM_BLOCK_ALIGN_SIZE (128 * 1024) +#define BRM_MEM_BLOCK_ALIGN (BRM_MEM_BLOCK_ALIGN_SIZE - 1) +#define BRM_NUM_SUBADDR 32 +#define BRM_NUM_DATAWORDS 32 +#define BRM_NUM_DATABYTES (BRM_NUM_DATAWORDS * 2) +#define BRM_HEADER_WORDS 2 + /* +2: compensate overflow */ +#define BRM_RT_MEMMAP_DESCRIPTOR_BLOCK_MAX_SIZE (BRM_NUM_DATAWORDS + 2) +#define BRM_RT_MEMMAP_DESCRIPTOR_BLOCK_ENTRIES 128 +#define BRM_CBUF_PAGES 2 +#define BRM_CBUF_PAGES_MIN 2 +#define BRM_CBUF_PAGES_MAX 8 +#define BRM_IRQ_LOG_ENTRY_PAGES 16 + + +/* + * Interrupt Mask Register, see Core1553BRM v4.0 Handbook, pp.75 + */ + +#define BRM_IRQ_MBC 0x0001 /* Monitor Block Counter */ +#define BRM_IRQ_CBA 0x0002 /* Command Block Accessed */ +#define BRM_IRQ_RTF 0x0004 /* Retry Fail */ +#define BRM_IRQ_ILLOP 0x0008 /* Illogical Opcode */ +#define BRM_IRQ_BC_ILLCMD 0x0010 /* BC Illocigal Command */ +#define BRM_IRQ_EOL 0x0020 /* End Of List */ +#define BRM_IRQ_RT_ILLCMD 0x0080 /* RT Illegal Command */ +#define BRM_IRQ_IXEQ0 0x0100 /* Index Equal Zero */ +#define BRM_IRQ_BDRCV 0x0200 /* Broadcast Command Received */ +#define BRM_IRQ_SUBAD 0x0400 /* Subaddress Accessed */ +#define BRM_IRQ_MERR 0x0800 /* Message Error */ +#define BRM_IRQ_BITF 0x1000 /* Bit Fail */ +#define BRM_IRQ_TAPF 0x2000 /* Terminal Address Parity Fail */ +#define BRM_IRQ_WRAPF 0x4000 /* Wrap Fail */ +#define BRM_IRQ_DMAF 0x8000 /* DMA Fail */ + + +/* + * interrupt message acknowledge + * controls intackh/intackm input signals of core + */ + +#define IRQ_ACK_HW 0x0002 /* acknowledge hardware interrupts */ +#define IRQ_ACK_MSG 0x0004 /* acknowledge message interrupts */ + + +/* + * RT mode control word flags, see Core1553BRM v4.0 Handbook, p.56 + */ + +#define BRM_RT_CW_FLAGS_NII 0x0001 /* Notice II */ +#define BRM_RT_CW_FLAGS_BRD 0x0002 /* Broadcast */ +#define BRM_RT_CW_FLAGS_AB 0x0004 /* A or B Buffer */ +#define BRM_RT_CW_FLAGS_LAB 0x0008 /* Last A or B Buffer */ +#define BRM_RT_CW_FLAGS_BAC 0x0010 /* Block Accessed */ +#define BRM_RT_CW_FLAGS_IBRD 0x0020 /* Interrupt Broadcast Received */ +#define BRM_RT_CW_FLAGS_IWA 0x0040 /* Interrupt When Accessed */ +#define BRM_RT_CW_FLAGS_INTX 0x0080 /* Interrupt Equals Zero */ + +#define BRM_RT_CW_INDX_MASK 0xFF00 /* Index: depth of multi-msg buffer */ + +/** + * common control register (reg 0) flags + */ + +#define BRM_CCR_XMTSW 0x0001 /* transmit word status enable */ +#define BRM_CCR_INEN 0x0002 /* interrupt log list enable */ +#define BRM_CCR_PPEN 0x0004 /* ping pong enable */ +#define BRM_CCR_DYNBC 0x0008 /* dynamic bus controll acceptance */ +#define BRM_CCR_BCEN 0x0010 /* broadcast enable */ +#define BRM_CCR_BMC 0x0020 /* bus monitor control */ +#define BRM_CCR_DUMMY 0x0040 /* bit 6 = unused */ +#define BRM_CCR_BUF_NCM0 0x0000 /* non-circular buffer mode 0 */ +#define BRM_CCR_BUF_NCM1 0x0080 /* non-circular buffer mode 0 */ +#define BRM_CCR_BUF_CBCS 0x0100 /* (combined storage) */ +#define BRM_CCR_BUF_CBSS 0x0180 /* (segregated storage) */ +#define BRM_CCR_MSGTO 0x0200 /* message timeout */ +#define BRM_CCR_ETCE 0x0400 /* external timer clock enable */ +#define BRM_CCR_BBEN 0x0800 /* Bus B enable */ +#define BRM_CCR_BAEN 0x1000 /* Bus A enable */ +#define BRM_CCR_SRST 0x2000 /* software reset */ +#define BRM_CCR_SBIT 0x4000 /* enable start BIT + (LOW = init core op) */ +#define BRM_CCR_STEX 0x8000 /* start execution */ + +#define BRM_CCR_BUF_CLR 0xFE7F /* buffer mode clear mask */ + +#define BRM_CCR_MSEL_CLR 0xFCFF /* mode select clear mask + [LOW = BC mode] */ +#define BRM_CCR_RTA_MASK 0xF800 /* remote terminal address bitmask */ +#define BRM_CCR_RTPTY_MASK 0x0001 /* remote terminal address parity */ +#define BRM_CCR_RTPTY_REG 10 /* remote terminal address parity bit*/ +#define BRM_CCR_RTA_REG 11 /* remote terminal address + bitfield base */ + + /* remote terminal address + parity */ +#define BRM_CCR_RTA(x) ((x << BRM_CCR_RTA_REG) & BRM_CCR_RTA_MASK) + + +/* + * operation and status register (reg 1) flags + */ + +#define BRM_OSR_TERACT 0x0001 /* terminal active, [RO] */ +#define BRM_OSR_READY 0x0002 /* READY status, [RO] */ +#define BRM_OSR_TAPF 0x0004 /* RT Address Parity Fail, [RO] */ +#define BRM_OSR_EX 0x0008 /* Core Executing, [RO] */ +#define BRM_OSR_SSYSF 0x0010 /* SSYSF Status, [RO] */ +#define BRM_OSR_DUMMY 0x0020 /* bit 5 = unused */ +#define BRM_OSR_LOCK 0x0040 /* LOCK status [RO] */ +#define BRM_OSR_ABSTD 0x0080 /* set MIL-STD-1553(A), + (LOW = 1553(B)) */ +#define BRM_OSR_MSEL_BC 0x0000 /* mode select: BC */ +#define BRM_OSR_MSEL_RT 0x0100 /* mode select: RT */ +#define BRM_OSR_MSEL_BM 0x0200 /* mode select: BM */ +#define BRM_OSR_MSEL_BMRT 0x0300 /* mode select: BM & RT */ +#define BRM_OSR_RTPTY 0x0400 /* RT address odd parity if HIGH*/ + + +/* + * command legalisation registers + */ +#define BMR_LEG_CMDS 16 +#define BMR_LEG_CMDS_PER_REGISTER 16 + +#define BRM_LEG_CMD_LEGAL 0UL +#define BRM_LEG_CMD_ILLEGAL 1UL + +#define BRM_LEG_CMD_LEGALIZE(field, cmd) do { \ + field &= (typeof(field)) ~(BRM_LEG_CMD_ILLEGAL << cmd); \ +} while (0) + +#define BRM_LEG_CMD_ILLEGALIZE(field, cmd) do { \ + field &= ((typeof(field)) BRM_LEG_CMD_ILLEGAL << cmd); \ +} while (0) + +#define BRM_LEG_CMD_ILLEGALIZE_ALL(field) do { \ + field = ((typeof(field)) (BRM_LEG_CMD_ILLEGAL \ + << BMR_LEG_CMDS_PER_REGISTER) - 1UL); \ +} while (0) + +#define BRM_LEG_CMD_LEGALIZE_ALL(field) do { \ + field = (typeof(field)) BRM_LEG_CMD_LEGAL; \ +} while (0) + + +#define BRM_LEG_CMD_SA_RX__0_15 0 +#define BRM_LEG_CMD_SA_RX_16_31 1 +#define BRM_LEG_CMD_SA_TX__0_15 2 +#define BRM_LEG_CMD_SA_TX_16_31 3 +#define BRM_LEG_CMD_SA_BC_RX__0_15 4 +#define BRM_LEG_CMD_SA_BC_RX_16_31 5 +#define BRM_LEG_CMD_SA_BC_TX__0_15 6 +#define BRM_LEG_CMD_SA_BC_TX_16_31 7 +#define BRM_LEG_CMD_MC_RX__0_15 8 +#define BRM_LEG_CMD_MC_RX_16_31 9 +#define BRM_LEG_CMD_MC_TX__0_15 10 +#define BRM_LEG_CMD_MC_TX_16_31 11 +#define BRM_LEG_CMD_MC_BC_RX__0_15 12 +#define BRM_LEG_CMD_MC_BC_RX_16_31 13 +#define BRM_LEG_CMD_MC_BC_TX__0_15 14 +#define BRM_LEG_CMD_MC_BC_TX_16_31 15 + +/* + * enhanced register flags + * (incomplete) + */ + +#define BRM_FREQ_12MHZ 0x0 +#define BRM_FREQ_16MHZ 0x1 +#define BRM_FREQ_20MHZ 0x2 +#define BRM_FREQ_24MHZ 0x3 +#define BRM_FREQ_MASK 0x3 + + + + +/* + * BRM register map + * registers are mapped to be 4-byte aligned, but only lower + * 2 bytes are used (see GR712RC-UM, p. 162) + */ +struct brm_reg { + uint32_t ctrl; /* 0x00 */ + uint32_t oper; /* 0x04 */ + uint32_t cur_cmd; /* 0x08 */ + uint32_t imask; /* 0x0C */ + uint32_t ipend; /* 0x10 */ + uint32_t ipoint; /* 0x14 */ + uint32_t bit_reg; /* 0x18 */ + uint32_t ttag; /* 0x1C */ + uint32_t dpoint; /* 0x20 */ + uint32_t sw; /* 0x24 */ + uint32_t initcount; /* 0x28 */ + uint32_t mcpoint; /* 0x2C */ + uint32_t mdpoint; /* 0x30 */ + uint32_t mbc; /* 0x34 */ + uint32_t mfilta; /* 0x38 */ + uint32_t mfiltb; /* 0x3C */ + uint32_t rt_cmd_leg[BMR_LEG_CMDS]; /* 0x40-0x80 */ + uint32_t enhanced; /* 0x84 */ + + uint32_t dummy[31]; + + uint32_t w_ctrl; /* 0x100 */ + uint32_t w_irqctrl; /* 0x104 */ + uint32_t w_ahbaddr; /* 0x108 */ +}; + + + +/* + * interrupt log list structure + * + * (see Core1553BRM v4.0 Handbook, p.86) + * + */ + +struct brm_irq_log_entry { + uint16_t IIW; /* interrupt information word */ + uint16_t IAW; /* interrupt address word */ +}; + + +/* + * data buffer structure + * + * (see Core1553BRM v4.0 Handbook, p.54 and pp. 57) + * + * GNU extensions: *) unnamed structs/unions + * + */ + +__extension__ +struct brm_data_buffer { + union { + struct { + uint16_t MIW; + uint16_t timetag; + uint16_t data[BRM_NUM_DATAWORDS]; + }; + uint16_t block[BRM_RT_MEMMAP_DESCRIPTOR_BLOCK_MAX_SIZE]; + }; +}; + +/* + * data buffer structures in circular buffer mode 1 + * + * (see Core1553BRM v4.0 Handbook, p.61) + */ + +struct brm_message_circular_buffer { + struct brm_data_buffer page[BRM_CBUF_PAGES]; +}; + + +/* + * descriptor block for different RT modes + * for circular buffer combined storage (mode 1): + * cw | top buffer | current buffer | bottom buffer + * for indexed/ping-pong mode: + * cw | data ptr A | data ptr B | bcast data ptr + * + * (see Core1553BRM v4.0 Handbook, p.55, pp.61) + * + * GNU extensions: *) unnamed structs/unions + * + */ + +__extension__ +struct brm_descriptor_table { + uint16_t CW; + union { + uint16_t top; + uint16_t buf_A; + }; + union { + uint16_t current; + uint16_t buf_B; + }; + union { + uint16_t bottom; + uint16_t bcast; + }; +}; + + +/* + * Remote Terminal Memory Map + * GNU extensions: *) unnamed structs/unions + * *) zero-length array + */ + +__extension__ +struct brm_rt_mem_map { + + union { + struct { + /* RX sub address descriptor block */ + struct brm_descriptor_table sa_rx[BRM_NUM_SUBADDR]; + /* TX sub address descriptor block */ + struct brm_descriptor_table sa_tx[BRM_NUM_SUBADDR]; + /* RX mode code descriptor bocks */ + struct brm_descriptor_table mc_rx[BRM_NUM_SUBADDR]; + /* TX mode code descriptor bocks */ + struct brm_descriptor_table mc_tx[BRM_NUM_SUBADDR]; + }; + + /* RX sub address descriptor block */ + struct brm_descriptor_table descriptors[BRM_NUM_SUBADDR * 4]; + }; + + union { + struct { + /* RX Sub Address messages */ + struct brm_message_circular_buffer + sa_msgs_rx[BRM_NUM_SUBADDR]; + /* RX Sub Address messages */ + struct brm_message_circular_buffer + sa_msgs_tx[BRM_NUM_SUBADDR]; + /* RX mode code messages */ + struct brm_message_circular_buffer + mc_msgs_rx[BRM_NUM_SUBADDR]; + /* TX mode code messages */ + struct brm_message_circular_buffer + mc_msgs_tx[BRM_NUM_SUBADDR]; + }; + struct brm_message_circular_buffer + messages[BRM_NUM_SUBADDR * 4]; + }; + + + /** + * track the index of the read pointer in rt circular + * buffer or pp mode for each entry + */ + union { + struct { + uint16_t sa_rx[BRM_NUM_SUBADDR]; + uint16_t sa_tx[BRM_NUM_SUBADDR]; + uint16_t mc_rx[BRM_NUM_SUBADDR]; + uint16_t mc_tx[BRM_NUM_SUBADDR]; + }; + uint16_t block[BRM_RT_MEMMAP_DESCRIPTOR_BLOCK_ENTRIES]; + } desc_block_rd_ptr; + + union { + uint16_t sa_tx[BRM_NUM_SUBADDR]; + uint16_t block[BRM_NUM_SUBADDR]; + } desc_block_wr_ptr; + + + /* compute unused offset to log list section (64 bytes from bottom) */ +#define BRM_RT_NUM_BYTES_OFFSET (BRM_MEM_BLOCK_SIZE_BYTES \ + - 4 * BRM_NUM_SUBADDR * sizeof(struct brm_descriptor_table) \ + - 4 * BRM_NUM_SUBADDR * sizeof(struct brm_message_circular_buffer) \ + - BRM_IRQ_LOG_ENTRY_PAGES * sizeof(struct brm_irq_log_entry) \ + - 4 * BRM_NUM_SUBADDR * sizeof(uint16_t) \ + - BRM_NUM_SUBADDR * sizeof(uint16_t) \ + ) + + /* zero-sized arrays are allowed in gnu89, so this is always ok */ + uint16_t unused[BRM_RT_NUM_BYTES_OFFSET >> 1]; + + /* interrupt log at 64 bytes from end */ + struct brm_irq_log_entry irq_log[BRM_IRQ_LOG_ENTRY_PAGES]; +}; + +/* check if brm_rt_mem_map wants to occupy larger memory block than possible */ +compile_time_assert((BRM_RT_NUM_BYTES_OFFSET >= 0), RT_MEM_BLOCK_TOO_LARGE); + + +/* + * offset to bottom address of circular buffer msgs + */ + +#define CBUF_BOTTOM_ADDR_OFFSET_ADJUST(x) ((uint16_t) \ + (((((x) * sizeof(struct brm_data_buffer)) >> 1) \ + - sizeof(uint16_t)) & 0xFFFF)) + + + + +/* + * manage log list and circular message buffers + */ + +#define BRM_IIW_PATTERN_INVALID 0xFFFF + +#define BRM_LOGLIST_INCREMENT_READPOS(cbuf_readpos, BRM_LOGLIST_NUM_ELEMENTS) \ + do { \ + cbuf_readpos++; \ + if (cbuf_readpos >= BRM_LOGLIST_NUM_ELEMENTS) { \ + cbuf_readpos = 0; \ + } \ + } while (0) + +/* word count for 1553brm circular buffers: data words + MIW + time stamp */ +#define BRM_WORDCOUNT(x) ((x) ? (BRM_HEADER_WORDS+(x)) :\ + (BRM_HEADER_WORDS+BRM_NUM_DATAWORDS)) + +#define BRM_DATAWORDCOUNT(x) ((x) ? ((x)) : (BRM_NUM_DATAWORDS)) + +#define BRM_GET_WCMC(x) (((x) >> BRM_WCMC_SHIFT) & BRM_WCMC_BITS) + +#define BRM_SET_WCMC(x) (((x) & BRM_WCMC_BITS) << BRM_WCMC_SHIFT) + + +/* + * 32bit address to 16bit core base addressing scheme + * (see p78 Core1553BRM Manual, "Register 05 – Interrupt Pointer") + * (see also p57, "Data Pointer A and B") + */ + +#define BASE_ADDR(x) ((((uint32_t) (&x)) & 0x0001FFFF) >> 1) + +#define BRM_CALC_SA_RX_DESC(x) (x) +#define BRM_CALC_SA_TX_DESC(x) ((x) - BRM_NUM_SUBADDR) +#define BRM_CALC_MC_RX_DESC(x) ((x) - BRM_NUM_SUBADDR * 2) +#define BRM_CALC_MC_TX_DESC(x) ((x) - BRM_NUM_SUBADDR * 3) + + + +/* + * data exchange buffers + */ + +struct brm_interface_buffers { + uint8_t *adb_ddb; + struct cpus_buffers *atr_cpus; + struct packet_tracker *pkt_gnd; + struct packet_tracker *pkt_obc; +}; + +/* + * tracked as250 values + */ + +struct as250_param { + struct transfer_descriptor atr; + uint8_t atd_blk_cnt; + uint8_t dtd_blk_cnt; +}; + + +/* + * 1553/as250 driver configuration + * ping-pong is now the only supported mode + */ + +struct brm_config { + uint16_t *brm_mem; + struct brm_reg *regs; + struct brm_rt_mem_map *rt_mem; + struct brm_interface_buffers buf; + struct as250_param as250; + enum {PING_PONG, CBUF_COMBINED_STORAGE} mode; + void *set_time_userdata; + void *rt_sync_with_dword_userdata; + void *rt_reset_userdata; + void (*set_time)(uint32_t coarse_time, + uint32_t fine_time, + void *userdata); + void (*rt_sync_with_dword)(uint16_t frame_num, void *userdata); + void (*rt_reset)(void *userdata); +}; + + + +/* forward-declarations */ +struct cpus_buffers; +struct packet_tracker; + +void gr712_set_core_freq(void); + +int32_t brm_1553_enable(struct brm_config *brm); +uint32_t brm_rt_init(struct brm_config *brm, + uint8_t rt_address, + uint32_t core_freq); + +int32_t brm_set_packet_tracker_obc(struct brm_config *brm, + struct packet_tracker *pkt_obc); + +int32_t brm_set_packet_tracker_gnd(struct brm_config *brm, + struct packet_tracker *pkt_gnd); + +int32_t brm_set_adb_ddb_buffer(struct brm_config *brm, uint8_t *p_buf); + + +int32_t as250_set_time_callback(struct brm_config *brm, + void (*callback)(uint32_t coarse_time, + uint32_t fine_time, + void *userdata), + void *userdata); + +int32_t as250_set_rt_reset_callback(struct brm_config *brm, + void (*callback)(void *userdata), + void *userdata); + +int32_t as250_set_sync_with_dword_callback(struct brm_config *brm, + void (*callback)(uint16_t frame_num, + void *userdata), + void *userdata); + +int32_t as250_set_atr_cpus_buffers(struct brm_config *brm, + struct cpus_buffers *p_cpus); + +void as250_desynchronized(struct brm_config *brm); +void as250_synchronized(struct brm_config *brm); + + +#endif + diff --git a/IBSW/include/cpus_buffers.h b/IBSW/include/cpus_buffers.h new file mode 100644 index 0000000000000000000000000000000000000000..36d859531da0899ef0e9248ea737591c82e45cce --- /dev/null +++ b/IBSW/include/cpus_buffers.h @@ -0,0 +1,73 @@ +/** + * @file cpus_buffers.h + * @ingroup cpus_buffer + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date June, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef CPUS_BUFFERS_H +#define CPUS_BUFFERS_H + + +#include <circular_buffer8.h> +#include <circular_buffer16.h> +#include <core1553brm_as250.h> +#include <stdint.h> + +#define CBUF_PUS_FRAMES 2 +#define CBUF_PUS_OVERFLOW_FRAMES 1 + +#ifndef PUS_PKT_MIN_SIZE +#define PUS_PKT_MIN_SIZE 12 +#endif + + +#define CBUF_PKTS_ELEM (AS250_TRANSFER_FRAME_SIZE * \ + (CBUF_PUS_FRAMES+CBUF_PUS_OVERFLOW_FRAMES)) + +#define CBUF_SIZE_ELEM (CBUF_PKTS_ELEM/PUS_PKT_MIN_SIZE) +#define CBUF_VALID_ELEM (CBUF_PKTS_ELEM/PUS_PKT_MIN_SIZE) + +#define CBUF_PUS_VALID 0x00 +#define CBUF_PUS_INVALID 0xFF + + + +struct cpus_buffers { + struct circular_buffer8 pus_pkts; + struct circular_buffer16 pus_size; + struct circular_buffer8 pus_valid; +}; + + +void cpus_init(struct cpus_buffers *p_cpus, + uint8_t *p_buf_pkts, + uint16_t *p_buf_size, + uint8_t *p_buf_valid); + +void cpus_reset(struct cpus_buffers *p_cpus); + +uint32_t cpus_get_free(struct cpus_buffers *p_cpus); + +int32_t cpus_next_valid_pkt_size(struct cpus_buffers *p_cpus); + +int32_t cpus_push_packet(struct cpus_buffers *p_cpus, + uint8_t *pus_pkt, + uint16_t size); + +int32_t cpus_pop_packet(struct cpus_buffers *p_cpus, + uint8_t *pus_pkt); + + +#endif diff --git a/IBSW/include/edac.h b/IBSW/include/edac.h new file mode 100644 index 0000000000000000000000000000000000000000..30f1c50b6ddd0456486d2d7ffaf2f930f5153f0a --- /dev/null +++ b/IBSW/include/edac.h @@ -0,0 +1,34 @@ +/** + * @file edac.h + * @ingroup edac + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date March, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#ifndef EDAC_H +#define EDAC_H + +#include <stdint.h> + +uint8_t edac_checkbits(const uint32_t value); + +void edac_trap(void); +int32_t edac_ahb_irq(void *userdata); + +int32_t edac_set_reset_callback(void (*callback)(void *userdata), + void *userdata); +int32_t edac_init_sysctl(void); + +#endif /* EDAC_H */ diff --git a/IBSW/include/error_log.h b/IBSW/include/error_log.h new file mode 100644 index 0000000000000000000000000000000000000000..16ed9c3152ee049852f8dedc6a1b271b1a8e00bd --- /dev/null +++ b/IBSW/include/error_log.h @@ -0,0 +1,83 @@ +/** + * @file error_log.h + * @ingroup error_log + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef ERROR_LOG_H +#define ERROR_LOG_H + + +#include <stdint.h> +#if (__sparc__) +#include <CrIaDataPool.h> +#else +#define ERR_LOG_N2 12 /* DBS-SRS-FN-1745 */ +#endif + +/** + * @note + * BELG-9/A/T requires that the error log should hold ERR_LOG_N1 entries, + * which is defined to be 60 in CHEOPS-PNP-INST-ICD-002 rev 5 + * In CHEOPS-IWF-INST-ICD-009 issue 2.2, DPU-SICD-IF-3540 and DPU-SICD-IF-3960 + * suggest that the log should be the size of 64 entries, as does + * DBS-SRS-FN-1708 in CHEOPS-IWF-INST-RS-013 isse 2.0 + * + * For the sake of compatibility to the DBS, we will use a size of 64 entries + */ + +#define RAM_ERROR_LOG_BASE 0x40050000 +#define RAM_ERROR_LOG_SIZE 0x04000000 +#define ERROR_LOG_MAX_ENTRIES 64 +#define ERROR_LOG_MAX_USABLE (ERROR_LOG_MAX_ENTRIES - 1) +#define SIZEOF_ERR_LOG_ENTRY 20 + + +__extension__ +struct event_time { + uint32_t coarse_time; + uint16_t fine_time; +}__attribute__((packed)); + +struct error_log_entry { + struct event_time time; + uint16_t err_evt_id; + uint8_t err_log_info[ERR_LOG_N2]; +}__attribute__((packed)); + +/* CHEOPS-IWF-INST-ICD-009: DPU-SICD-IF-3540 */ +struct error_log { + uint32_t err_log_next; + uint32_t err_log_next_unsaved; + struct error_log_entry entry[ERROR_LOG_MAX_ENTRIES]; +}; + + +void error_log_init(struct error_log **log); + +void error_log_add_entry(struct error_log *log, struct event_time *time, + uint16_t error_id, uint8_t *error_log_info); + +uint32_t error_log_read_entry_raw(struct error_log *log, + struct error_log_entry *log_entry); + +uint32_t error_log_read_entry(struct error_log *log, struct event_time *time, + uint16_t *error_id, uint8_t *error_log_info); + +uint32_t error_log_num_entries(struct error_log *log); + +void error_log_dump_reverse(struct error_log *log, uint8_t *buf); + +#endif diff --git a/IBSW/include/errors.h b/IBSW/include/errors.h new file mode 100644 index 0000000000000000000000000000000000000000..c2f7e75f3ed1a9114acf9968b9f6de8871c4bd32 --- /dev/null +++ b/IBSW/include/errors.h @@ -0,0 +1,377 @@ +/** + * @file errors.h + * @ingroup grspw2 + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief this extends errno.h definitions for more detailed error tracking + * + * The BCC errno.h implementation sets an offset after which custom error + * number may be defined. We set up classes of errors for some of the + * software in the IBSW package, each offset by 100 from each other. + */ + +#ifndef ERRORS_H +#define ERRORS_H + + +#include <errno.h> + +/* + * start counting up from last errno value + 1 + */ +#ifdef __ELASTERROR +#define ERR_BASE (__ELASTERROR) +#else +#define ERR_BASE 2000 +#endif + + +/* + * detailed errno definitions go below + */ + + +/** + * @def E_CPUS_PKT_SIZE_LIMIT + * attempted to push a packet larger than the transfer frame size of the + * AS250 protocol + * + * @def E_CPUS_FORWARD_WRITE + * could not forward the write position of the underlying circular buffer + * + * @def E_CPUS_PATTERN_WRITE + * could not write (in)valid pattern marker + * + * @def E_CPUS_SIZE_WRITE + * could not write of size of packet + * + * @def E_CPUS_PKT_READ + * error reading packet data from buffer + * + * @def E_CPUS_PKT_WRITE + * could not write packet data + * + * @def E_CPUS_FULL + * buffer full, could not accept packet data + * + * @def E_CPUS_PUSH_INVALID + * could not write invalid pattern + * + * @def E_CPUS_WRITE + * could not write packet to buffer + */ + +/* + * circularly buffered PUS frame constructor errors + */ + +#define ERR_CPUS_OFF 100 +#define ERR_CPUS(x) (x+ERR_BASE+ERR_CPUS_OFF) + +#define E_CPUS_PKT_SIZE_LIMIT ERR_CPUS(1) +#define E_CPUS_FORWARD_WRITE ERR_CPUS(2) +#define E_CPUS_PATTERN_WRITE ERR_CPUS(3) +/* error 4 removed */ +#define E_CPUS_SIZE_WRITE ERR_CPUS(5) +#define E_CPUS_PKT_READ ERR_CPUS(6) +#define E_CPUS_PKT_WRITE ERR_CPUS(7) +#define E_CPUS_FULL ERR_CPUS(8) +#define E_CPUS_PUSH_INVALID ERR_CPUS(9) +#define E_CPUS_WRITE ERR_CPUS(10) +/* error 11 removed */ +/* error 12 removed */ + + + +/** + * @def E_PTRACK_PKT_SIZE_LIMIT + * packet size excceds buffer size + * + * @def E_PTRACK_PKT_WRITE + * could not write packet data + * + * @def E_PTRACK_SIZE_WRITE + * could not write of size of packet + * + * @def E_PTRACK_PKT_READ + * error while reading a packet (size mismatch) + * + * @def E_PTRACK_NOPKT + * there was no packet + * + * @def E_PTRACK_INVALID + * the packet tracker reference was not a valid pointer + */ + +/* + * circularly buffered pus packet tracker + */ + +#define ERR_PTRACK_OFF 200 +#define ERR_PTRACK(x) (x+ERR_BASE+ERR_PTRACK_OFF) + +#define E_PTRACK_PKT_SIZE_LIMIT ERR_PTRACK(1) +#define E_PTRACK_PKT_WRITE ERR_PTRACK(2) +#define E_PTRACK_SIZE_WRITE ERR_PTRACK(3) +#define E_PTRACK_PKT_READ ERR_PTRACK(4) +#define E_PTRACK_NOPKT ERR_PTRACK(5) +#define E_PTRACK_INVALID ERR_PTRACK(6) + + +/** + * @def E_BRM_MEM_ADDR_ALIGN + * the supplied memory block is not properly aligned + * + * @def E_BRM_INVALID_COREFREQ + * the specified 1553 core frequency is not valid + * + * @def E_BRM_INVALID_PKT_SIZE + * the size field of an alleged packet exceeded the allowed size + * + * @def E_BRM_INVALID_PKT_ID + * the packet's PUS id was invalid + * + * @def E_BRM_IRQ_RT_ILLCMD + * the bus controller wrote an illegal 1553 command + * + * @def E_BRM_IRQ_ILLOP + * the bus controller wrote an illegal 1553 operation + * + * @def E_BRM_IRQ_MERR + * a message error occured on the bus + * + * @def E_BRM_IRQ_DMAF + * a DMA fault occured + * + * @def E_BRM_IRQ_WRAPF + * a wrap fault occured + * + * @def E_BRM_IRQ_TAPF + * a terminal address parity fault occured + * + * @def E_BRM_IRQ_BITF + * a BIT fail occured + * + * @def E_BRM_IRQ_IXEQ0 + * an Index Equal Zero occured + * + * @def E_BRM_CW_BAC_FLAG + * an block access was reported, but the block access flag was not set + * + * @def E_BRM_INVALID_TRANSFER_SIZE + * the specified transfer size did not match the total size of the packets + */ + +/* + * 1553BRM/AS250 errors + */ + +#define ERR_BRM_OFF 300 +#define ERR_BRM(x) (x+ERR_BASE+ERR_BRM_OFF) + +#define E_BRM_MEM_ADDR_ALIGN ERR_BRM(1) +#define E_BRM_INVALID_COREFREQ ERR_BRM(2) +#define E_BRM_INVALID_PKT_SIZE ERR_BRM(3) +#define E_BRM_INVALID_PKT_ID ERR_BRM(4) +#define E_BRM_IRQ_RT_ILLCMD ERR_BRM(5) +#define E_BRM_IRQ_ILLOP ERR_BRM(6) +#define E_BRM_IRQ_MERR ERR_BRM(7) +#define E_BRM_IRQ_DMAF ERR_BRM(8) +#define E_BRM_IRQ_WRAPF ERR_BRM(9) +#define E_BRM_IRQ_TAPF ERR_BRM(10) +#define E_BRM_IRQ_BITF ERR_BRM(11) +#define E_BRM_IRQ_IXEQ0 ERR_BRM(12) +#define E_BRM_CW_BAC_FLAG ERR_BRM(13) +#define E_BRM_INVALID_TRANSFER_SIZE ERR_BRM(14) + + +/** + * @def E_IRQ_QUEUE_BUSY + * a deferred interrupt could not be queued + * + * @def E_IRQ_EXCEEDS_IRL_SIZE + * the requested IRQ number exceeds the nominal number of interrupt lines + * + * @def E_IRQ_POOL_EMPTY + * all available ISR callback slots are used + * + * @def E_IRQ_DEREGISTER + * the removal of the specified ISR callback was unsuccessful + */ + +/* + * irq dispatch errors + */ + +#define ERR_IRQ_OFF 400 +#define ERR_IRQ(x) (x+ERR_BASE+ERR_IRQ_OFF) + +#define E_IRQ_QUEUE_BUSY ERR_IRQ(1) +#define E_IRQ_EXCEEDS_IRL_SIZE ERR_IRQ(2) +#define E_IRQ_POOL_EMPTY ERR_IRQ(3) +#define E_IRQ_DEREGISTER ERR_IRQ(4) + + + +/** + * @def E_SPW_NO_RX_DESC_AVAIL + * there are no free RX descriptors available + * + * @def E_SPW_NO_TX_DESC_AVAIL + * there are no free TX descriptors available + * + * @def E_SPW_CLOCKS_INVALID + * the specified clock dividers are invalid + * + * @def E_SPW_INVALID_ADDR_ERROR + * an invalid address error occured + * + * @def E_SPW_PARITY_ERROR + * a parity error occured + * + * @def E_SPW_DISCONNECT_ERROR + * a disconnect error occured + * + * @def E_SPW_ESCAPE_ERROR + * an escape error occured + * + * @def E_SPW_CREDIT_ERROR + * a creadit error occured + * + * @def E_SPW_RX_AHB_ERROR + * a RX DMA error occured + * + * @def E_SPW_TX_AHB_ERROR + * a TX DMA error occured + * + * @def E_SPW_RX_DESC_TABLE_ALIGN + * the supplied RX descriptor table is incorrectly aligned + * + * @def E_SPW_TX_DESC_TABLE_ALIGN + * the supplied TX descriptor table is incorrectly aligned + */ + +/* + * grspw2 errors + */ + +#define ERR_SPW_OFF 500 +#define ERR_SPW(x) (x+ERR_BASE+ERR_SPW_OFF) + +#define E_SPW_NO_RX_DESC_AVAIL ERR_SPW(1) +#define E_SPW_NO_TX_DESC_AVAIL ERR_SPW(2) +/* error 3 removed */ +/* error 4 removed */ +#define E_SPW_CLOCKS_INVALID ERR_SPW(5) +#define E_SPW_INVALID_ADDR_ERROR ERR_SPW(6) +#define E_SPW_PARITY_ERROR ERR_SPW(7) +#define E_SPW_DISCONNECT_ERROR ERR_SPW(8) +#define E_SPW_ESCAPE_ERROR ERR_SPW(9) +#define E_SPW_CREDIT_ERROR ERR_SPW(10) +#define E_SPW_RX_AHB_ERROR ERR_SPW(11) +#define E_SPW_TX_AHB_ERROR ERR_SPW(12) +#define E_SPW_RX_DESC_TABLE_ALIGN ERR_SPW(13) +#define E_SPW_TX_DESC_TABLE_ALIGN ERR_SPW(14) + + +/* + * timing errors + */ + +/* timing errors removed */ + + +/** + * @def ERR_FLASH_BLOCKS_EXCEEDED + * the specified flash block exceeds the number of blocks per chip + * + * @def ERR_FLASH_PAGES_EXCEEDED + * the specified page exceeds the number of pages per block + * + * @def ERR_FLASH_PAGESIZE_EXCEEDED + * the specified page offset exceeds the size of a page + * + * @def ERR_FLASH_DISABLED + * the flash is diabled + * + * @def ERR_FLASH_READ_PAGE_EXCEEDED + * the specified read offset would have exceed the flash page size + * + * @def ERR_FLASH_BLOCK_INVALID + * a flash block was invalid + * + * @def ERR_FLASH_ADDR_EMPTY + * a read failed because the flash was marked empty at the given address + * + * @def ERR_FLASH_DATA_WRITE_ERROR + * a write to the data flash failed + * + * @def ERR_FLASH_EDAC_WRITE_ERROR + * a write to the eadc flash failed + * + * @def ERR_FLASH_DATA_ERASE_ERROR + * a data flash erase failed + * + * @def ERR_FLASH_EDAC_ERASE_ERROR + * an edac flash erase failed + * + * @def ERR_FLASH_WRITE_PAGE_EXCEEDED + * the current write would have exceeded the flash page size + * + * @def ERR_FLASH_EDAC_READ_ERROR + * the flash edac status could not be read + */ + +/* + * flash errors + */ + +#define ERR_FLASH_OFF 700 + +#define ERR_FLASH(x) (x+ERR_BASE+ERR_FLASH_OFF) + +#define ERR_FLASH_BLOCKS_EXCEEDED ERR_FLASH(1) +#define ERR_FLASH_PAGES_EXCEEDED ERR_FLASH(2) +#define ERR_FLASH_PAGESIZE_EXCEEDED ERR_FLASH(3) +#define ERR_FLASH_DISABLED ERR_FLASH(4) +#define ERR_FLASH_READ_PAGE_EXCEEDED ERR_FLASH(5) +#define ERR_FLASH_BLOCK_INVALID ERR_FLASH(6) +#define ERR_FLASH_ADDR_EMPTY ERR_FLASH(7) +#define ERR_FLASH_DATA_WRITE_ERROR ERR_FLASH(8) +#define ERR_FLASH_EDAC_WRITE_ERROR ERR_FLASH(9) +#define ERR_FLASH_DATA_ERASE_ERROR ERR_FLASH(10) +#define ERR_FLASH_EDAC_ERASE_ERROR ERR_FLASH(11) +#define ERR_FLASH_WRITE_PAGE_EXCEEDED ERR_FLASH(12) +#define ERR_FLASH_EDAC_READ_ERROR ERR_FLASH(13) + + +/** + * @def ERR_DSU_CWP_INVALID + * the requested CPU window exceeds the valid range + */ + +/* + * DSU errors + */ + +#define ERR_DSU_OFF 800 + +#define ERR_DSU(x) (x+ERR_BASE+ERR_DSU_OFF) + +#define ERR_DSU_CWP_INVALID ERR_DSU(1) + + + + +#endif diff --git a/IBSW/include/event_report.h b/IBSW/include/event_report.h new file mode 100644 index 0000000000000000000000000000000000000000..4ca5c98a0ea211dbf81878d9ccc939731f2e9435 --- /dev/null +++ b/IBSW/include/event_report.h @@ -0,0 +1,65 @@ +/** + * @file event_report.h + * @ingroup event_report + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at), + * Armin Luntzer (roland.ottensamer@univie.ac.at) + * @date August, 2015 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + + +#ifndef EVENT_REPORT__H +#define EVENT_REPORT__H + + +#include <stdint.h> + +#if (__sparc__) && !NO_IASW +#include <CrIaIasw.h> +#include <Services/General/CrIaConstants.h> +#else + +#define CRIA_SERV5_EVT_NORM 1 +#define CRIA_SERV5_EVT_ERR_LOW_SEV 2 +#define CRIA_SERV5_EVT_ERR_MED_SEV 3 +#define CRIA_SERV5_EVT_ERR_HIGH_SEV 4 +#define CRIA_SERV5_EVT_INIT_SUCC 301 +#define CRIA_SERV5_EVT_INIT_FAIL 302 +#define CRIA_SERV5_EVT_NOTIF_ERR 304 +#define CRIA_SERV5_EVT_SPW_ERR 300 +#define CRIA_SERV5_EVT_SPW_ERR_L 315 +#define CRIA_SERV5_EVT_SPW_ERR_M 316 +#define CRIA_SERV5_EVT_SPW_ERR_H 317 +#define CRIA_SERV5_EVT_1553_ERR 310 +#define CRIA_SERV5_EVT_1553_ERR_L 311 +#define CRIA_SERV5_EVT_1553_ERR_M 312 +#define CRIA_SERV5_EVT_1553_ERR_H 313 +#define CRIA_SERV5_EVT_FL_FBF_ERR 325 +#define CRIA_SERV5_EVT_SBIT_ERR 330 +#define CRIA_SERV5_EVT_DBIT_ERR 335 +#define CRIA_SERV5_EVT_FL_EL_ERR 320 +#define CRIA_SERV5_EVT_SYNC_LOSS 350 + +void CrIaEvtRaise(uint8_t subtype, uint16_t id, uint16_t *data, uint32_t size); + +#endif + + +enum error_class {INIT, NOTIFY, FBF, EDAC, CORE1553BRM, GRSPW2, ERRLOG, SYNC}; +enum error_severity {NORMAL, LOW, MEDIUM, HIGH}; + +void event_report(enum error_class c, enum error_severity s, uint32_t err); + +#endif + diff --git a/IBSW/include/exchange_area.h b/IBSW/include/exchange_area.h new file mode 100644 index 0000000000000000000000000000000000000000..2ab0f3a9be76a00b9e52e2529fe90a8801f846e9 --- /dev/null +++ b/IBSW/include/exchange_area.h @@ -0,0 +1,79 @@ +/** + * @file exchange_area.h + * @ingroup irq_dispatch + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2016 + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief description of the exchange area used by the DBS + * + * See CHEOPS-IWF-INST-ICD-009: DPU-SICD-IF-7400 and DPU-SICD-IF-3520 for + * details. + * + */ + + +#ifndef EXCHANGE_AREA_H +#define EXCHANGE_AREA_H + +#include <error_log.h> + +#define EXCHANGE_AREA_BASE_ADDR 0x40040000 +#define STACKTRACE_MAX_ENTRIES 7 + + + +/* CHEOPS-IWF-INST-ICD-009: DPU-SICD-IF-7400 */ + +#define RESET_UNKNOWN_CAUSE 0x0000 +#define RESET_POWER_ON 0x0001 +#define RESET_WATCHDOG 0x0002 +#define RESET_EXCEPTION 0x0003 +#define RESET_TC_RESET 0x0004 +#define RESET_CPU_ERROR 0x0005 +#define RESET_RESET_MILBUS 0x0006 + + + +struct cpu_reginfo { + uint32_t psr; + uint32_t wim; + uint32_t pc; + uint32_t npc; + uint32_t fsr; +}; + + +/* CHEOPS-IWF-INST-ICD-009: DPU-SICD-IF-3520 */ + +struct exchange_area { + + uint8_t reset_type; + uint8_t hk_dbs_status_byte1; + uint8_t hk_dbs_status_byte2; + uint8_t hk_dbs_status_byte3; + struct event_time reset_time; + uint8_t trapnum_core0; /* if reset_type == EXCEPTION_RESET */ + uint8_t trapnum_core1; /* " */ + + struct cpu_reginfo regs_cpu0; /* 0 if reset_type == RESET_REQUIRED */ + struct cpu_reginfo regs_cpu1; /* " */ + uint32_t ahb_status_reg; /* " */ + uint32_t ahb_failing_addr_reg; /* " */ + + uint32_t stacktrace_cpu0[STACKTRACE_MAX_ENTRIES]; /* 0 if unused */ + uint32_t stacktrace_cpu1[STACKTRACE_MAX_ENTRIES]; /* " */ +}; + + +#endif diff --git a/IBSW/include/grspw2.h b/IBSW/include/grspw2.h new file mode 100644 index 0000000000000000000000000000000000000000..aa189d5fc7ccd08915d585ed510b4927c461b86a --- /dev/null +++ b/IBSW/include/grspw2.h @@ -0,0 +1,567 @@ +/** + * @file grspw2.h + * @ingroup grspw2 + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef GRSPW2_H +#define GRSPW2_H + + +#include <stdint.h> +#include <list.h> +#include <compiler.h> +#include <sysctl.h> + +/** + * core addresses and IRQs in the GR712 + * (does not actually belong here...) + */ + +#define GRSPW2_BASE_CORE_0 0x80100800 +#define GRSPW2_BASE_CORE_1 0x80100900 +#define GRSPW2_BASE_CORE_2 0x80100A00 +#define GRSPW2_BASE_CORE_3 0x80100B00 +#define GRSPW2_BASE_CORE_4 0x80100C00 +#define GRSPW2_BASE_CORE_5 0x80100D00 + +#define GRSPW2_IRQ_CORE0 22 +#define GRSPW2_IRQ_CORE1 23 +#define GRSPW2_IRQ_CORE2 24 +#define GRSPW2_IRQ_CORE3 25 +#define GRSPW2_IRQ_CORE4 26 +#define GRSPW2_IRQ_CORE5 27 + + +/* default setting for maximum transfer unit (4 hdr bytes + 1 kiB payload) */ +#define GRSPW2_DEFAULT_MTU 0x0000404 + +/* maximum transfer unit hardware limitation (yes, it's a tautology) */ +#define GRSPW2_MAX_MTU 0x1FFFFFC + + + +/** + * GRSPW2 control register bit masks + * see GR712RC-UM, p. 126 + */ + + +#define GRSPW2_CTRL_LD 0x00000001 /* Link Disable */ +#define GRSPW2_CTRL_LS 0x00000002 /* Link Start */ +#define GRSPW2_CTRL_AS 0x00000004 /* Autostart */ +#define GRSPW2_CTRL_IE 0x00000008 /* Interrupt Enable */ +#define GRSPW2_CTRL_TI 0x00000010 /* Tick In */ +#define GRSPW2_CTRL_PM 0x00000020 /* Promiscuous Mode */ +#define GRSPW2_CTRL_RS 0x00000040 /* Reset */ +#define GRSPW2_CTRL_DUMMY1 0x00000080 /* bit 7 == unused */ +#define GRSPW2_CTRL_TQ 0x00000100 /* Tick-out IRQ */ +#define GRSPW2_CTRL_LI 0x00000200 /* Link error IRQ */ +#define GRSPW2_CTRL_TT 0x00000400 /* Time Tx Enable */ +#define GRSPW2_CTRL_TR 0x00000800 /* Time Rx Enable */ +#define GRSPW2_CTRL_DUMMY2 0x00001000 /* bit 12 == unused */ +#define GRSPW2_CTRL_DUMMY3 0x00002000 /* bit 13 == unused */ +#define GRSPW2_CTRL_DUMMY4 0x00004000 /* bit 14 == unused */ +#define GRSPW2_CTRL_DUMMY5 0x00008000 /* bit 15 == unused */ +#define GRSPW2_CTRL_RE 0x00010000 /* RMAP Enable */ +#define GRSPW2_CTRL_RD 0x00020000 /* RMAP buffer disable */ +#define GRSPW2_CTRL_DUMMY6 0x00040000 /* bit 18 == unused */ +#define GRSPW2_CTRL_DUMMY7 0x00080000 /* bit 19 == unused */ +#define GRSPW2_CTRL_NP 0x00100000 /* No port force */ +#define GRSPW2_CTRL_PS 0x00200000 /* Port select */ +#define GRSPW2_CTRL_DUMMY8 0x00400000 /* bit 22 == unused */ +#define GRSPW2_CTRL_DUMMY9 0x00800000 /* bit 23 == unused */ +#define GRSPW2_CTRL_DUMMY10 0x01000000 /* bit 24 == unused */ +#define GRSPW2_CTRL_DUMMY11 0x02000000 /* bit 25 == unused */ +#define GRSPW2_CTRL_PO 0x04000000 /* Number of ports - 1 */ +#define GRSPW2_CTRL_NCH 0x18000000 /* Number of DMA channels - 1 */ +#define GRSPW2_CTRL_RC 0x20000000 /* RMAP CRC available */ +#define GRSPW2_CTRL_RX 0x40000000 /* RX unaligned access */ +#define GRSPW2_CTRL_RA 0x80000000 /* RMAP available */ + +#define GRSPW2_CTRL_RX_BIT 30 +#define GRSPW2_CTRL_RX_BIT_MASK 0x1 + +#define GRSPW2_CTRL_NCH_BIT 27 +#define GRSPW2_CTRL_NCH_BIT_MASK 0x3 + +#define GRSPW2_CTRL_PO_BIT 26 +#define GRSPW2_CTRL_PO_BIT_MASK 0x1 + + +#define GRSPW2_CTRL_GET_RX(x) \ + (((x >> GRSPW2_CTRL_RX_BIT) & GRSPW2_CTRL_RX_BIT_MASK)) + +#define GRSPW2_CTRL_GET_NCH(x) \ + (((x >> GRSPW2_CTRL_NCH_BIT) & GRSPW2_CTRL_NCH_BIT_MASK) + 1) + +#define GRSPW2_CTRL_GET_PO(x) \ + (((x >> GRSPW2_CTRL_PO_BIT) & GRSPW2_CTRL_PO_BIT_MASK) + 1) + + +/** + * GRSPW2 control register bit masks + * see GR712RC-UM, p. 127 + */ + + +#define GRSPW2_STATUS_TO 0x00000001 /* Tick Out */ +#define GRSPW2_STATUS_CE 0x00000002 /* Credit Error */ +#define GRSPW2_STATUS_ER 0x00000004 /* Escape Error */ +#define GRSPW2_STATUS_DE 0x00000008 /* Disconnect Error */ +#define GRSPW2_STATUS_PE 0x00000010 /* Parity Error */ +#define GRSPW2_STATUS_DUMMY1 0x00000020 /* bit 5 == unused */ +#define GRSPW2_STATUS_DUMMY2 0x00000040 /* bit 6 == unused */ +#define GRSPW2_STATUS_IA 0x00000080 /* Invalid Address */ +#define GRSPW2_STATUS_EE 0x00000100 /* Early EOP/EEP */ +#define GRSPW2_STATUS_AP 0x00000200 /* Active port */ +/* bits 10-20 = unused */ +#define GRSPW2_STATUS_LS 0x00E00000 + /* bits 24-31 == unused */ + +#define GRSPW2_STATUS_CLEAR_MASK 0x19F /* TO|CE|ER|DE|PE|IA|EE */ +#define GRSPW2_STATUS_LS_BIT 21 +#define GRSPW2_STATUS_LS_MASK 0x7 + +#define GRSPW2_STATUS_GET_LS(x) \ + ((x >> GRSPW2_STATUS_LS_BIT) & GRSPW2_STATUS_LS_MASK) + +#define GRSPW2_STATUS_LS_ERROR_RESET 0x0 +#define GRSPW2_STATUS_LS_ERROR_WAIT 0x1 +#define GRSPW2_STATUS_LS_READY 0x2 +#define GRSPW2_STATUS_LS_STARTED 0x3 +#define GRSPW2_STATUS_LS_CONNECTING 0x4 +#define GRSPW2_STATUS_LS_RUN 0x5 + + + +/** + * GRSPW2 default address register bit masks + * see GR712RC-UM, p. 127 + */ + +#define GRSPW2_DEFAULT_ADDR_DEFADDR_BITS 0x00FF +#define GRSPW2_DEFAULT_ADDR_DEFADDR_RESETVAL 254 + +#define GRSPW2_DEFAULT_ADDR_DEFMASK_BITS 0x00FF +#define GRSPW2_DEFAULT_ADDR_DEFMASK 0xFF00 + + +/** + * GRSPW2 clock divisior register bit masks + * see GR712RC-UM, p. 127 + */ + +#define GRSPW2_CLOCKDIV_RUN_MASK 0x00FF +#define GRSPW2_CLOCKDIV_START_MASK 0xFF00 +#define GRSPW2_CLOCKDIV_START_BIT 8 + + +/** + * GRSPW2 destination key register + * see GR712RC-UM, p. 128 + */ + +#define GRSPW2_DESTKEY_MASK 0x00FF + + +/** + * GRSPW2 time register + * see GR712RC-UM, p. 128 + */ + +#define GRSPW2_TIME_TCTRL_BIT 6 +#define GRSPW2_TIME_TCTRL 0x00C0 +#define GRSPW2_TIME_TIMECNT 0x003F + + +/** + * GRSPW2 DMA control register + * see GR712RC-UM, p. 128-129 + */ + +#define GRSPW2_DMACONTROL_TE 0x00000001 /* Transmitter enable */ +#define GRSPW2_DMACONTROL_RE 0x00000002 /* Receiver enable */ +#define GRSPW2_DMACONTROL_TI 0x00000004 /* Transmit interrupt */ +#define GRSPW2_DMACONTROL_RI 0x00000008 /* Receive interrupt */ +#define GRSPW2_DMACONTROL_AI 0x00000010 /* AHB error interrup */ +#define GRSPW2_DMACONTROL_PS 0x00000020 /* Packet sent */ +#define GRSPW2_DMACONTROL_PR 0x00000040 /* Packet received */ +#define GRSPW2_DMACONTROL_TA 0x00000080 /* TX AHB error */ +#define GRSPW2_DMACONTROL_RA 0x00000100 /* RX AHB error */ +#define GRSPW2_DMACONTROL_AT 0x00000200 /* Abort TX */ +#define GRSPW2_DMACONTROL_RX 0x00000400 /* RX active */ +#define GRSPW2_DMACONTROL_RD 0x00000800 /* RX descriptors available */ +#define GRSPW2_DMACONTROL_NS 0x00001000 /* No spill */ +#define GRSPW2_DMACONTROL_EN 0x00002000 /* Enable addr */ +#define GRSPW2_DMACONTROL_SA 0x00004000 /* Strip addr */ +#define GRSPW2_DMACONTROL_SP 0x00008000 /* Strip pid */ +#define GRSPW2_DMACONTROL_LE 0x00010000 /* Link error disable */ + /* bits 17-31 == unused */ + +/** + * GRSPW2 RX maximum length register + * see GR712RC-UM, p. 129 + */ + +#define GRSPW2_RX_MAX_LEN_MASK 0xFFFFFF + + +/** + * GRSPW2 transmitter descriptor table address register + * see GR712RC-UM, p. 129 + */ + +#define GRSWP2_TX_DESCRIPTOR_TABLE_DESCBASEADDR_BIT 10 +#define GRSWP2_TX_DESCRIPTOR_TABLE_DESCBASEADDR_REG_MASK 0xFFFFFC00 +#define GRSWP2_TX_DESCRIPTOR_TABLE_DESCBASEADDR_BIT_MASK 0xFFFFFC + +#define GRSWP2_TX_DESCRIPTOR_TABLE_DESCSEL_BIT 4 +#define GRSPW2_TX_DESCRIPTOR_TABLE_DESCSEL_REG_MASK 0x3F0 +#define GRSPW2_TX_DESCRIPTOR_TABLE_DESCSEL_BIT_MASK 0x3F + +#define GRSPW2_TX_DESCRIPTOR_TABLE_GET_DESCSEL(x) \ + (((x) >> GRSWP2_TX_DESCRIPTOR_TABLE_DESCSEL_BIT)\ + & GRSPW2_TX_DESCRIPTOR_TABLE_DESCSEL_BIT_MASK) + + +/** + * GRSPW2 receiver descriptor table address register + * see GR712RC-UM, p. 129 + */ + +#define GRSWP2_RX_DESCRIPTOR_TABLE_DESCBASEADDR_BIT 10 +#define GRSWP2_RX_DESCRIPTOR_TABLE_DESCBASEADDR_REG_MASK 0xFFFFFC00 +#define GRSWP2_RX_DESCRIPTOR_TABLE_DESCBASEADDR_BIT_MASK 0xFFFFFC + +#define GRSWP2_RX_DESCRIPTOR_TABLE_DESCSEL_BIT 4 +#define GRSPW2_RX_DESCRIPTOR_TABLE_DESCSEL_REG_MASK 0x3F0 +#define GRSPW2_RX_DESCRIPTOR_TABLE_DESCSEL_BIT_MASK 0x3F + +#define GRSPW2_RX_DESCRIPTOR_TABLE_GET_DESCSEL(x) \ + (((x) >> GRSWP2_RX_DESCRIPTOR_TABLE_DESCSEL_BIT)\ + & GRSPW2_RX_DESCRIPTOR_TABLE_DESCSEL_BIT_MASK) + + +/** + * GRSPW2 dma channel address register + * see GR712RC-UM, p. 129 + */ + +#define GRSPW2_DMA_CHANNEL_MASK_BIT 8 +#define GRSPW2_DMA_CHANNEL_MASK_BIT_MASK 0x00FF +#define GRSPW2_DMA_CHANNEL_MASK_REG_MASK 0xFF00 + +#define GRSPW2_DMA_CHANNEL_ADDR_REG_MASK 0x00FF + + + + + +/* Maximum number of TX Descriptors */ +#define GRSPW2_TX_DESCRIPTORS 64 + +/* Maximum number of RX Descriptors */ +#define GRSPW2_RX_DESCRIPTORS 128 + +#define GRSPW2_RX_DESC_SIZE 8 +#define GRSPW2_TX_DESC_SIZE 16 + +/* BD Table Size (RX or TX) */ +#define GRSPW2_DESCRIPTOR_TABLE_SIZE 0x400 + +/* alignment of a descriptor table (1024 bytes) */ +#define GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN 0x3FF + +/** + * GRSPW2 RX descriptor control bits + * see GR712RC-UM, p. 112 + */ + +#define GRSPW2_RX_DESC_PKTLEN_MASK 0x01FFFFFF +/* descriptor is enabled */ +#define GRSPW2_RX_DESC_EN 0x02000000 +/* wrap back to start of table */ +#define GRSPW2_RX_DESC_WR 0x04000000 +/* packet interrupt enable */ +#define GRSPW2_RX_DESC_IE 0x08000000 +/* packet ended with error EOP */ +#define GRSPW2_RX_DESC_EP 0x10000000 +/* header CRC error detected */ +#define GRSPW2_RX_DESC_HC 0x20000000 +/* data CRC error detected */ +#define GRSPW2_RX_DESC_DC 0x40000000 +/* Packet was truncated */ +#define GRSPW2_RX_DESC_TR 0x80000000 + + +/** + * GRSPW2 TX descriptor control bits + * see GR712RC-UM, p. 115 + * NOTE: incomplete + */ + + +/* descriptor is enabled */ +#define GRSPW2_TX_DESC_EN 0x00001000 +/* wrap back to start of table */ +#define GRSPW2_TX_DESC_WR 0x00002000 +/* packet interrupt enabled */ +#define GRSPW2_TX_DESC_IE 0x00004000 + + + +/** + * GRSPW2 register map, repeating DMA Channels 1-4 are in separate struct + * see GR712RC-UM, p. 125 + */ + +struct grspw2_dma_regs { + uint32_t ctrl_status; + uint32_t rx_max_pkt_len; + uint32_t tx_desc_table_addr; + uint32_t rx_desc_table_addr; + uint32_t addr; + uint32_t dummy[3]; +}; + +struct grspw2_regs { + uint32_t ctrl; /* 0x00 */ + uint32_t status; /* 0x04 */ + uint32_t nodeaddr; /* 0x08 */ + uint32_t clkdiv; /* 0x0C */ + uint32_t destkey; /* 0x10 */ + uint32_t time; /* 0x14 */ + uint32_t dummy[2]; /* 0x18 - 0x1C */ + + struct grspw2_dma_regs dma[4]; /* 0x20 - 0x9C */ +}; + + +/** + * GRSPW2 RX descriptor word layout, see GR712-UM, p. 112 + */ + +__extension__ +struct grspw2_rx_desc { + union { + struct { + uint32_t truncated : 1; + uint32_t crc_error_data : 1; + uint32_t crc_error_header: 1; + uint32_t EEP_termination : 1; + uint32_t interrupt_enable: 1; + uint32_t wrap : 1; + uint32_t enable : 1; + uint32_t pkt_size :25; + }; + uint32_t pkt_ctrl; + }; + + uint32_t pkt_addr; +}; + + + +/** + * check whether the descriptor structure was actually aligned to be the same + * size as a rx descriptor block as used by the grspw2 core + */ +compile_time_assert((sizeof(struct grspw2_rx_desc) == GRSPW2_RX_DESC_SIZE), + RXDESC_STRUCT_WRONG_SIZE); + +/** + * GRSPW2 TX descriptor word layout, see GR712-UM, pp. 115 + */ +__extension__ +struct grspw2_tx_desc { + union { + struct { + uint32_t reserved1 :14; + uint32_t append_data_crc : 1; + uint32_t append_header_crc: 1; + uint32_t link_error : 1; + uint32_t interrupt_enable : 1; + uint32_t wrap : 1; + uint32_t enable : 1; + uint32_t non_crc_bytes : 4; + uint32_t hdr_size : 8; + }; + uint32_t pkt_ctrl; + }; + + uint32_t hdr_addr; + + union { + struct { + uint32_t reserved2 : 8; + uint32_t data_size :24; + }; + uint32_t data_size_reg; + }; + + uint32_t data_addr; +}; + +/** + * check whether the descriptor structure was actually aligned to be the same + * size as a tx descriptor block as used by the grspw2 core + */ +compile_time_assert((sizeof(struct grspw2_tx_desc) == GRSPW2_TX_DESC_SIZE), + TXDESC_STRUCT_WRONG_SIZE); + + +/** + * the descriptor ring elements are tracked in a doubly linked list + */ + + +struct grspw2_rx_desc_ring_elem { + struct grspw2_rx_desc *desc; + struct list_head node; +}; + + +struct grspw2_tx_desc_ring_elem { + struct grspw2_tx_desc *desc; + struct list_head node; +}; + + + +/** + * grspw2 core configuration structure + * since we are not able to malloc(), it's easiest to create our lists on + * the stack + */ + +struct grspw2_core_cfg { + + /** NOTE: actual memory buffers we use could be referenced here */ + + /* points to the register map of a grspw2 core */ + struct grspw2_regs *regs; + + /* the core's interrupt */ + uint32_t core_irq; + + /* the ahb interrupt */ + uint32_t ahb_irq; + + uint32_t strip_hdr_bytes; /* bytes to strip from the RX packets */ + + uint32_t rx_bytes; + uint32_t tx_bytes; + + struct sysobj sobj; + + /* routing node, we currently support only one device and only + * blind routing (i.e. address bytes are ignored */ + struct grspw2_core_cfg *route[1]; + + /** + * the rx and tx descriptor pointers in these arrays must point to the + * descriptors in the same order as they are used by the grspw2 core so + * they may be sequentially accessed at any time + */ + struct grspw2_rx_desc_ring_elem rx_desc_ring[GRSPW2_RX_DESCRIPTORS]; + struct grspw2_tx_desc_ring_elem tx_desc_ring[GRSPW2_TX_DESCRIPTORS]; + + /** + * we use two list heads for each descriptor type to manage active and + * inactive descriptors + * spin-lock protection is fine as long as the lists are only modified + * outside of an ISR or if the ISR may schedule itself to be + * re-executed at a later time when the lock has been released + */ + struct list_head rx_desc_ring_used; + struct list_head rx_desc_ring_free; + + struct list_head tx_desc_ring_used; + struct list_head tx_desc_ring_free; + + struct { + uint32_t *rx_desc_tbl; + uint32_t *tx_desc_tbl; + uint8_t *rx_descs; + uint8_t *tx_descs; + uint8_t *tx_hdr; + uint32_t tx_hdr_size; + } alloc; + +}; + + + +void grspw2_set_promiscuous(struct grspw2_core_cfg *cfg); +void grspw2_unset_promiscuous(struct grspw2_core_cfg *cfg); + +int32_t grspw2_tx_desc_table_init(struct grspw2_core_cfg *cfg, + uint32_t *mem, uint32_t tbl_size, + uint8_t *hdr_buf, uint32_t hdr_size, + uint8_t *data_buf, uint32_t data_size); + +int32_t grspw2_rx_desc_table_init(struct grspw2_core_cfg *cfg, + uint32_t *mem, uint32_t tbl_size, + uint8_t *pkt_buf, uint32_t pkt_size); + + +uint32_t grspw2_get_num_pkts_avail(struct grspw2_core_cfg *cfg); +uint32_t grspw2_get_num_free_tx_desc_avail(struct grspw2_core_cfg *cfg); + +uint32_t grspw2_get_pkt(struct grspw2_core_cfg *cfg, uint8_t *pkt); +uint32_t grspw2_drop_pkt(struct grspw2_core_cfg *cfg); +uint32_t grspw2_get_next_pkt_size(struct grspw2_core_cfg *cfg); + +void grspw2_tick_in(struct grspw2_core_cfg *cfg); +uint32_t grspw2_get_timecnt(struct grspw2_core_cfg *cfg); +uint32_t grspw2_get_link_status(struct grspw2_core_cfg *cfg); + +void grspw2_tick_out_interrupt_enable(struct grspw2_core_cfg *cfg); +void grspw2_set_time_rx(struct grspw2_core_cfg *cfg); + +int32_t grspw2_add_pkt(struct grspw2_core_cfg *cfg, + const void *hdr, uint32_t hdr_size, + const void *data, uint32_t data_size); + + +void grspw2_core_start(struct grspw2_core_cfg *cfg); + + +int32_t grspw2_core_init(struct grspw2_core_cfg *cfg, uint32_t core_addr, + uint8_t node_addr, uint8_t link_start, + uint8_t link_run, uint32_t mtu, + uint32_t core_irq, uint32_t ahb_irq, + uint32_t strip_hdr_bytes); + + +int32_t grspw2_enable_routing(struct grspw2_core_cfg *cfg, + struct grspw2_core_cfg *route); + +int32_t grspw2_enable_routing_noirq(struct grspw2_core_cfg *cfg, + struct grspw2_core_cfg *route); +int32_t grspw2_route(void *userdata); + +int32_t grspw2_disable_routing(struct grspw2_core_cfg *cfg); + +void set_gr712_spw_clock(void); + + +void grspw2_set_link_error_irq(struct grspw2_core_cfg *cfg); +void grspw2_unset_link_error_irq(struct grspw2_core_cfg *cfg); +void grspw2_spw_hardreset(struct grspw2_regs *regs); + + +#endif diff --git a/IBSW/include/ibsw.h b/IBSW/include/ibsw.h new file mode 100644 index 0000000000000000000000000000000000000000..4589540e82b358a5b9a1ec0094962899b8f75969 --- /dev/null +++ b/IBSW/include/ibsw.h @@ -0,0 +1,73 @@ +/** + * @file ibsw.h + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef IBSW_H +#define IBSW_H + +#include <stdint.h> +#include <sys/types.h> + +#include <timing.h> +#include <cpus_buffers.h> +#include <packet_tracker.h> +#include <grspw2.h> +#include <error_log.h> + + +struct ibsw_config; + + + +ssize_t ibsw_configure_cpus(struct cpus_buffers *pus_buf); + +ssize_t ibsw_configure_ptrack(struct packet_tracker *pkt, uint32_t pkts); + +ssize_t ibsw_configure_spw(struct grspw2_core_cfg *spw, uint32_t spw_core_addr, + uint32_t spw_core_irq, uint32_t spw_addr, + uint32_t tx_hdr_size, uint32_t spw_strip_hdr_bytes, + uint32_t gate); + +ssize_t ibsw_configure_1553(struct brm_config *brm, + struct cpus_buffers *pus_buf, + struct packet_tracker *pkt_gnd, + struct packet_tracker *pkt_obc, + struct time_keeper *timer); + +void ibsw_configure_timing(struct time_keeper *timer, + struct brm_config *brm, + struct grspw2_core_cfg *spw); + +void ibsw_configure_1553_sync(struct brm_config __attribute__((unused)) *brm, + struct time_keeper *timer); + +void ibsw_configure_error_log(struct error_log **error_log); + +int32_t ibsw_configure_edac(void); + +int32_t ibsw_update_cpu_0_idle(void *userdata); + +void ibsw_init_cpu_0_idle_timing(struct ibsw_config *cfg); + +void cyclical_notification(void *userdata); + +void ibsw_mainloop(struct ibsw_config *cfg); + + +ssize_t ibsw_init(struct ibsw_config *cfg); + + +#endif diff --git a/IBSW/include/ibsw_interface.h b/IBSW/include/ibsw_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..3ad7819fdb023df7b4ac7ca7506d9ec8189eb461 --- /dev/null +++ b/IBSW/include/ibsw_interface.h @@ -0,0 +1,213 @@ +/** + * @file ibsw_interface.h + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date August, 2015 + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef IBSW_INTERFACE_H +#define IBSW_INTERFACE_H + +#include <circular_buffer8.h> +#include <circular_buffer16.h> +#include <cpus_buffers.h> +#include <packet_tracker.h> +#include <grspw2.h> +#include <timing.h> +#include <core1553brm_as250.h> + +#if (__sparc__) + +#include <CrIaIasw.h> +#include <CrFwConstants.h> +#include <CrFwUserConstants.h> +#include <Pckt/CrFwPckt.h> +#include <FwProfile/FwRtConstants.h> +#include <FwProfile/FwRtConfig.h> +#include <FwProfile/FwRtCore.h> +#include <CrIaDataPoolId.h> +#include <CrIaDataPool.h> + +#else + +/* dummy definitions for testing */ +typedef int CrFwBool_t; +typedef unsigned char CrFwDestSrc_t; +typedef char* CrFwPckt_t; +typedef int FwRtOutcome_t; + +struct FwRtDesc { + int dummy; + int errCode; + int cnt; +}; + +typedef struct FwRtDesc* FwRtDesc_t; +typedef unsigned short int CrFwPcktLength_t; +typedef struct CrFwTimeStamp { + unsigned char t[6]; +} CrFwTimeStamp_t; + +#endif /* __sparc__ */ + + +#define RTCONT_CYC 1 +#define RTCONT_ERRLOG 2 +#define RTCONT_FLASH 3 +#define RTCONT_ACQ 4 +#define RTCONT_CMPR 5 + +#define DEADLINE_CYC 0.125f +#define DEADLINE_ERRLOG 0.020f +#define DEADLINE_FLASH 0.0f +/** + * DEADLINE_FLASH is the deadline for the RT container which executes + * flash read/write operations. It is set to zero because these operations + * are performed as a background task which uses the remaining time in + * an 8 Hz cycle. This logic is implemented in the while-loop in function + * flash_functional_behaviour + */ +#define DEADLINE_ACQ 0.0f +#define DEADLINE_CMPR 0.0f + +#define RUNBEFORE_ERRLOG 0.100f /* Mantis 2159, 2175 */ +#define RUNBEFORE_FLASH 0.100f + + +/* + CrIbIsObcPcktAvail, CrIbIsGrdPcktAvail, CrIbObcPcktCollect + and CrIbGrdPcktCollect are defined int CrIaIasw as wrappers + to CrIbIsMilBusPcktAvail and CrIbMilBusPcktCollect +*/ +CrFwBool_t CrIbIsMilBusPcktAvail(CrFwDestSrc_t src); +CrFwPckt_t CrIbMilBusPcktCollect(CrFwDestSrc_t src); +CrFwBool_t CrIbMilBusPcktHandover(CrFwPckt_t pckt); +uint32_t CrIbMilBusGetLinkCapacity(void); + + +void execute_cyclical(void); +void execute_flash_op(struct grtimer_uptime t0); +void execute_log_move_to_flash(void); + +void run_rt(uint32_t rt_id, float deadline, void (*behaviour) (void)); +void execute_acquisition(void); +void execute_compression(void); + +void rt_reset(void *userdata); +void fdir_reset(void *userdata); +void shutdown(void); +void CrIbEnableWd(void); +void CrIbDisableWd(void); +void CrIbResetWd(void); + +void CrIbSetSyncFlag(uint32_t sync); + +void CrIbFbfOpen(uint32_t fbf); + +void CrIbFbfClose(uint32_t fbf); + +uint32_t CrIbFbfReadBlock(uint32_t fbf, uint32_t fbf_block, uint32_t *buf); + +uint32_t CrIbFbfWriteBlock(uint32_t fbf, uint32_t *buf); + +int32_t CrIbFlashTriggerRead(uint8_t fbf, uint16_t block, uint32_t *mem); + +int32_t CrIbFlashTriggerWrite(uint8_t fbf, uint32_t *mem); + +uint8_t CrIbFlashIsReady(void); + +uint32_t CrIbGetDpuBoardId(void); + +enum sem_op {SWITCH_ON, SWITCH_OFF, HEATER_ON, HEATER_OFF, + GET_STATUS_ON, GET_FAILURE, GET_STATUS_HEATER_ON}; + +uint32_t CrIbSemLowLevelOp(enum sem_op op); + +CrFwBool_t CrIbIsSEMLinkRunning(void); +CrFwBool_t CrIbIsEGSELinkRunning(void); + +CrFwBool_t CrIbIsSemPcktAvail(__attribute__((unused)) CrFwDestSrc_t src); +CrFwPckt_t CrIbSemPcktCollect(__attribute__((unused)) CrFwDestSrc_t src); +CrFwBool_t CrIbSemPcktHandover(CrFwPckt_t pckt); + +void CrIbDisableSemSpWLinkErrorIRQ(void); +void CrIbEnableSemSpWLinkErrorIRQ(void); + +#if (__SPW_ROUTING__) +void CrIbDisableMonSpWLinkErrorIRQ(void); +void CrIbEnableMonSpWLinkErrorIRQ(void); +void CrIbEnableSpWRouting(void); +void CrIbEnableSpWRoutingNOIRQ(void); +void CrIbSpWRoute(void); +void CrIbDisableSpWRouting(void); +#endif + +void CrIbResetSEMSpW(void); + +void CrIbLogError(unsigned short evtId, unsigned char *evtData); +void CrIbDumpRamErrorLog(unsigned char *buf); +uint32_t CrIbDumpFlashErrorLog(unsigned int unit, unsigned int addr, char *buf); +uint32_t get_error_log_entires_made_since_IBSW_IASW_started(void); +int32_t error_log_move_to_flash(void); + +CrFwTimeStamp_t CrIbGetCurrentTime(void); +CrFwTimeStamp_t CrIbGetNextTime(void); +void CrIbDisableSpWTick(void); + +enum scrubmem {SRAM1_ID, SRAM2_ID}; +uint32_t CrIbScrubMemory(enum scrubmem memId, uint32_t scrubLen); +uint32_t CrIbMemRepair(void); +void CrIbResetDPU(unsigned char reset_type); + +uint32_t CrIbGetNotifyCnt(void); + +void CrIbUpdateDataPoolVariablesWithValuesFromIbswSysctlTree(uint32_t hz); + +void CrIbInjectFault(uint32_t mem_value, uint32_t edac_value, void *addr); + + +struct flash_operation { + uint8_t fbf; + uint16_t block; + uint32_t *mem; + uint8_t isReady; + enum {READ, WRITE} op; + uint32_t error; +}; + +extern struct flash_operation flash_operation; + +struct ibsw_config { + uint32_t cpu0_load; + uint32_t cpu1_load; + struct grtimer_uptime cpu_0_idle_exit; + struct grtimer_uptime cpu_1_idle_exit; + struct brm_config brm; + struct grspw2_core_cfg spw0; + struct grspw2_core_cfg spw1; + struct cpus_buffers pus_buf; + struct packet_tracker pkt_gnd; + struct packet_tracker pkt_obc; + struct time_keeper timer; + struct error_log *error_log; + uint32_t isErrLogValid; +}; + +extern struct ibsw_config ibsw_cfg; + +void CrIbUpdateDataPoolVariablesWithValuesFromIbswSysctlTree(uint32_t hz); + +void CrIbUpdateDataPoolVariablesWithFpgaValues(void); + +#endif diff --git a/IBSW/include/io.h b/IBSW/include/io.h new file mode 100644 index 0000000000000000000000000000000000000000..d7f6d168161f4d48d39f9933b620eb0654848f1a --- /dev/null +++ b/IBSW/include/io.h @@ -0,0 +1,141 @@ +/** + * @file io.h + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief a collection of accessor functions and macros to perform unbuffered + * access to memory or hardware registers + */ + +#ifndef _IO_H_ +#define _IO_H_ + +#include <stdint.h> + + +/* + * raw "register" io + * convention/calls same as in linux kernel (see arch/sparc/include/asm/io_32.h) + * @note: SPARSE macros are removed, we probably won't use it for the foreseeable + * future + * @note need only big endian functions for now + */ + + +#if (__sparc__) + +#define ASI_LEON_NOCACHE 0x01 /* force cache miss */ + +static inline uint8_t __raw_readb(const volatile void *addr) +{ + uint8_t ret; + + __asm__ __volatile__("lduba [%1] %2, %0\n\t" + : "=r" (ret) + : "r" (addr), "i" (ASI_LEON_NOCACHE)); + + return ret; +} + +static inline uint16_t __raw_readw(const volatile void *addr) +{ + uint16_t ret; + + __asm__ __volatile__("lduha [%1] %2, %0\n\t" + : "=r" (ret) + : "r" (addr), "i" (ASI_LEON_NOCACHE)); + + return ret; +} + + +static inline uint32_t __raw_readl(const volatile void *addr) +{ + uint32_t ret; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" + : "=r" (ret) + : "r" (addr), "i" (ASI_LEON_NOCACHE)); + + return ret; +} + +static inline void __raw_writeb(uint8_t w, const volatile void *addr) +{ + __asm__ __volatile__("stba %r0, [%1] %2\n\t" + : + : "Jr" (w), "r" (addr), "i" (ASI_LEON_NOCACHE)); +} + +static inline void __raw_writew(uint16_t w, const volatile void *addr) +{ + __asm__ __volatile__("stha %r0, [%1] %2\n\t" + : + : "Jr" (w), "r" (addr), "i" (ASI_LEON_NOCACHE)); +} + + +static inline void __raw_writel(uint32_t l, const volatile void *addr) +{ + __asm__ __volatile__("sta %r0, [%1] %2\n\t" + : + : "Jr" (l), "r" (addr), "i" (ASI_LEON_NOCACHE)); +} + + +#else + +static inline uint8_t __raw_readb(const volatile void *addr) +{ + return *(const volatile uint8_t *)addr; +} + +static inline uint16_t __raw_readw(const volatile void *addr) +{ + return *(const volatile uint16_t *)addr; +} + +static inline uint32_t __raw_readl(const volatile void *addr) +{ + return *(const volatile uint32_t *)addr; +} + +static inline void __raw_writeb(uint8_t w, volatile void *addr) +{ + *(volatile uint8_t *)addr = w; +} + +static inline void __raw_writew(uint16_t w, volatile void *addr) +{ + *(volatile uint16_t *)addr = w; +} + +static inline void __raw_writel(uint32_t l, volatile void *addr) +{ + *(volatile uint32_t *)addr = l; +} + +#endif + + +#define ioread8(X) __raw_read8(X) +#define iowrite8(X) __raw_write8(X) + +#define ioread16be(X) __raw_readw(X) +#define ioread32be(X) __raw_readl(X) + +#define iowrite16be(val,X) __raw_writew(val,X) +#define iowrite32be(val,X) __raw_writel(val,X) + + + +#endif diff --git a/IBSW/include/iwf_flash.h b/IBSW/include/iwf_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..beadc376a00562e6384b559bd4744c202f8756b7 --- /dev/null +++ b/IBSW/include/iwf_flash.h @@ -0,0 +1,128 @@ +/** + * @file iwf_flash.h + * @ingroup iwf_flash + * + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date 2015 + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @see CHEOPS-IWF-INST-IRD-020 + * @see K9F8G08UXM 1G x 8 Bit/ 2G x 8 Bit NAND Flash Memory + * + */ + + +#ifndef IWF_FLASH_H +#define IWF_FLASH_H + +#include <stdint.h> +#include <compiler.h> + + + +#define FLASH_UNITS 4 + +#define FLASH_BLOCKS_PER_CHIP 4096 +#define FLASH_PAGES_PER_BLOCK 64 +#define FLASH_PAGE_SIZE 4096 + + +#define FLASH_LOGICAL_PAGE_OFFSET_SHIFT 2 /* see IWF-INST-IRD-020 */ +#define FLASH_LOGICAL_PAGE_ADDR_SHIFT 14 +#define FLASH_LOGICAL_PAGE_OFFSET_BITS 12 + +/* a real flash page is wider than 4096 bytes... */ +#define FLASH_PAGE_OFFSET_BITS 13 +#define FLASH_PAGE_ADDR_BITS 18 +#define FLASH_PAGE_ADDR_SHIFT FLASH_PAGE_OFFSET_BITS + +#define FLASH_MAX_BYTES_PER_WRITE (FLASH_PAGES_PER_BLOCK * FLASH_PAGE_SIZE) + + +#define FLASH_BAD_BLOCK_BYTE 4096 /* regular 0-4095 (+1) */ +#define FLASH_BAD_BLOCK_PAGES {0, 1} +#define FLASH_BLOCK_VALID 0xffffffff /* 4 parallel flash chips */ +#define FLASH_EDAC_BLOCK_VALID 0xff + + + +#define FLASH_CMD_READ_SEQ_1 0x00000000 +#define FLASH_CMD_READ_SEQ_2 0x30303030 +#define FLASH_CMD_READ_UPDATE_ADDR_1 0x05050505 +#define FLASH_CMD_READ_UPDATE_ADDR_2 0xe0e0e0e0 + +#define FLASH_CMD_RESET 0xffffffff + +#define FLASH_CMD_BLOCK_ERASE_SEQ_1 0x60606060 +#define FLASH_CMD_BLOCK_ERASE_SEQ_2 0xd0d0d0d0 + +#define FLASH_CMD_PAGE_PROGRAM_SEQ_1 0x80808080 +#define FLASH_CMD_PAGE_PROGRAM_SEQ_2 0x10101010 + +#define FLASH_CMD_READ_STATUS 0x70707070 + +#define FLASH_STATUS_FAIL 0x01010101 +#define FLASH_EDAC_STATUS_FAIL 0x1 + +__extension__ +struct iwf_flash_address { + union { + struct { + uint32_t skip :1; + uint32_t byte5 :2; + uint32_t byte4 :8; + uint32_t byte3 :8; + uint32_t byte2 :5; + uint32_t byte1 :8; + }; + uint32_t phys_addr; + }; +}; + +compile_time_assert((sizeof(struct iwf_flash_address) == 4), + IWF_FPGA_FLASH_ADDRESS_WRONG_SIZE); + + +void flash_get_read_addr(uint32_t unit, uint32_t *block, + uint32_t *page, uint32_t *offset); + +void flash_get_write_addr(uint32_t unit, uint32_t *block, + uint32_t *page, uint32_t *offset); + +uint32_t flash_gen_phys_addr(uint32_t block, uint32_t page, uint32_t offset); +uint32_t flash_gen_logical_addr(uint32_t block, uint32_t page, uint32_t offset); + +void flash_reverse_logical_addr(uint32_t addr, uint32_t *block, + uint32_t *page, uint32_t *offset); + +int32_t flash_init_read(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset); + +uint32_t flash_read_word(uint32_t unit, uint32_t offset); +int32_t flash_read(uint32_t unit, uint32_t offset, uint32_t *buf, uint32_t len); +int32_t flash_read_bypass_edac(uint32_t unit, uint32_t offset, + uint32_t *buf, uint32_t len); + +int32_t flash_stop_write(uint32_t unit); + +int32_t flash_init_write(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset); + +int32_t flash_write_word(uint32_t unit, uint32_t word); +int32_t flash_write(uint32_t unit, uint32_t *buf, uint32_t len); + +int32_t flash_erase_block(uint32_t unit, uint32_t block); + + + +#endif /* IWF_FLASH_H */ diff --git a/IBSW/include/iwf_fpga.h b/IBSW/include/iwf_fpga.h new file mode 100644 index 0000000000000000000000000000000000000000..b3bf921e9a477fe0320c4993396f1096188aee0b --- /dev/null +++ b/IBSW/include/iwf_fpga.h @@ -0,0 +1,351 @@ +/** + * @file iwf_fpga.h + * @ingroup iwf_fpga + * + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date 2015 + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief a description of the IWF's FPGA registers as used in their DPU + * + * For details, see IWF-INST-IRD-020 DPU HW-SW Interface Requirements 5.2.4.2 + * + */ + + +#ifndef IWF_FPGA_H +#define IWF_FPGA_H + +#include <stdint.h> +#include <compiler.h> + +/* + * helper macro to fill unused 4-byte slots with "unusedXX" variables + * yes, this needs to be done exactly like that, or __COUNTER__ will not be expanded + */ + +#define CONCAT(x, y) x##y +#define MACRO_CONCAT(x, y) CONCAT(x, y) +#define UNUSED_UINT32_SLOT uint32_t MACRO_CONCAT(unused, __COUNTER__) + + + +/* see IWF-INST-IRD-020 DPU HW SW Interface Requirements 5.2.4.2 (p22 or so) */ + + +#define IWF_FPGA_BASE 0x20000000 +#define IWF_FPGA_DPU_BASE 0x20000004 +#define IWF_FPGA_RESET_BASE 0x20000010 +#define IWF_FPGA_IRQ_BASE 0x20000020 +#define IWF_FPGA_SEM_BASE 0x20000030 +#define IWF_FPGA_HEATER_BASE 0x20000040 +#define IWF_FPGA_ADC_CTRL_BASE 0x20000050 +#define IWF_FPGA_ADC_VAL_BASE 0x20000100 +#define IWF_FPGA_MEM_CTRL_BASE 0x20000200 +#define IWF_FPGA_FLASH_CMD_BASE 0x20001100 +#define IWF_FPGA_FLASH_ADDR_BASE 0x20001200 +#define IWF_FPGA_FLASH_STATUS_BASE 0x20001300 + +#define IWF_FPGA_FLASH_1_DATA_BASE 0x01fffff0 +#define IWF_FPGA_FLASH_2_DATA_BASE 0x01fffff4 +#define IWF_FPGA_FLASH_3_DATA_BASE 0x01fffff8 +#define IWF_FPGA_FLASH_4_DATA_BASE 0x01fffffc + +#define FLASH_CHIPS_PER_DEVICE 4 +#define FLASH_DEVICES 4 + + + +struct iwf_fpga_version { + uint32_t version; +}; + +struct iwf_fpga_dpu { + uint32_t status; + uint32_t addr; +}; + +struct iwf_fpga_reset { + uint32_t ctrl; + uint32_t status; +}; + +struct iwf_fpga_irq { + uint32_t status; +}; + +struct iwf_fpga_sem { + uint32_t ctrl; + uint32_t status; +}; + +struct iwf_fpga_heater { + uint32_t ctrl; + uint32_t status; +}; + +struct iwf_fpga_adc_ctrl { + uint32_t ctrl; + uint32_t status; +}; + +struct iwf_fpga_adc_val { + uint32_t adc_p3v3__adc_p5v; + uint32_t adc_p1v8__adc_p2v5; + uint32_t adc_n5v__adc_pgnd; + uint32_t adc_tempoh1a__adc_temp1; + uint32_t adc_tempoh2a__adc_tempoh1b; + uint32_t adc_tempoh3a__adc_tempoh2b; + uint32_t adc_tempoh4a__adc_tempoh3b; + uint32_t spare_01__adc_tempoh4b; + uint32_t sem_p15v__sem_p30v; + uint32_t sem_p5v0__sem_p7v0; + uint32_t spare_02__sem_n5v0; + uint32_t spare_03__spare_04; + uint32_t spare_05__spare_06; + uint32_t spare_07__spare_08; + uint32_t spare_09__spare_10; + uint32_t spare_11__spare_12; +}; + +__extension__ +struct iwf_fpga_mem_ctrl { + union { + struct { + uint32_t spare0 :23; + uint32_t sram_flash : 1; /* write only */ + uint32_t spare1 : 6; + uint32_t reserved : 1; + uint32_t write_protect : 1; /* write only */ + } mem_ctrl; + + uint32_t ctrl; + }; + + union { + struct { + uint32_t spare0 :23; + uint32_t sram_flash : 1; + uint32_t spare1 : 5; + uint32_t empty : 1; + uint32_t ready_busy : 1; + uint32_t write_protect : 1; + } mem_status; + + uint32_t status; + }; + + UNUSED_UINT32_SLOT; + + union { + struct { + uint32_t spare0 :24; + uint32_t write_protect : 1; + uint32_t ready_busy : 1; + uint32_t spare1 : 5; + uint32_t pass_fail : 1; + } mem_flash_edac; + + uint32_t flash_edac; + }; +}; + +compile_time_assert((sizeof(struct iwf_fpga_mem_ctrl) == 16), + IWF_FPGA_MEM_CTRL_WRONG_SIZE); + +__extension__ +struct iwf_fpga_flash_cmd { + union { + uint8_t cmd_chip[FLASH_CHIPS_PER_DEVICE]; + uint32_t cmd; + }; +}; + +__extension__ +struct iwf_fpga_flash_addr { + union { + uint8_t addr_chip[FLASH_CHIPS_PER_DEVICE]; + uint32_t addr; + }; +}; + +__extension__ +struct iwf_fpga_flash_status { + union { + uint8_t status_chip[FLASH_CHIPS_PER_DEVICE]; + uint32_t stats; + }; +}; + + + +struct iwf_fpga_map { + struct iwf_fpga_version *fpga; + struct iwf_fpga_dpu *dpu; + struct iwf_fpga_reset *reset; + struct iwf_fpga_irq *irq; + struct iwf_fpga_sem *sem; + struct iwf_fpga_heater *heater; + struct iwf_fpga_adc_ctrl *adc_ctrl; + struct iwf_fpga_adc_val *adc_val; + struct iwf_fpga_mem_ctrl *mem_ctrl; + struct iwf_fpga_flash_cmd *flash_cmd; + struct iwf_fpga_flash_addr *flash_addr; + struct iwf_fpga_flash_status *flash_status; + + uint32_t *flash_data[FLASH_DEVICES]; +}; + + + +extern struct iwf_fpga_map fpga; + + + +#define SEM_ON 0x00000001 +#define SEM_OFF 0xfffffffe + +#define SEM_HEATER_ON 0x00000010 +#define SEM_HEATER_OFF 0xffffffef + +#define SEM_STATUS_ON 0x00000001 +#define SEM_STATUS_FAILURE 0x00000002 +#define SEM_STATUS_HEATER_ON 0x00000010 + +/* use one of the folllowing reset types to + trigger a reset using fpga_reset_ctrl_set */ +#define RESET_CTRL_UN 0x00000004 /* unknown, FDIR */ +#define RESET_CTRL_CO 0x00000008 /* commanded reset */ +#define RESET_CTRL_MB 0x00000020 /* RESET_RT mode code */ + +/* these are the types that are reported in the + DBS exchange area as reset information */ +#define DBS_EXCHANGE_RESET_TYPE_UN 0x00000000 +#define DBS_EXCHANGE_RESET_TYPE_PO 0x00000001 +#define DBS_EXCHANGE_RESET_TYPE_WD 0x00000002 +#define DBS_EXCHANGE_RESET_TYPE_EX 0x00000003 +#define DBS_EXCHANGE_RESET_TYPE_CO 0x00000004 +#define DBS_EXCHANGE_RESET_TYPE_CP 0x00000005 +#define DBS_EXCHANGE_RESET_TYPE_MB 0x00000006 + +#define MEM_CTRL_SRAM_FLASH_ACTIVE 0x00000100 +#define MEM_CTRL_PROM_ACTIVE 0xfffffeff + +#define MEM_CTRL_WRITE_PROTECT_OFF 0x00000001 +#define MEM_CTRL_WRITE_PROTECT_ON 0xfffffffe + +#define MEM_CTRL_FLASH_READY 0x00000002 +#define MEM_CTRL_FLASH_EDAC_READY 0x00000004 + +#define MEM_CTRL_FLASH_EMPTY 0x00000004 + + +#define FLASH_EDAC_WRITE_UNPROTECTED 0x00000080 +#define FLASH_EDAC_READ 0x00000040 +#define FLASH_EDAC_FAIL 0x00000001 + +#define PT2_BOARD 0x00000002 +#define EM_BOARD 0x00000003 +#define EQM_BOARD_NOM 0x00000005 +#define EQM_BOARD_RED 0x00000006 +#define FM_BOARD_NOM 0x00000009 +#define FM_BOARD_RED 0x0000000A + +enum heater {HEATER_1, HEATER_2, HEATER_3, HEATER_4}; + + + +uint32_t fpga_version_reg_get(void); +uint32_t fpga_dpu_status_reg_get(void); +uint32_t fpga_dpu_addr_reg_get(void); +uint32_t fpga_sem_status_reg_get(void); +uint32_t fpga_oper_heater_status_reg_get(void); + + +void fpga_sem_switch_on(uint8_t); +void fpga_sem_switch_off(uint8_t); + +void fpga_sem_heater_on(void); +void fpga_sem_heater_off(void); + +uint32_t fpga_sem_get_status_on(void); +uint32_t fpga_sem_get_status_failure(void); +uint32_t fpga_sem_get_status_heater_on(void); + +/* getter functions for the BEE FPGA analog values */ +uint16_t fpga_adc_get_adc_p3v3(void); +uint16_t fpga_adc_get_adc_p5v(void); +uint16_t fpga_adc_get_adc_p1v8(void); +uint16_t fpga_adc_get_adc_p2v5(void); +uint16_t fpga_adc_get_adc_n5v(void); +uint16_t fpga_adc_get_adc_pgnd(void); +uint16_t fpga_adc_get_adc_tempoh1a(void); +uint16_t fpga_adc_get_adc_temp1(void); +uint16_t fpga_adc_get_adc_tempoh2a(void); +uint16_t fpga_adc_get_adc_tempoh1b(void); +uint16_t fpga_adc_get_adc_tempoh3a(void); +uint16_t fpga_adc_get_adc_tempoh2b(void); +uint16_t fpga_adc_get_adc_tempoh4a(void); +uint16_t fpga_adc_get_adc_tempoh3b(void); +uint16_t fpga_adc_get_spare_01(void); +uint16_t fpga_adc_get_adc_tempoh4b(void); +uint16_t fpga_adc_get_sem_p15v(void); +uint16_t fpga_adc_get_sem_p30v(void); +uint16_t fpga_adc_get_sem_p5v0(void); +uint16_t fpga_adc_get_sem_p7v0(void); +uint16_t fpga_adc_get_spare_02(void); +uint16_t fpga_adc_get_sem_n5v0(void); + + +uint32_t fpga_dpu_get_board_serial(void); +uint32_t fpga_dpu_get_core_power_status(void); +uint32_t fpga_dpu_get_dpu_power_status(void); + + +uint16_t fpga_dpu_get_rt_addr(void); + +void fpga_reset_ctrl_set(uint32_t flag); +uint32_t fpga_reset_status_get(void); + +void fpga_heater_on(enum heater h); +void fpga_heater_off(enum heater h); + +uint32_t fpga_heater_status(enum heater h); + +uint32_t fpga_flash_ready(void); + +uint32_t fpga_flash_read_edac_status(void); + +uint32_t fpga_flash_edac_ready(void); + +uint32_t fpga_flash_empty(void); + +void fpga_flash_set_cmd(uint32_t unit, uint32_t cmd); + +void fpga_flash_write_addr(uint32_t unit, uint32_t addr); + +uint32_t fpga_flash_read_word(uint32_t unit); + +void fpga_flash_write_word(uint32_t unit, uint32_t word); + +uint32_t fpga_flash_read_status(uint32_t unit); + +void fpga_flash_enable_write_protect(void); +void fpga_flash_disable_write_protect(void); + +uint32_t fpga_mem_ctrl_sram_flash_enabled(void); +void fpga_mem_ctrl_sram_flash_set_enabled(void); +void fpga_mem_ctrl_sram_flash_clear_enabled(void); + + +#endif /* IWF_FPGA_H */ diff --git a/IBSW/include/leon/irq.h b/IBSW/include/leon/irq.h new file mode 100644 index 0000000000000000000000000000000000000000..cd7946061c4d7b2079115cb540ddbd9052aac711 --- /dev/null +++ b/IBSW/include/leon/irq.h @@ -0,0 +1,110 @@ +/** + * @file leon/irq.h + * + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date 2015 + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief a list of IRQ numbers used in the GR712RC + */ + + +#ifndef IRQ_H +#define IRQ_H + +/** + * Note: some IRQs are shared betweend devices; these devices cannot usually be used a the same time and + * are selected by programming the appropriate jumpers on the board + */ + +/** + * IRQs 1-15 are external I/O interrupts + */ + +#define GR712_IRL1_AHBSTAT 1 /* AHB status register, bus error */ +#define GR712_IRL1_APBUART_0 2 /* UART0 RX/TX interrupt (uart0) */ +#define GR712_IRL1_GRGPIO_0 3 /* GPIO0 */ +#define GR712_IRL1_GRGPIO_1 4 /* GPIO1 */ +#define GR712_IRL1_CANOC_0 5 /* OC CAN AHB interface (core 1) */ +#define GR712_IRL1_CANOC_1 6 /* OC CAN AHB interface (core 2) */ +#define GR712_IRL1_GRTIMER 7 /* Timer Unit with Latches (grtimer0); underflow */ +#define GR712_IRL1_GPTIMER_0 8 /* Modular Timer Unit 0 (gptimer0) */ +#define GR712_IRL1_GPTIMER_1 9 /* Modular Timer Unit 1 */ +#define GR712_IRL1_GPTIMER_2 10 /* Modular Timer Unit 2 */ +#define GR712_IRL1_GPTIMER_3 11 /* Modular Timer Unit 3 */ +#define GR712_IRL1_IRQMP 12 /* Multi-Processor Interrupt Control (chained IRQ controller) */ +#define GR712_IRL1_SPICTRL 13 /* SPI Controller (spi0) */ +#define GR712_IRL1_SLINK 13 /* SLINK Master (adev14) */ +#define GR712_IRL1_B1553BRM 14 /* AMBA Wrapper for Core1553BRM (b1553brm0) */ +#define GR712_IRL1_GRETH 14 /* GR Ethernet MAC (greth0) */ +#define GR712_IRL1_GRTC 14 /* CCSDS Telecommand Decoder (grtc0) */ +#define GR712_IRL1_SATCAN 14 /* SatCAN controller (satcan0) */ +/* IRQ 15 is not maskable and not mapped to a particular function in GR712 */ + + +/** + * IRQ 16-31 are generated as IRQ 12 on the chained interrupt controller + */ + +#define GR712_IRL2_ASCS 16 /* ASCS Master (adev27) */ +#define GR712_IRL2_APBUART_1 17 /* UART1 RX/TX interrupt (uart1) */ +#define GR712_IRL2_APBUART_2 18 /* UART2 RX/TX interrupt (uart2) */ +#define GR712_IRL2_APBUART_3 19 /* UART3 RX/TX interrupt (uart3) */ +#define GR712_IRL2_APBUART_4 20 /* UART4 RX/TX interrupt (uart4) */ +#define GR712_IRL2_APBUART_5 21 /* UART5 RX/TX interrupt (uart5) */ +#define GR712_IRL2_GRSPW2_0 22 /* GRSPW2 SpaceWire Serial Link RX/TX data interrupt (grspw0) */ +#define GR712_IRL2_GRSPW2_1 23 /* GRSPW2 SpaceWire Serial Link RX/TX data interrupt (grspw1) */ +#define GR712_IRL2_GRSPW2_2 24 /* GRSPW2 SpaceWire Serial Link RX/TX data interrupt (grspw2) */ +#define GR712_IRL2_GRSPW2_3 25 /* GRSPW2 SpaceWire Serial Link RX/TX data interrupt (grspw3) */ +#define GR712_IRL2_GRSPW2_4 26 /* GRSPW2 SpaceWire Serial Link RX/TX data interrupt (grspw4) */ +#define GR712_IRL2_GRSPW2_5 27 /* GRSPW2 SpaceWire Serial Link RX/TX data interrupt (grspw5) */ +#define GR712_IRL2_I2CMST 28 /* AMBA Wrapper for OC I2C-Master (i2cmst0) */ +#define GR712_IRL2_GRTM 29 /* CCSDS Telemetry Encoder interrupt */ +#define GR712_IRL2_GRTMTS 30 /* CCSDS Telemetry Encoder time strobe interrupt */ + + +/** + * chained IRQ controller interrupt + */ + +#define IRL1_EXTENDED_INT GR712_IRL1_IRQMP + + +/** aliases */ + +#define GR712_IRL1_GPIO1 1 +#define GR712_IRL1_GPIO2 2 +#define GR712_IRL1_GPIO3 3 +#define GR712_IRL1_GPIO4 4 +#define GR712_IRL1_GPIO5 5 +#define GR712_IRL1_GPIO6 6 +#define GR712_IRL1_GPIO7 7 +#define GR712_IRL1_GPIO8 8 +#define GR712_IRL1_GPIO9 9 +#define GR712_IRL1_GPIO10 10 +#define GR712_IRL1_GPIO11 11 +#define GR712_IRL1_GPIO12 12 +#define GR712_IRL1_GPIO13 13 +#define GR712_IRL1_GPIO14 14 +#define GR712_IRL1_GPIO15 15 + + + + + + + + + + +#endif diff --git a/IBSW/include/leon/irq_dispatch.h b/IBSW/include/leon/irq_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..f00a6b362ff22a3e55f210a3368426ca9ca12afc --- /dev/null +++ b/IBSW/include/leon/irq_dispatch.h @@ -0,0 +1,40 @@ +/** + * @file leon/irq_dispatch.h + * @ingroup irq_dispatch + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date December, 2013 + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef IRQ_DISPATCH_H +#define IRQ_DISPATCH_H + +#include <stdint.h> + +enum prty {PRIORITY_NOW, PRIORITY_LATER}; + +int32_t irq_dispatch_enable(); + +void irq_queue_execute(); + +void irq_set_level(uint32_t irq_mask, uint32_t level); + +int32_t irl1_register_callback(int32_t irq, enum prty priority, int32_t (* callback)(void *userdata), void *userdata); +int32_t irl2_register_callback(int32_t irq, enum prty priority, int32_t (* callback)(void *userdata), void *userdata); + +int32_t irl1_deregister_callback(int32_t irq, int32_t(* callback)(void *userdata), void *userdata); +int32_t irl2_deregister_callback(int32_t irq, int32_t(* callback)(void *userdata), void *userdata); + + +#endif diff --git a/IBSW/include/leon/leon_reg.h b/IBSW/include/leon/leon_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..9ab3fd9c551fcd230509923f042f06efb737feef --- /dev/null +++ b/IBSW/include/leon/leon_reg.h @@ -0,0 +1,172 @@ +/** + * @file leon/leon_reg.h + * + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date 2015 + * + * @copyright GPLv2 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief layout of some registers in the GR712RC + * + */ + +#ifndef LEON_REG_H +#define LEON_REG_H + +#include <stdint.h> + +/** + * helper macro to fill unused 4-byte slots with "unusedXX" variables + * yes, this needs to be done exactly like that, or __COUNTER__ will not be expanded + */ +#define CONCAT(x, y) x##y +#define MACRO_CONCAT(x, y) CONCAT(x, y) +#define UNUSED_UINT32_SLOT uint32_t MACRO_CONCAT(unused, __COUNTER__) + + +#define CORE1553BRM_REG_BASE 0xFFF00000 + +/* LEON3 APB base address is at 0x80000000 + * documentation appears to be conflicting sometimes, your mileage may vary + * offsets from base are indicated to the right for orientation + */ + +#define LEON3_BASE_ADDRESS_APB 0x80000000 + +#define LEON3_BASE_ADDRESS_FTMCTRL 0x80000000 +#define LEON3_BASE_ADDRESS_APBUART 0x80000100 +#define LEON3_BASE_ADDRESS_IRQMP 0x80000200 +#define LEON3_BASE_ADDRESS_GPTIMER 0x80000300 +#define LEON3_BASE_ADDRESS_GRGPIO_1 0x80000900 +#define LEON3_BASE_ADDRESS_GRGPIO_2 0x80000A00 +#define LEON3_BASE_ADDRESS_AHBSTAT 0x80000F00 +#define LEON3_BASE_ADDRESS_GRTIMER 0x80100600 + +/* FTMCTRL Memory Controller Registers [p. 44] */ + +struct leon3_ftmctrl_registermap { + uint32_t mcfg1; + uint32_t mcfg2; + uint32_t mcfg3; +}; + +struct leon3_apbuart_registermap { + uint32_t data; + uint32_t status; + uint32_t ctrl; + uint32_t scaler; +}; + +struct leon3_grgpio_registermap { + uint32_t ioport_data; + uint32_t ioport_output_value; + uint32_t ioport_direction; + uint32_t irq_mask; + uint32_t irq_polarity; + uint32_t irq_edge; +}; + +struct leon3_irqctrl_registermap { + uint32_t irq_level; /* 0x00 */ + uint32_t irq_pending; /* 0x04 */ + uint32_t irq_force; /* 0x08 */ + uint32_t irq_clear; /* 0x0C */ + uint32_t mp_status; /* 0x10 */ + uint32_t mp_broadcast; /* 0x14 */ + UNUSED_UINT32_SLOT; /* 0x18 */ + UNUSED_UINT32_SLOT; /* 0x1C */ + UNUSED_UINT32_SLOT; /* 0x20 */ + UNUSED_UINT32_SLOT; /* 0x24 */ + UNUSED_UINT32_SLOT; /* 0x28 */ + UNUSED_UINT32_SLOT; /* 0x2C */ + UNUSED_UINT32_SLOT; /* 0x30 */ + UNUSED_UINT32_SLOT; /* 0x34 */ + UNUSED_UINT32_SLOT; /* 0x38 */ + UNUSED_UINT32_SLOT; /* 0x3C */ + uint32_t irq_mpmask[2]; /* 0x40 CPU 0 */ + /* 0x44 CPU 1 */ + UNUSED_UINT32_SLOT; /* 0x48 */ + UNUSED_UINT32_SLOT; /* 0x4C */ + UNUSED_UINT32_SLOT; /* 0x50 */ + UNUSED_UINT32_SLOT; /* 0x54 */ + UNUSED_UINT32_SLOT; /* 0x58 */ + UNUSED_UINT32_SLOT; /* 0x5C */ + UNUSED_UINT32_SLOT; /* 0x60 */ + UNUSED_UINT32_SLOT; /* 0x64 */ + UNUSED_UINT32_SLOT; /* 0x68 */ + UNUSED_UINT32_SLOT; /* 0x6C */ + UNUSED_UINT32_SLOT; /* 0x70 */ + UNUSED_UINT32_SLOT; /* 0x74 */ + UNUSED_UINT32_SLOT; /* 0x78 */ + UNUSED_UINT32_SLOT; /* 0x7C */ + uint32_t irq_mpforce[2]; /* 0x80 CPU 0*/ + /* 0x84 CPU 1*/ + UNUSED_UINT32_SLOT; /* 0x88 */ + UNUSED_UINT32_SLOT; /* 0x8C */ + UNUSED_UINT32_SLOT; /* 0x90 */ + UNUSED_UINT32_SLOT; /* 0x94 */ + UNUSED_UINT32_SLOT; /* 0x98 */ + UNUSED_UINT32_SLOT; /* 0x9C */ + UNUSED_UINT32_SLOT; /* 0xA0 */ + UNUSED_UINT32_SLOT; /* 0xA4 */ + UNUSED_UINT32_SLOT; /* 0xA8 */ + UNUSED_UINT32_SLOT; /* 0xAC */ + UNUSED_UINT32_SLOT; /* 0xB0 */ + UNUSED_UINT32_SLOT; /* 0xB4 */ + UNUSED_UINT32_SLOT; /* 0xB8 */ + UNUSED_UINT32_SLOT; /* 0xBC */ + uint32_t extended_irq_id[2]; /* 0xC0 CPU 0*/ + /* 0xC4 CPU 1*/ +}; + + + +struct leon3_ahbstat_registermap { + uint32_t status; + uint32_t failing_address; +}; + + + +struct gptimer_timer { + uint32_t value; + uint32_t reload; + uint32_t ctrl; + uint32_t unused; +}; + +struct gptimer_unit { + uint32_t scaler; + uint32_t scaler_reload; + uint32_t config; + uint32_t unused; + struct gptimer_timer timer[4]; +}; + +struct grtimer_timer { + uint32_t value; + uint32_t reload; + uint32_t ctrl; + uint32_t latch_value; +}; + +struct grtimer_unit { + uint32_t scaler; + uint32_t scaler_reload; + uint32_t config; + + uint32_t irq_select; + + struct grtimer_timer timer[2]; +}; + +#endif diff --git a/IBSW/include/leon3_dsu.h b/IBSW/include/leon3_dsu.h new file mode 100644 index 0000000000000000000000000000000000000000..8725222535fc08f7fe2faa259ea4ae81f2922469 --- /dev/null +++ b/IBSW/include/leon3_dsu.h @@ -0,0 +1,263 @@ +/** + * @file leon3_dsu.h + * @ingroup leon3_dsu + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date February, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef LEON3_DSU_H +#define LEON3_DSU_H + + +/* + * helper macro to fill unused 4-byte slots with "unusedXX" variables + * yes, this needs to be done exactly like that, or __COUNTER__ will not be expanded + */ + +#define CONCAT(x, y) x##y +#define MACRO_CONCAT(x, y) CONCAT(x, y) +#define UNUSED_UINT32_SLOT uint32_t MACRO_CONCAT(unused, __COUNTER__) + + + +#ifndef NWINDOWS +#define NWINDOWS 8 /* number of register windows */ +#endif + + +/** + * @see GR712-UM v2.3 pp. 81 + */ + + +#define DSU_CTRL 0x90000000 +#define DSU_TIMETAG 0x90000008 + +#define DSU_BREAK_STEP 0x90000020 /* mapped only in CPU0 DSU */ +#define DSU_MODE_MASK 0x90000024 /* mapped only in CPU0 DSU */ + +#define DSU_AHB_TRACE_CTRL 0x90000040 +#define DSU_AHB_TRACE_IDX 0x90000044 + +#define DSU_AHB_BP_ADDR_1 0x90000050 +#define DSU_AHB_MASK_1 0x90000054 +#define DSU_AHB_BP_ADDR_2 0x90000058 +#define DSU_AHB_MASK_2 0x9000005c + +#define DSU_INST_TRCE_BUF_START 0x90100000 +#define DSU_INST_TRCE_BUF_LINES 256 +#define DSU_INST_TRCE_CTRL 0x90110000 + +#define DSU_AHB_TRCE_BUF_START 0x90200000 +#define DSU_AHB_TRCE_BUF_LINES 256 + +#define DSU_IU_REG 0x90300000 + +#define DSU_IU_REG_CHECKBITS 0x90300800 + +#define DSU_FPU_REG 0x90301000 + +#define DSU_IU_SPECIAL_REG 0x90400000 + +#define DSU_REG_Y 0x90400000 +#define DSU_REG_PSR 0x90400004 +#define DSU_REG_WIM 0x90400008 +#define DSU_REG_TBR 0x9040000C +#define DSU_REG_PC 0x90400010 +#define DSU_REG_NPC 0x90400014 +#define DSU_REG_FSR 0x90400018 +#define DSU_REG_CPSR 0x9040001C + + + + +#define DSU_OFFSET_CPU(x) ((x & 0x07) << 24) +#define DSU_BASE(x) (DSU_CTRL + DSU_OFFSET_CPU(x)) + + +/** + * @see GR712-UM v2.3 p. 82 + */ +#define DSU_CTRL_TE (1 << 0) /* trace enable */ +#define DSU_CTRL_BE (1 << 1) /* break on error */ +#define DSU_CTRL_BW (1 << 2) /* break on IU watchpoint */ +#define DSU_CTRL_BS (1 << 3) /* break on s/w breakpoint */ +#define DSU_CTRL_BX (1 << 4) /* break on any trap */ +#define DSU_CTRL_BZ (1 << 5) /* break on error trap */ +#define DSU_CTRL_DM (1 << 6) /* RO: debug mode status */ + /* bits 7, 8 are unused */ +#define DSU_CTRL_PE (1 << 9) /* processor error mode */ +#define DSU_CTRL_HL (1 << 10) /* processor halt mode */ +#define DSU_CTRL_PW (1 << 11) /* processor power mode */ + + + + + + +/** + * maps the break and step register + * @see GR712-UM v2.3 p.82 + */ +__extension__ +struct dsu_break_step { + union { + struct { + uint16_t single_step; + uint16_t break_now; + }; + uint32_t reg; + }; +}; + +/** + * maps the debug mode maskregister + * @see GR712-UM v2.3 p.83 + */ +__extension__ +struct dsu_mode_mask { + union { + struct { + uint16_t debug_mode; + uint16_t enter_debug; + }; + uint32_t reg; + }; +}; + + + +/** + * maps the AHB trace buffer registers from DSU_AHB_TRACE_CTRL to DSU_AHB_MASK_2 + * must be pointed to DSU_AHB_TRACE_CTRL + */ + +struct ahb_bp_reg { + uint32_t addr; + uint32_t mask; +}; + +struct dsu_ahb_trace_ctrl { + uint32_t ctrl; + uint32_t idx; + UNUSED_UINT32_SLOT; + UNUSED_UINT32_SLOT; + UNUSED_UINT32_SLOT; + struct ahb_bp_reg bp[2]; +}; + + +/** + * a single line in the instruction trace buffer, see GR712-UM v2.3 p.80 + */ +__extension__ +struct instr_trace_buffer_line { + + union { + struct { + uint32_t unused :1; + uint32_t multi_cycle_inst :1; + uint32_t timetag :30; + uint32_t load_store_param :32; + uint32_t program_cntr :30; + uint32_t instr_trap :1; + uint32_t proc_error_mode :1; + uint32_t opcode :32; + }; + uint32_t field[4]; + }; +}__attribute__((packed)); + +/** + * maps the instruction trace buffer, must be pointed to DSU_INST_TRCE_BUF_START + */ + +struct dsu_instr_trace_buffer { + struct instr_trace_buffer_line line[DSU_INST_TRCE_BUF_LINES]; +}; + + +/** + * a single line in the AHB trace buffer, see GR712-UM v2.3 p.79 + */ +__extension__ +struct ahb_trace_buffer_line { + + union { + struct { + uint32_t ahb_bp_hi :1; + uint32_t unused1 :1; + uint32_t timetag :30; + uint32_t unused2 :1; + uint32_t hirq :15; + uint32_t hwrite :1; + uint32_t htrans :2; + uint32_t hsize :3; + uint32_t hburst :3; + uint32_t hmaster :4; + uint32_t hmastlock :1; + uint32_t hresp :2; + uint32_t load_store_data :32; + uint32_t load_store_addr :32; + }; + uint32_t field[4]; + }; +}__attribute__((packed)); + + +/** + * maps the AHB trace buffer, must be pointed to DSU_AHB_TRCE_BUF_START + */ + +struct dsu_ahb_trace_buffer { + struct ahb_trace_buffer_line line[DSU_AHB_TRCE_BUF_LINES]; +}; + + + + + +void dsu_set_noforce_debug_mode(uint32_t cpu); +void dsu_set_cpu_debug_on_error(uint32_t cpu); +void dsu_set_cpu_break_on_iu_watchpoint(uint32_t cpu); +void dsu_set_cpu_break_on_breakpoint(uint32_t cpu); +void dsu_set_cpu_break_on_trap(uint32_t cpu); +void dsu_set_cpu_break_on_error_trap(uint32_t cpu); +void dsu_set_force_debug_on_watchpoint(uint32_t cpu); +uint32_t dsu_get_reg_psr(uint32_t cpu); +uint32_t dsu_get_reg_tbr(uint32_t cpu); +void dsu_set_reg_psr(uint32_t cpu, uint32_t val); + +uint32_t dsu_get_reg_wim(uint32_t cpu); +uint32_t dsu_get_reg_pc(uint32_t cpu); +uint32_t dsu_get_reg_sp(uint32_t cpu, uint32_t cwp); +uint32_t dsu_get_reg_fsr(uint32_t cpu); + + +void dsu_set_reg_tbr(uint32_t cpu, uint32_t val); +void dsu_set_reg_pc(uint32_t cpu, uint32_t val); +void dsu_set_reg_npc(uint32_t cpu, uint32_t val); +uint32_t dsu_get_reg_npc(uint32_t cpu); +void dsu_clear_iu_reg_file(uint32_t cpu); +void dsu_clear_cpu_debug_on_error(uint32_t cpu); +void dsu_clear_cpu_break_on_iu_watchpoint(uint32_t cpu); +void dsu_clear_cpu_break_on_breakpoint(uint32_t cpu); +void dsu_clear_cpu_break_on_trap(uint32_t cpu); +void dsu_clear_cpu_break_on_error_trap(uint32_t cpu); +void dsu_clear_force_debug_on_watchpoint(uint32_t cpu); +void dsu_set_reg_wim(uint32_t cpu, uint32_t val); +void dsu_set_reg_sp(uint32_t cpu, uint32_t cwp, uint32_t val); +void dsu_set_reg_fp(uint32_t cpu, uint32_t cwp, uint32_t val); + +#endif /* LEON3_DSU_H */ diff --git a/IBSW/include/leon3_gptimer.h b/IBSW/include/leon3_gptimer.h new file mode 100644 index 0000000000000000000000000000000000000000..be128ebc54da96aaaaf6b5e6b6f95b2463a8c497 --- /dev/null +++ b/IBSW/include/leon3_gptimer.h @@ -0,0 +1,70 @@ +/** + * @file leon3_gptimer.h + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef LEON3_GPTIMER_H +#define LEON3_GPTIMER_H + +#include <io.h> +#include <leon/leon_reg.h> + + + + +void gptimer_set_scaler_reload(struct gptimer_unit *ptu, uint32_t value); +uint32_t gptimer_get_scaler_reload(struct gptimer_unit *ptu); + +void gptimer_set_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer); +void gptimer_clear_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer); + +void gptimer_set_load(struct gptimer_unit *ptu, uint32_t timer); +void gptimer_clear_load(struct gptimer_unit *ptu, uint32_t timer); + +void gptimer_set_enabled(struct gptimer_unit *ptu, uint32_t timer); +void gptimer_clear_enabled(struct gptimer_unit *ptu, uint32_t timer); + +void gptimer_set_restart(struct gptimer_unit *ptu, uint32_t timer); +void gptimer_clear_restart(struct gptimer_unit *ptu, uint32_t timer); + +void gptimer_set_chained(struct gptimer_unit *ptu, uint32_t timer); +void gptimer_clear_chained(struct gptimer_unit *ptu, uint32_t timer); + +uint32_t gptimer_get_interrupt_pending_status(struct gptimer_unit *ptu, + uint32_t timer); +void gptimer_clear_interrupt_pending_status(struct gptimer_unit *ptu, + uint32_t timer); + +uint32_t gptimer_get_num_implemented(struct gptimer_unit *ptu); +uint32_t gptimer_get_first_timer_irq_id(struct gptimer_unit *ptu); + +void gptimer_set_value(struct gptimer_unit *ptu, + uint32_t timer, + uint32_t value); +uint32_t gptimer_get_value(struct gptimer_unit *ptu, uint32_t timer); + +void gptimer_set_reload(struct gptimer_unit *ptu, + uint32_t timer, + uint32_t reload); +uint32_t gptimer_get_reload(struct gptimer_unit *ptu, uint32_t timer); + +void gptimer_start(struct gptimer_unit *ptu, uint32_t timer, uint32_t value); + +void gptimer_start_cyclical(struct gptimer_unit *ptu, + uint32_t timer, + uint32_t value); + +#endif /* LEON3_GPTIMER_H */ diff --git a/IBSW/include/leon3_grtimer.h b/IBSW/include/leon3_grtimer.h new file mode 100644 index 0000000000000000000000000000000000000000..94620609a98711e6334aa23e68b224d6334eb8d1 --- /dev/null +++ b/IBSW/include/leon3_grtimer.h @@ -0,0 +1,73 @@ +/** + * @file leon3_grtimer.h + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef LEON3_GRTIMER_H +#define LEON3_GRTIMER_H + +#include <io.h> +#include <leon/leon_reg.h> + + +#define LEON3_GRTIMER_CFG_LATCH 0x800 + + +void grtimer_set_scaler_reload(struct grtimer_unit *rtu, uint32_t value); +uint32_t grtimer_get_scaler_reload(struct grtimer_unit *rtu); + +void grtimer_set_interrupt_enabled(struct grtimer_unit *rtu, uint32_t timer); +void grtimer_clear_interrupt_enabled(struct grtimer_unit *rtu, uint32_t timer); + +void grtimer_set_load(struct grtimer_unit *rtu, uint32_t timer); +void grtimer_clear_load(struct grtimer_unit *rtu, uint32_t timer); + +void grtimer_set_enabled(struct grtimer_unit *rtu, uint32_t timer); +void grtimer_clear_enabled(struct grtimer_unit *rtu, uint32_t timer); + +void grtimer_set_restart(struct grtimer_unit *rtu, uint32_t timer); +void grtimer_clear_restart(struct grtimer_unit *rtu, uint32_t timer); + +void grtimer_set_chained(struct grtimer_unit *rtu, uint32_t timer); +void grtimer_clear_chained(struct grtimer_unit *rtu, uint32_t timer); + +uint32_t grtimer_get_interrupt_pending_status(struct grtimer_unit *rtu, + uint32_t timer); +void grtimer_clear_interrupt_pending_status(struct grtimer_unit *rtu, + uint32_t timer); + +uint32_t grtimer_get_num_implemented(struct grtimer_unit *rtu); + +uint32_t grtimer_get_first_timer_irq_id(struct grtimer_unit *rtu); + +void grtimer_set_value(struct grtimer_unit *rtu, + uint32_t timer, + uint32_t value); +uint32_t grtimer_get_value(struct grtimer_unit *rtu, uint32_t timer); + + +void grtimer_set_reload(struct grtimer_unit *rtu, + uint32_t timer, + uint32_t reload); +uint32_t grtimer_get_reload(struct grtimer_unit *rtu, uint32_t timer); + +void grtimer_set_latch_irq(struct grtimer_unit *rtu, uint32_t irq); +void grtimer_clear_latch_irq(struct grtimer_unit *rtu, uint32_t irq); +void grtimer_enable_latch(struct grtimer_unit *rtu); + +uint32_t grtimer_get_latch_value(struct grtimer_unit *rtu, uint32_t timer); + +#endif /* LEON3_GRTIMER_H */ diff --git a/IBSW/include/leon3_grtimer_longcount.h b/IBSW/include/leon3_grtimer_longcount.h new file mode 100644 index 0000000000000000000000000000000000000000..20e35e11874b505ad5f8c2863fc81fc0a45d7a15 --- /dev/null +++ b/IBSW/include/leon3_grtimer_longcount.h @@ -0,0 +1,51 @@ +/** + * @file leon3_grtimer_longcount.h + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef LEON3_GRTIMER_LONGCOUNT_H +#define LEON3_GRTIMER_LONGCOUNT_H + +#include <leon/leon_reg.h> +#include <leon3_grtimer.h> + +/** + * "coarse" contains the counter of the secondary (chained) timer in + * multiples of seconds and is chained + * to the "fine" timer, which should hence underflow in a 1-second cycle + */ + +struct grtimer_uptime { + uint32_t coarse; + uint32_t fine; +}; + + +int32_t grtimer_longcount_start(struct grtimer_unit *rtu, + uint32_t scaler_reload, + uint32_t fine_ticks_per_sec, + uint32_t coarse_ticks_max); + +void grtimer_longcount_get_uptime(struct grtimer_unit *rtu, + struct grtimer_uptime *up); + +double grtimer_longcount_difftime(struct grtimer_unit *rtu, + struct grtimer_uptime time1, + struct grtimer_uptime time0); + +uint32_t grtimer_longcount_get_latch_time_diff(struct grtimer_unit *rtu); + +#endif /* LEON3_GRTIMER_LONGCOUNT_H */ diff --git a/IBSW/include/leon3_timers.h b/IBSW/include/leon3_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..58d75fb03abf92e2239b438e0f1fe040e27a496d --- /dev/null +++ b/IBSW/include/leon3_timers.h @@ -0,0 +1,35 @@ +/** + * @file leon3_timers.h + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#ifndef LEON3_TIMERS_H +#define LEON3_TIMERS_H + + +#define LEON3_TIMER_EN 0x00000001 /* enable counting */ +#define LEON3_TIMER_RS 0x00000002 /* restart from timer reload value */ +#define LEON3_TIMER_LD 0x00000004 /* load counter */ +#define LEON3_TIMER_IE 0x00000008 /* irq enable */ +#define LEON3_TIMER_IP 0x00000010 /* irq pending (clear by writing 0 */ +#define LEON3_TIMER_CH 0x00000020 /* chain with preceeding timer */ + +#define LEON3_CFG_TIMERS_MASK 0x00000007 +#define LEON3_CFG_IRQNUM_MASK 0x000000f8 +#define LEON3_CFG_IRQNUM_SHIFT 0x3 + +#endif diff --git a/IBSW/include/list.h b/IBSW/include/list.h new file mode 100644 index 0000000000000000000000000000000000000000..68466b8aa2f7578410bc057cd1b4c53e5f3d65eb --- /dev/null +++ b/IBSW/include/list.h @@ -0,0 +1,349 @@ +/** +. @file list.h + * @ingroup linked_list + * + * @note This list implementation was shamelessly stolen and modified from the + * linux kernel's include/linux/list.h + * Its API (if you will) is used in this (currently non-GPL) project as + * under the assumption that the inclusion of header files does not + * automatically imply derivative work, see + * http://lkml.iu.edu//hypermail/linux/kernel/0301.1/0362.html + * + * No explicit copyright or author statement is given in the original + * file, so we assume per the Linux COPYING file: + * + * @author Linus Torvalds (and others who actually wrote the linux kernel + * version) + * @author Armin Luntzer (armin.luntzer@univie.ac.at) (local modifications or + * extensions) + * + * @copyright + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup linked_list Linked Lists + * @brief a modified doubly-linked list implementation from the linux kernel + * + * + * This is a (slightly modified) doubly-linked list implementation from the + * Linux kernel. An easy to understand explanation of + * how it works and is used can be found here + * http://kernelnewbies.org/FAQ/LinkedLists + * + * Be smart + * ----- + * It is a valid to criticise linked lists as generally performing badly + * if you traverse their entries at high frequency rather than just + * manipulating them. This can be especially true (and has been demonstrated + * numerous times) for implementations like std:list. + * + * Please consider the following though: linked lists are not inherently + * slow because of how they work algorithmically (*the opposite is true*), + * but rather because how their cache hit (or miss) rate is in + * configurations where entries are randomly scattered in memory rather + * than layed out in one big chunk. + * + * Be smart. Don't do that. Allocate a pool in a __single chunk__ and enjoy the + * cache performance. Do not use larger chunks than the page size of your + * platform if you have MMU support. If you need more than that, you probably + * need to redesign your program anyways. + * + * This does of course not apply as long as you do access your lists only + * at slow rates (i.e. in the order of several tens of ms) or if performance + * is not at all critial. + * + */ + +#ifndef LIST_H +#define LIST_H + +#ifdef LIST_HEAD +#undef LIST_HEAD +#endif + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * @brief add a new entry + * @param new: new entry to be added + * @param head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ + +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + + +/** + * @brief get the struct for this entry + * @param ptr: the &struct list_head pointer. + * @param type: the type of the struct this is embedded in. + * @param member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + + +/** + * @brief iterate over list of given type + * @param pos: the type * to use as a loop counter. + * @param head: the head for your list. + * @param member: the name of the list_struct within the struct. + * @param note modified to use __typeof__() + */ + +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof__(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, __typeof__(*pos), member)) + + +/** + * @brief iterate over list of given type safe against removal of list entry + * @param pos: the type * to use as a loop counter. + * @param n: another type * to use as temporary storage + * @param head: the head for your list. + * @param member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, __typeof__(*pos), member), \ + n = list_entry(pos->member.next, __typeof__(*pos), member);\ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, __typeof__(*pos), member)) + + +/** + * @brief iterator wrapper start + * @param pos: the type * to use as a loop counter. + * @param head: the head for your list. + * @param member: the name of the list_struct within the struct. + * @param type: the type of struct + * @param warning requires list_entry_while() to close statement + * @param note this construction is necessary for a truly circular list that is "headless" + * @param note and can be iterated from any starting element without additional overhead + * @param note compared to the LIST_HEAD/list_for_each_entry approach + * @param note check if this is functional for all targets (confirmed: gcc 4.8.2) + */ + +#define list_entry_do(pos, head, member, type) \ + { \ + pos = list_entry((head), type, member); \ + do \ + { \ + + +/** + * @brief list iterator wrapper stop + * @param pos: the type * to use as a loop counter. + * @param head: the head for your list. + * @param member: the name of the list_struct within the struct. + * @param type: the type of struct + * @param warning requires list_entry_do() to open statement + * @param note see list_entry_while() + */ + +#define list_entry_while(pos, head, member, type) \ + } \ + while (pos = list_entry(pos->member.next, type, member),\ + &pos->member != head); \ + } + +/** + * @brief the list entry do-while equivalent fo a code block + * @param pos: the type * to use as a loop counter. + * @param head: the head for your list. + * @param member: the name of the list_struct within the struct. + * @param type: the type of struct + * @param _CODE_: a code segment + * @param note see list_entry_while(), list_entry_do() + */ + +#define list_entry_do_while(pos, head, member, type, _CODE_) \ + list_entry_do(pos,head,member,type) \ + { \ + _CODE_; \ + } list_entry_while(pos,head,member,type) + + +/** + * @brief reverse iterate over list of given type + * @param pos: the type * to use as a loop counter. + * @param head: the head for your list. + * @param member: the name of the list_struct within the struct. + * (slightly modified in case there is no typeof() functionality in target compiler) + */ + +#define list_for_each_entry_rev(pos, head, member) \ + for (pos = list_entry((head)->prev, __typeof__(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, __typeof(*pos), member)) + + +/* + * @brief delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + + +/** + * @brief deletes entry from list. + * @param entry: the element to delete from the list. + * @note list_empty on entry does not return true after this, + * the entry is in an undefined state. + */ + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = (void *) 0; + entry->prev = (void *) 0; +} + + +/** + * @brief deletes entry from list. + * @param entry: the element to delete from the list. + * @brief list_empty() on entry does not return true after this, the entry is + * in an undefined state. + */ + +static inline void __list_del_entry(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +/** + * @brief deletes entry from list and reinitialize it. + * @param entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del_entry(entry); + INIT_LIST_HEAD(entry); +} + +/** + * @brief add a new entry + * @param new: new entry to be added + * @param head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ + +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + + +/** + * @brief replace old entry by new one + * @param old : the element to be replaced + * @param new : the new element to insert + * + * If @param old was empty, it will be overwritten. + */ + +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + + +/** + * @brief tests whether a list is empty + * @param head: the list to test. + */ + +static inline int list_empty(struct list_head *head) +{ + return head->next == head; +} + +/** + * @brief tests whether there is at least one element in the list + * @param head: the list to test. + */ + +static inline int list_filled(struct list_head *head) +{ + return head->next != head; +} + + +/** + * @brief delete from one list and add as another's tail + * @param list: the entry to move + * @param head: the head that will follow our entry + */ + +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + + +/** + * @brief rotate the list to the left + * @param head: the head of the list + */ + +static inline void list_rotate_left(struct list_head *head) +{ + struct list_head *first; + + if (!list_empty(head)) { + first = head->next; + list_move_tail(first, head); + } +} + + +#endif diff --git a/IBSW/include/memcfg.h b/IBSW/include/memcfg.h new file mode 100644 index 0000000000000000000000000000000000000000..7dc53b2302cd4ffabe6624e794b7c8222c858b66 --- /dev/null +++ b/IBSW/include/memcfg.h @@ -0,0 +1,108 @@ +/** + * @file memcfg.h + * @ingroup memcfg + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date March, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef MEMCFG_H +#define MEMCFG_H + +#include <stdint.h> + + +/** + * @see GR712-UM v2.3 pp. 66 + */ + + + +#define MCFG1_PROM_READ_WS_MASK 0x0000000F + +#define MCFG1_PROM_WRITE_WS_OFF 4 +#define MCFG1_PROM_WRITE_WS_MASK 0x000000F0 + +#define MCFG1_PROM_WIDTH_OFF 8 +#define MCFG1_PROM_WIDTH_MASK 0x00000300 + +#define MCFG1_PWEN 0x00000800 + +#define MCFG1_ROMBANKSZ_OFF 14 +#define MCFG1_ROMBANKSZ_MASK 0x00003C00 + +#define MCFG1_IOEN 0x00080000 + +#define MCFG1_IO_WAITSTATES_OFF 20 +#define MCFG1_IO_WAITSTATES_MASK 0x00F00000 + +#define MCFG1_BEXCN 0x02000000 +#define MCFG1_IBRDY 0x04000000 + +#define MCFG1_IOBUSW_OFF 27 +#define MCFG1_IOBUSW_MASK 0x18000000 + +#define MCFG1_ABRDY 0x20000000 +#define MCFG1_PBRDY 0x40000000 + + + + +#define MCFG2_RAM_READ_WS_MASK 0x00000003 + +#define MCFG2_RAM_WRITE_WS_OFF 2 +#define MCFG2_RAM_WRITE_WS_MASK 0x0000000C + +#define MCFG2_RAM_WIDTH_OFF 4 +#define MCFG2_RAM_WIDTH_MASK 0x00000030 + +#define MCFG2_RMW 0x00000040 + +#define MCFG2_RAM_BANK_SIZE_OFF 9 +#define MCFG2_RAM_BANK_SIZE_MASK 0x00001E00 + +#define MCFG2_SI 0x00002000 +#define MCFG2_SE 0x00004000 + + +#define MCFG3_PROM_EDAC 0x00000100 +#define MCFG3_RAM_EDAC 0x00000200 +#define MCFG3_RB_EDAC 0x00000400 +#define MCFG3_WB_EDAC 0x00000800 +#define MCFG3_TCB 0x0000007F + + + +/* memory configuration for flash + SRAM */ +#define MEMCFG1_FLASH 0x101aca11 +#define MEMCFG2_SRAM 0x00001665 +#define MEMCFG3_SRAM 0x08000300 + +#define MEMCFG1_PROMACCESS 0x10180011 + + + +void memcfg_enable_ram_edac(void); +void memcfg_disable_ram_edac(void); + +void memcfg_enable_edac_write_bypass(void); +void memcfg_disable_edac_write_bypass(void); + +void memcfg_enable_edac_read_bypass(void); +void memcfg_disable_edac_read_bypass(void); + +uint32_t memcfg_bypass_read(void *addr, uint8_t *tcb); +void memcfg_bypass_write(void *addr, uint32_t value, uint8_t tcb); + +void memcfg_configure_sram_flash_access(void); +#endif /* MEMCFG_H */ diff --git a/IBSW/include/memscrub.h b/IBSW/include/memscrub.h new file mode 100644 index 0000000000000000000000000000000000000000..510bfdc8eeebff39d68563cd72dbc3ea7372e693 --- /dev/null +++ b/IBSW/include/memscrub.h @@ -0,0 +1,31 @@ +/** + * @file memscrub.h + * @ingroup memscrub + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date March, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef MEMSCRUB_H +#define MEMSCRUB_H + +#include <stdint.h> + +uint32_t *memscrub(uint32_t *addr, uint32_t n); +uint32_t memscrub_get_num_log_entries(void); +uint32_t memscrub_repair(void); + +void memscrub_init(void); + + +#endif /* MEMSCRUB_H */ diff --git a/IBSW/include/packet_tracker.h b/IBSW/include/packet_tracker.h new file mode 100644 index 0000000000000000000000000000000000000000..b0fc1de3afd28dc5fb310a219aa4d68c42eb79bd --- /dev/null +++ b/IBSW/include/packet_tracker.h @@ -0,0 +1,92 @@ +/** + * @file packet_tracker.h + * @ingroup packet_tracker + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef PACKET_TRACKER_H +#define PACKET_TRACKER_H + + +#include <circular_buffer8.h> +#include <circular_buffer16.h> +#include <stdint.h> + + +#define PTRACK_PUS_TMTC_HEADER_BYTES 6 + +#ifndef PUS_PKT_MIN_SIZE +#define PUS_PKT_MIN_SIZE 12 +#endif + +/* ecss say: data length = (Number of octets in packet data field) - 1 */ +#define PTRACK_PUS_DATA_LENGTH_ADJUST(x) ((x)+1) + +/* packet size fields */ +#define PUS_LEN_LO_OFFSET 0x04 +#define PUS_LEN_HI_OFFSET 0x05 + +#define PUS_LEN_LO_LSHIFT 0x08 +#define PUS_LEN_HI_MASK 0x00ff + + +/* source/dest ids */ +#define PUS_SRC_ID_OFFSET 0x09 + +#define PUS_ID_GND 0x00 +#define PUS_ID_OBC 0x0c +#define PUS_ID_DPU 0x14 +#define PUS_ID_SEM 0x3c +#define PUS_ID_HK 0x15 + + + +struct packet_tracker { + struct circular_buffer8 pus_pkts; + struct circular_buffer16 pus_size; +}; + + +void ptrack_init(struct packet_tracker *p_pkt, + uint8_t* p_buf_pkts, + uint32_t pkts_elem, + uint16_t *p_buf_size, + uint32_t size_elem); + +void ptrack_reset(struct packet_tracker *p_pkt); + +int32_t ptrack_add_pkt(struct packet_tracker *p_pkt, + uint8_t *packet_buffer, + uint32_t packet_buffer_size); + +uint16_t ptrack_peek_next_pkt_size(struct packet_tracker *p_pkt); +uint16_t ptrack_get_next_pkt(struct packet_tracker *p_pkt, uint8_t *p_buf); + +uint16_t ptrack_get_pkt_size(uint8_t *packet_buffer); + +int32_t ptrack_add_single_pkt(struct packet_tracker *p_pkt, + uint8_t *packet_buffer, + uint32_t packet_buffer_size); + +int32_t ptrack_add_multiple_pkts(struct packet_tracker *p_pkt, + uint8_t *packet_buffer, + uint32_t packet_buffer_size); + +uint8_t ptrack_get_next_pkt_src_id(uint8_t *packet_buffer); + + +uint32_t ptrack_get_packets_in_buffer(struct packet_tracker *p_pkt); + +#endif diff --git a/IBSW/include/spinlock.h b/IBSW/include/spinlock.h new file mode 100644 index 0000000000000000000000000000000000000000..50644f52497a449aa122667873c891bcafd273d2 --- /dev/null +++ b/IBSW/include/spinlock.h @@ -0,0 +1,257 @@ +/** + * @file spinlock.h + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date December, 2013 + * @brief MPPB Spin Locking Mechanism + * + * @copyright Armin Luntzer (armin.luntzer@univie.ac.at) + * @copyright David S. Miller (davem@caip.rutgers.edu), 1997 (some parts) + * + * @copyright + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef SPINLOCK_H +#define SPINLOCK_H + +#include <stdint.h> +#include <compiler.h> + +struct spinlock { + volatile uint8_t lock; + volatile uint32_t lock_recursion; +}; + + +/* the sparc PIL field */ +#define PSR_PIL 0x00000f00 + + +#if (__sparc__) + + + +/** + * @brief save and disable the processor interrupt level state + * @return PSR + * @warning make sure to call a save/restore pair from within the same stack frame + */ + +static uint32_t spin_lock_save_irq() +{ + uint32_t psr; + uint32_t tmp; + /** + * @note RDPSR and WRPSR are only available privileged mode and will trap otherwise + * @note The three NOPs after WRPSR could in principle be left out, + * @note but we keep them nonetheless, as the SPARC (V7.0) instruction manual states: + * @note 3. If any of the three instructions after a WRPSR instruction reads + * @note the modified PSR, the value read is unpredictable. + */ + __asm__ __volatile__( + "rd %%psr, %0 \n\t" + "or %0, %2, %1 \n\t" + "wr %1, 0, %%psr \n\t" + "nop \n\t" + "nop \n\t" + "nop \n\t" + : "=&r" (psr), "=r" (tmp) + : "i" (PSR_PIL) + : "memory"); + return psr; +} + +/** + * @brief Restore the processor interrupt level state + */ + +static void spin_lock_restore_irq(uint32_t psr) +{ + uint32_t tmp; + + __asm__ __volatile__( + "rd %%psr, %0 \n\t" + "and %2, %1, %2 \n\t" + "andn %0, %1, %0 \n\t" + "wr %0, %2, %%psr \n\t" + "nop \n\t" + "nop \n\t" + "nop \n\t" + : "=&r" (tmp) + : "i" (PSR_PIL), "r" (psr) + : "memory"); +} + + +/** + * @brief MPPB LEON-side spin lock + * @param p_lock a struct spinlock + * + * @warning will silently fail AND deadlock everytime YOU are stupid + * @note it is, however, save to use with interrupts (sort of) + */ +__attribute__((unused)) +static void spin_lock(struct spinlock *p_lock) +{ + uint32_t psr_flags; + + if (unlikely(p_lock->lock_recursion)) + return; + + psr_flags = spin_lock_save_irq(); + + p_lock->lock_recursion = 1; + + __asm__ __volatile__( + "1: \n\t" + "ldstub [%0], %%g2 \n\t" + "andcc %%g2, %%g2, %%g2 \n\t" + "bnz,a 1b \n\t" + " nop \n\n" + : + : "r" (&p_lock->lock) + : "g2", "memory", "cc"); + + p_lock->lock_recursion = 0; + + spin_lock_restore_irq(psr_flags); +} + +/** + * @brief MPPB LEON-side spin lock which does not care about interrupts + * @param p_lock a struct spinlock + * + * @warning will silently fail AND deadlock everytime YOU are stupid + */ + +__attribute__((unused)) +static void spin_lock_raw(struct spinlock *p_lock) +{ + if (unlikely(p_lock->lock_recursion)) + return; + + p_lock->lock_recursion = 1; + + __asm__ __volatile__( + "1: \n\t" + "ldstub [%0], %%g2 \n\t" + "andcc %%g2, %%g2, %%g2 \n\t" + "bnz,a 1b \n\t" + " nop \n\n" + : + : "r" (&p_lock->lock) + : "g2", "memory", "cc"); + + p_lock->lock_recursion = 0; +} + +/** + *@brief lock check + *@returns success or failure + */ + +static int spin_is_locked(struct spinlock *p_lock) +{ + return (p_lock->lock != 0); +} + +/** + *@brief spins until lock opens + */ + +__attribute__((unused)) +static void spin_unlock_wait(struct spinlock *p_lock) +{ + __asm__ __volatile__ ("" : : : "memory"); /* optimization barrier, just in case */ + while(spin_is_locked(p_lock)); +} + +/** + * @brief MPPB LEON-side spin lock + * @param p_lock a struct spinlock + * @return success or failure + * + * @note + */ + +__attribute__((unused)) +static int spin_try_lock(struct spinlock *p_lock) +{ + uint32_t retval; + + __asm__ __volatile__("ldstub [%1], %0" : "=r" (retval) : "r" (&p_lock->lock) : "memory"); + + return (retval == 0); +} + +/** + * @brief MPPB LEON-side spin-unlock + * @param p_lock a struct spinlock + */ + +__attribute__((unused)) +static void spin_unlock(struct spinlock *p_lock) +{ + __asm__ __volatile__("swap [%0], %%g0 \n\t" : : "r" (&p_lock->lock) : "memory"); +} + + +#else /*!(__sparc__)*/ + +__attribute__((unused)) +static uint32_t spin_lock_save_irq() +{ + return 0; +} + +__attribute__((unused)) +static void spin_lock_restore_irq(__attribute__((unused)) uint32_t psr) +{ +} + +#if (__unused__) +__attribute__((unused)) +static void spin_lock(__attribute__((unused)) struct spinlock *p_lock) +{ +} + +__attribute__((unused)) +static void spin_lock_raw(__attribute__((unused)) struct spinlock *p_lock) +{ +} + +__attribute__((unused)) +static int spin_is_locked(__attribute__((unused)) struct spinlock *p_lock) +{ + return 0; +} + +__attribute__((unused)) +static void spin_unlock_wait(__attribute__((unused)) struct spinlock *p_lock) +{ +} + +__attribute__((unused)) +static int spin_try_lock(__attribute__((unused)) struct spinlock *p_lock) +{ + return 0; +} + +__attribute__((unused)) +static void spin_unlock(__attribute__((unused)) struct spinlock *p_lock) +{ +} +#endif /* (__unused__) */ + +#endif /*!(__sparc__)*/ + + +#endif diff --git a/IBSW/include/stacktrace.h b/IBSW/include/stacktrace.h new file mode 100644 index 0000000000000000000000000000000000000000..020bc53f62f9d343b0b559c6a9fcf3f4d64c6b74 --- /dev/null +++ b/IBSW/include/stacktrace.h @@ -0,0 +1,160 @@ +/** + * @file stacktrace.h + * @ingroup stacktrace + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @author Linus Torvalds et al. + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @note The stack tracing was inspired by __save_stack_trace() in + * linux/asm/sparc/kernel/stacktrace.c. Not particular author was given + * in the file, hence the generic credit. + */ + +#ifndef STACKTRACE_H +#define STACKTRACE_H + +#include <stdint.h> + + +/* reg window offset */ +#define RW_L0 0x00 +#define RW_L1 0x04 +#define RW_L2 0x08 +#define RW_L3 0x0c +#define RW_L4 0x10 +#define RW_L5 0x14 +#define RW_L6 0x18 +#define RW_L7 0x1c +#define RW_I0 0x20 +#define RW_I1 0x24 +#define RW_I2 0x28 +#define RW_I3 0x2c +#define RW_I4 0x30 +#define RW_I5 0x34 +#define RW_I6 0x38 +#define RW_I7 0x3c + +/* stack frame offsets */ +#define SF_L0 0x00 +#define SF_L1 0x04 +#define SF_L2 0x08 +#define SF_L3 0x0c +#define SF_L4 0x10 +#define SF_L5 0x14 +#define SF_L6 0x18 +#define SF_L7 0x1c +#define SF_I0 0x20 +#define SF_I1 0x24 +#define SF_I2 0x28 +#define SF_I3 0x2c +#define SF_I4 0x30 +#define SF_I5 0x34 +#define SF_FP 0x38 +#define SF_PC 0x3c +#define SF_RETP 0x40 +#define SF_XARG0 0x44 +#define SF_XARG1 0x48 +#define SF_XARG2 0x4c +#define SF_XARG3 0x50 +#define SF_XARG4 0x54 +#define SF_XARG5 0x58 +#define SF_XXARG 0x5c + + + +#define UREG_G0 0 +#define UREG_G1 1 +#define UREG_G2 2 +#define UREG_G3 3 +#define UREG_G4 4 +#define UREG_G5 5 +#define UREG_G6 6 +#define UREG_G7 7 +#define UREG_I0 8 +#define UREG_I1 9 +#define UREG_I2 10 +#define UREG_I3 11 +#define UREG_I4 12 +#define UREG_I5 13 +#define UREG_I6 14 +#define UREG_I7 15 +#define UREG_FP UREG_I6 +#define UREG_RETPC UREG_I7 + + + +/* These for pt_regs32. */ +#define PT_PSR 0x0 +#define PT_PC 0x4 +#define PT_NPC 0x8 +#define PT_Y 0xc +#define PT_G0 0x10 +#define PT_WIM PT_G0 +#define PT_G1 0x14 +#define PT_G2 0x18 +#define PT_G3 0x1c +#define PT_G4 0x20 +#define PT_G5 0x24 +#define PT_G6 0x28 +#define PT_G7 0x2c +#define PT_I0 0x30 +#define PT_I1 0x34 +#define PT_I2 0x38 +#define PT_I3 0x3c +#define PT_I4 0x40 +#define PT_I5 0x44 +#define PT_I6 0x48 +#define PT_FP PT_I6 +#define PT_I7 0x4c + + + +/* modified from linux/arch/sparc */ +struct pt_regs { + uint32_t psr; + uint32_t pc; + uint32_t npc; + uint32_t y; + uint32_t u_regs[16]; /* globals and ins */ +}; + +struct leon_reg_win { + uint32_t locals[8]; + uint32_t ins[8]; +}; + +/* a stack frame */ +struct sparc_stackf { + uint32_t locals[8]; + uint32_t ins[6]; + struct sparc_stackf *fp; /* %i6 = %fp */ + uint32_t callers_pc; /* %i7 = ret %pc */ + uint8_t *structptr; + uint32_t xargs[6]; + uint32_t xxargs[1]; +}; + +struct stack_trace { + uint32_t nr_entries; + uint32_t max_entries; + uint32_t *entries; +}; + + + +void save_stack_trace(struct stack_trace *trace, uint32_t sp, uint32_t pc); + +/* part of libgloss */ +void __flush_windows(void); + +#endif diff --git a/IBSW/include/syncpulse.h b/IBSW/include/syncpulse.h new file mode 100644 index 0000000000000000000000000000000000000000..3ca2a6646e1b81e886b84ac0c625b681fe5a6215 --- /dev/null +++ b/IBSW/include/syncpulse.h @@ -0,0 +1,42 @@ +/** + * @file syncpulse.h + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef SYNCPULSE_H +#define SYNCPULSE_H + + +#include <timing.h> + + + +void syncpulse_configure_gpio(uint32_t port, uint32_t gpio_base_addr); + +void syncpulse_status_set_callback(struct time_keeper *time, + void (*sync_status)(uint32_t sync)); + +int32_t syncpulse_notification_timer_underflow(void *userdata); +int32_t syncpulse_missed(void *userdata); +int32_t syncpulse(void *userdata); + +void syncpulse_enable_spw_tick(struct time_keeper *time); +void syncpulse_disable_spw_tick(struct time_keeper *time); +void syncpulse_spw_get_next_time(struct time_keeper *time, + uint32_t *coarse_time, + uint32_t *fine_time); + +#endif /* SYNCPULSE_H */ diff --git a/IBSW/include/sysctl.h b/IBSW/include/sysctl.h new file mode 100644 index 0000000000000000000000000000000000000000..15b476112d5cc5c238ca2c23b84d7aa5c67b923c --- /dev/null +++ b/IBSW/include/sysctl.h @@ -0,0 +1,84 @@ +#ifndef SYSOBJ_H +#define SYSOBJ_H + +#include <sys/types.h> +#include <list.h> + +#ifdef offsetof +#undef offsetof +#endif +/* linux/stddef.h */ +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +/* linux/kernel.h */ +#define container_of(ptr, type, member) ({ \ + typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* Indirect stringification. Doing two levels allows the parameter to be a + * macro itself. For example, compile with -DFOO=bar, __stringify(FOO) + * converts to "bar". + */ +__extension__ +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + +/* sysfs.h, modified */ +#define __ATTR(_name, _show, _store) { \ + .name = __stringify(_name), \ + .show = _show, \ + .store = _store, \ +} + + + +struct sysobj { + const char *name; + struct list_head entry; + + struct sysobj *parent; + struct sysobj *child; + + struct sysset *sysset; + + struct sobj_attribute **sattr; +}; + +struct sysset { + struct list_head list; + struct sysobj sobj; +}; + + +struct sobj_attribute { + const char *name; + ssize_t (*show) (struct sysobj *sobj, struct sobj_attribute *sattr, char *buf); + ssize_t (*store)(struct sysobj *sobj, struct sobj_attribute *sattr, const char *buf, size_t len); +}; + +extern struct sysset *sys_set; +extern struct sysset *driver_set; + + +struct sysobj *sysobj_create(void); +void sysobj_init(struct sysobj *sobj); +int32_t sysobj_add(struct sysobj *sobj, struct sysobj *parent, + struct sysset *sysset, const char *name); + +struct sysobj *sysobj_create_and_add(const char *name, struct sysobj *parent); + +void sysobj_show_attr(struct sysobj *sobj, const char *name, char *buf); +void sysobj_store_attr(struct sysobj *sobj, const char *name, const char *buf, size_t len); + +struct sysset *sysset_create_and_add(const char *name, + struct sysobj *parent_sobj, + struct sysset *parent_sysset); + +void sysset_show_tree(struct sysset *sysset); +struct sysobj *sysset_find_obj(struct sysset *sysset, const char *path); + + +int32_t sysctl_init(void); + + +#endif diff --git a/IBSW/include/timing.h b/IBSW/include/timing.h new file mode 100644 index 0000000000000000000000000000000000000000..d3b8af87823bbca95c9718b90186f215b60e5b55 --- /dev/null +++ b/IBSW/include/timing.h @@ -0,0 +1,134 @@ +/** + * @file timing.h + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef TIMING_H +#define TIMING_H + +#include <compiler.h> +#include <io.h> +#include <leon/leon_reg.h> +#include <grspw2.h> +#include <core1553brm_as250.h> +#include <leon3_grtimer_longcount.h> + + +/* IASW/IBSW timer configuration below */ + + +#define CPU_CPS 25000000 + +#define GPTIMER_RELOAD 4 +#define GRTIMER_RELOAD 4 /* use 5 instead of 3 cycle minimum for + round number of clock ticks */ +#define GPTIMER_MAX 0xffffffff +#define GRTIMER_MAX 0xffffffff + +#define GPTIMER_TICKS_PER_SEC ((CPU_CPS / (GPTIMER_RELOAD + 1))) +#define GPTIMER_TICKS_PER_MSEC (GPTIMER_TICKS_PER_SEC / 1000) +#define GPTIMER_TICKS_PER_USEC (GPTIMER_TICKS_PER_SEC / 1000000) +#define GPTIMER_USEC_PER_TICK (1000000.0 / GPTIMER_TICKS_PER_SEC) + +#define GRTIMER_TICKS_PER_SEC ((CPU_CPS / (GRTIMER_RELOAD + 1))) +#define GRTIMER_TICKS_PER_MSEC (GRTIMER_TICKS_PER_SEC / 1000) +#define GRTIMER_TICKS_PER_USEC (GRTIMER_TICKS_PER_SEC / 1000000) +#define GRTIMER_USEC_PER_TICK (1000000.0 / GRTIMER_TICKS_PER_SEC) + +#define GPTIMER_CYCLES_PER_SEC CPU_CPS +#define GPTIMER_CYCLES_PER_MSEC (GPTIMER_CYCLES_PER_SEC / 1000) +#define GPTIMER_CYCLES_PER_USEC (GPTIMER_CYCLESS_PER_SEC / 1000000) +#define GPTIMER_USEC_PER_CYCLE (1000000.0 / GPTIMER_CYCLES_PER_SEC) + +#define GRTIMER_CYCLES_PER_SEC CPU_CPS +#define GRTIMER_CYCLES_PER_MSEC (GRTIMER_CYCLES_PER_SEC / 1000) +#define GRTIMER_CYCLES_PER_USEC (GRTIMER_CYCLESS_PER_SEC / 1000000) +#define GRTIMER_SEC_PER_CYCLE ( 1.0 / GRTIMER_CYCLES_PER_SEC) +#define GRTIMER_MSEC_PER_CYCLE ( 1000.0 / GRTIMER_CYCLES_PER_SEC) +#define GRTIMER_USEC_PER_CYCLE (1000000.0 / GRTIMER_CYCLES_PER_SEC) + + + +#define IASW_CPS 8 +#define T_CYC ( 125 * GPTIMER_TICKS_PER_MSEC) /* 125 ms */ +#define T_CYC1 ( 15 * GPTIMER_TICKS_PER_MSEC) /* 15 ms */ +#define T_SYNC_TOL ( 1 * GPTIMER_TICKS_PER_MSEC) /* 1 ms */ +#define T_WATCHDOG (1800 * GPTIMER_TICKS_PER_MSEC) /* 1.8 s */ + + + +struct time_keeper { + + uint32_t mil_cuc_coarse; + uint32_t mil_cuc_fine; + + uint32_t cuc_coarse; + uint32_t cuc_fine; + + uint32_t pulse_desync_cnt; + uint32_t miltime_desync_cnt; + + uint32_t notify_cnt; + + uint32_t tick_in; + + uint32_t watchdog_enabled; + + uint32_t synced; + + uint32_t pulse_missed; + + uint32_t cuc_recv; + + struct grtimer_uptime synctime; + struct gptimer_unit *ptu; + struct grtimer_unit *rtu; + + struct brm_config *brm; + struct grspw2_core_cfg *spw; + + void (*bark)(void); + + void (*signal)(void *userdata); + void *userdata; + + void (*sync_status)(uint32_t sync); +}; + + +void timekeeper_init(struct time_keeper *time, + struct gptimer_unit *ptu, + struct grtimer_unit *rtu, + struct brm_config *brm, + struct grspw2_core_cfg *spw); + +void timekeeper_get_current_time(struct time_keeper *time, + uint32_t *coarse_time, + uint32_t *fine_time); + +void timekeeper_set_1553_time(uint32_t coarse_time, + uint32_t fine_time, + void *userdata); + + +void timekeeper_set_signal_callback(struct time_keeper *time, + void (*signal)(void *userdata), + void *userdata); + +void timekeeper_set_cuc_time(struct time_keeper *time); + + +#endif /* TIMING_H */ diff --git a/IBSW/include/traps.h b/IBSW/include/traps.h new file mode 100644 index 0000000000000000000000000000000000000000..f09700cae68e83fe243dccb2393156ff054550a4 --- /dev/null +++ b/IBSW/include/traps.h @@ -0,0 +1,36 @@ +/** + * @file traps.h + * @ingroup traps + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date February, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + + +#ifndef TRAPS_H +#define TRAPS_H + +#include <stdint.h> + + + + +void trap_handler_install(uint32_t trap, void (*handler)()); + +void data_access_exception_trap(void); +void data_access_exception_trap_ignore(void); + +void floating_point_exception_trap(void); +void reset_trap(void); + +#endif /* TRAPS_H */ diff --git a/IBSW/include/watchdog.h b/IBSW/include/watchdog.h new file mode 100644 index 0000000000000000000000000000000000000000..7cbc80f70b8cb6a28d2cd15bf546d866dabaa27b --- /dev/null +++ b/IBSW/include/watchdog.h @@ -0,0 +1,29 @@ +/** + * @file watchdog.h + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef WATCHDOG_H +#define WATCHDOG_H + +#include <timing.h> + +void watchdog_enable(struct time_keeper *time, void (*shutdown_callback)(void)); +void watchdog_disable(struct time_keeper *time); +void watchdog_feed(struct time_keeper *time); + + +#endif /* WATCHDOG_H */ diff --git a/IBSW/include/wrap_malloc.h b/IBSW/include/wrap_malloc.h new file mode 100644 index 0000000000000000000000000000000000000000..96cef2fd7b1fb14dd69893bbf00750b4f40aa819 --- /dev/null +++ b/IBSW/include/wrap_malloc.h @@ -0,0 +1,105 @@ +/** + * @file wrap_malloc.h + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @note needs linker flags to override: -Wl,--wrap=malloc + */ + +#ifndef WRAP_MALLOC_H +#define WRAP_MALLOC_H + +#include <compiler.h> +#include <stddef.h> +#include <stdint.h> + + +#define SRAM1_ADDR 0x40000000UL /* regular SRAM on dpu */ +#define SRAM1_SIZE 0x02000000UL +#define SRAM2_OFF 0x00000000UL /* if SRAM2 should not start at 0 */ +#define SRAM2_ADDR (0x04000000UL + SRAM2_OFF) /* RMW-disabled SRAM */ +#define SRAM2_SIZE (0x01FFFFF0UL - SRAM2_OFF) +#define FPGA_ADDR 0x20000000UL +#define FPGA_SIZE 0x0000FFFFUL + +#define AHBRAM_ADDR 0xA0000000UL +#define AHBRAM_SIZE 0x00030000UL /* 192 kiB */ +#define REG1_ADDR 0x80000000UL +#define REG1_SIZE 0x20000000UL +#define REG2_ADDR 0xFFF00000UL +#define REG2_SIZE 0x000FFFFFUL + +#define FLASH_BLOCKSIZE 1048576 + +/* SRAM 1 memory map */ + +#define SRAM1_DBS_FLASH_BUFFER 0x40080000UL + +/* 10 MiB - 256 kiB for the Software */ +#define SRAM1_DBS_SIZE 0x00480000UL /* 4608 kiB see DPU-SICD-IF-3110 */ +#define SRAM1_SW_SIZE 0x00100000UL /* 1 MiB for software */ +#define SRAM1_CPU_0_STACK_SIZE 0x00020000UL /* 128 kiB */ +#define SRAM1_CPU_1_STACK_SIZE 0x00020000UL /* 128 kiB */ +#define SRAM1_HEAP_SIZE 0x00400000UL /* 4 MiB generic heap for IBSW/IASW */ + +/* 256 kiB + 22 MiB various IASW buffers */ +#define SRAM1_SEMEVTS_SIZE 0x00000000UL /* NOTE: removed in 1.0 */ /* 0x00040000UL 256 kiB for SEM events */ +#define SRAM1_HKSTORE_SIZE 0x00000000UL /* NOTE: removed in 1.0 */ /* 0x00200000UL 2 MiB for HK store */ +#define SRAM1_FLASH_SIZE 0x00420000UL /* 4 MiB + 128 kiB for flash exchange */ +#define SRAM1_AUX_SIZE 0x00420000UL /* 4 MiB + 128 kiB for e.g. Centroiding */ +#define SRAM1_RES_SIZE 0x00800000UL /* 8 MiB reserved (for the GIB) */ +#define SRAM1_SWAP_SIZE 0x00600000UL /* 6 MiB for swap buffers */ + +/* calculate absolute addresses from the sizes defined above */ +#define SRAM1_SW_ADDR (SRAM1_ADDR + SRAM1_DBS_SIZE) +#define SRAM1_CPU_0_STACK_ADDR (SRAM1_SW_ADDR + SRAM1_SW_SIZE) +#define SRAM1_CPU_1_STACK_ADDR (SRAM1_CPU_0_STACK_ADDR + SRAM1_CPU_0_STACK_SIZE) +#define SRAM1_HEAP_ADDR (SRAM1_CPU_1_STACK_ADDR + SRAM1_CPU_1_STACK_SIZE) +#define SRAM1_SEMEVTS_ADDR (SRAM1_HEAP_ADDR + SRAM1_HEAP_SIZE) +#define SRAM1_HKSTORE_ADDR (SRAM1_SEMEVTS_ADDR + SRAM1_SEMEVTS_SIZE) +#define SRAM1_FLASH_ADDR (SRAM1_HKSTORE_ADDR + SRAM1_HKSTORE_SIZE) +#define SRAM1_AUX_ADDR (SRAM1_FLASH_ADDR + SRAM1_FLASH_SIZE) +#define SRAM1_RES_ADDR (SRAM1_AUX_ADDR + SRAM1_AUX_SIZE) +#define SRAM1_SWAP_ADDR (SRAM1_RES_ADDR + SRAM1_RES_SIZE) + +#define SRAM1_END (SRAM1_SWAP_ADDR + SRAM1_SWAP_SIZE) + +/* stack base is at the end of the stack */ +#define SRAM1_CPU_0_STACK_BASE (SRAM1_CPU_0_STACK_ADDR + SRAM1_CPU_0_STACK_SIZE) +#define SRAM1_CPU_1_STACK_BASE (SRAM1_CPU_1_STACK_ADDR + SRAM1_CPU_1_STACK_SIZE) + +/* SRAM 2 memory map */ +#define SRAM2_SDB_ADDR SRAM2_ADDR +#define SRAM2_SDB_SIZE SRAM2_SIZE /* use all of SRAM 2 */ +#define SRAM2_END (SRAM2_SDB_ADDR + SRAM2_SDB_SIZE) + +compile_time_assert((SRAM1_END <= (SRAM1_ADDR + SRAM1_SIZE)), + HEAP1_MEM_OOB); +compile_time_assert((SRAM2_END <= (SRAM2_ADDR + SRAM2_SIZE)), + HEAP2_MEM_OOB); + + +#define MEM_ALIGN 8UL /* align to quadword so stack + space can be allocated by + pthreads */ + + +enum ram_block {DBS, HEAP, SEMEVTS, HKSTORE, FLASH, AUX, RES, SWAP, SDB}; + +int32_t malloc_enable_syscfg(void); + +void *alloc(uint32_t size, enum ram_block ram); +void release(enum ram_block ram); + +#endif diff --git a/IBSW/lib/ahb.c b/IBSW/lib/ahb.c new file mode 100644 index 0000000000000000000000000000000000000000..5895670500d8aec13dbb66a1017d7d3f81419de1 --- /dev/null +++ b/IBSW/lib/ahb.c @@ -0,0 +1,142 @@ +/** + * @file ahb.c + * @ingroup ahb + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date March, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup ahb Advanced High-performance Bus (AHB) + * @brief Access to the AHB registers + * + * + * ## Overview + * + * This components implements functionality to access or modify the AHB status + * registers of the GR712RC. + * + * @see _GR712-UM v2.7 chapter 7_ + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * - functionality will be added as needed + * + */ + +#include <io.h> +#include <ahb.h> +#include <leon_reg.h> + + + +/** + * @brief deassert the new error bit in the AHB status register + * @see GR712-UM v2.3 p. 71 + */ + +void ahbstat_clear_new_error(void) +{ + uint32_t tmp; + + struct leon3_ahbstat_registermap *ahbstat = + (struct leon3_ahbstat_registermap *) LEON3_BASE_ADDRESS_AHBSTAT; + + + tmp = ioread32be(&ahbstat->status); + tmp &= ~AHB_STATUS_NE; + iowrite32be(tmp, &ahbstat->status); +} + + +/** + * @brief retrieve the AHB status register + * + * @return the contents of the AHB status register + * + * @see GR712-UM v2.3 p. 71 + * + */ + +uint32_t ahbstat_get_status(void) +{ + struct leon3_ahbstat_registermap const *ahbstat = + (struct leon3_ahbstat_registermap *) LEON3_BASE_ADDRESS_AHBSTAT; + + + return ioread32be(&ahbstat->status); +} + + +/** + * @brief check the new error bit in the AHB status register + * + * @return not 0 if new error bit is set + * + * @see GR712-UM v2.3 p. 71 + * + */ + +uint32_t ahbstat_new_error(void) +{ + struct leon3_ahbstat_registermap const *ahbstat = + (struct leon3_ahbstat_registermap *) LEON3_BASE_ADDRESS_AHBSTAT; + + + return (ioread32be(&ahbstat->status) & AHB_STATUS_NE); +} + + +/** + * @brief check if the last error reported via the AHB status register is + * correctable + * + * @return not 0 if correctable error bit is set + * + * @see GR712-UM v2.3 p. 71 + * + */ + +uint32_t ahbstat_correctable_error(void) +{ + struct leon3_ahbstat_registermap const *ahbstat = + (struct leon3_ahbstat_registermap *) LEON3_BASE_ADDRESS_AHBSTAT; + + + return (ioread32be(&ahbstat->status) & AHB_STATUS_CE); +} + + +/** + * @brief get the AHB failing address + * + * @return the HADDR signal of the AHB transaction that caused the error + * + * @see GR712-UM v2.3 p. 72 + * + */ + +uint32_t ahbstat_get_failing_addr(void) +{ + struct leon3_ahbstat_registermap const *ahbstat = + (struct leon3_ahbstat_registermap *) LEON3_BASE_ADDRESS_AHBSTAT; + + + return ioread32be(&ahbstat->failing_address); +} + diff --git a/IBSW/lib/asm/data_access_exception_trap.S b/IBSW/lib/asm/data_access_exception_trap.S new file mode 100644 index 0000000000000000000000000000000000000000..93529106c22ba168dae5ff0fd7b46623fc0c2dec --- /dev/null +++ b/IBSW/lib/asm/data_access_exception_trap.S @@ -0,0 +1,75 @@ +/** + * @file asm/data_access_exception_trap.S + * @ingroup edac + * @brief this is a function that is called by a custom trap handler to handle + * an EDAC error + */ + + + +#define SAVE_ALL_HEAD \ + sethi %hi(leonbare_trapsetup), %l4; \ + jmpl %l4 + %lo(leonbare_trapsetup), %l6; +#define SAVE_ALL \ + SAVE_ALL_HEAD \ + nop; + + +#define FW_REGS_SZ 0x90 /* 36*4 */ +#define SF_REGS_SZ 0x60 /* 24*4 */ + +/* All traps low-level code here must end with this macro. */ +#define RESTORE_ALL b leonbare_trapreturn; clr %l6; + + + + .text + .align 4 + .globl data_access_exception_trap + + + +#define PSR_ET 0x00000020 /* enable traps field */ +#define PSR_PIL_MASK 0x00000F00 /* processor interrupt level */ + +data_access_exception_trap: + + /* Since we do not overwrite values either in RAM or in FLASH, we cannot + * continue from the original instruction or the same trap will occur, + * hence we have to point %pc to %npc and increment %npc to the + * following instruction + */ + + mov %l2, %l1 + add %l2, 4, %l2 + + rd %wim, %l3 /* trap setup needs the %wim in %l3 */ + + SAVE_ALL /* create a trap window */ + + /* re-enable traps but not interrupts (set level to max) */ + or %l0, PSR_PIL_MASK, %o0 + wr %o0, PSR_ET, %psr + nop + nop + nop + + call edac_trap + add %sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1 + + + RESTORE_ALL /* also returns */ + + + + + + .globl data_access_exception_trap_ignore + +data_access_exception_trap_ignore: + + /* see above */ + mov %l2, %l1 + add %l2, 4, %l2 + jmp %l1 + rett %l2 diff --git a/IBSW/lib/asm/floating_point_exception_trap.S b/IBSW/lib/asm/floating_point_exception_trap.S new file mode 100644 index 0000000000000000000000000000000000000000..66b790dc3b20ff9b61c15a3d3e8a88941790aec9 --- /dev/null +++ b/IBSW/lib/asm/floating_point_exception_trap.S @@ -0,0 +1,70 @@ +/** + * @file asm/floating_point_exception_trap.S + * @ingroup edac + * @brief this is a function that is called by a custom trap handler to handle + * a floating point exception + */ + + + +#define SAVE_ALL_HEAD \ + sethi %hi(leonbare_trapsetup), %l4; \ + jmpl %l4 + %lo(leonbare_trapsetup), %l6; +#define SAVE_ALL \ + SAVE_ALL_HEAD \ + nop; + + +#define FW_REGS_SZ 0x90 /* 36*4 */ +#define SF_REGS_SZ 0x60 /* 24*4 */ + +/* All traps low-level code here must end with this macro. */ +#define RESTORE_ALL b leonbare_trapreturn; clr %l6; + + + + .text + .align 4 + .globl floating_point_exception_trap + + + +#define PSR_ET 0x00000020 /* enable traps field */ +#define PSR_PIL_MASK 0x00000F00 /* processor interrupt level */ + +floating_point_exception_trap: + + + mov %l2, %l1 + add %l2, 4, %l2 + + rd %wim, %l3 /* trap setup needs the %wim in %l3 */ + + SAVE_ALL /* create a trap window */ + + /* re-enable traps but not interrupts (set level to max) */ + or %l0, PSR_PIL_MASK, %o0 + wr %o0, PSR_ET, %psr + nop + nop + nop + + call fpe_trap + add %sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1 + + + RESTORE_ALL /* also returns */ + + + + + + .globl floating_point_exception_trap_ignore + +floating_point_exception_trap_ignore: + + /* see above */ + mov %l2, %l1 + add %l2, 4, %l2 + jmp %l1 + rett %l2 diff --git a/IBSW/lib/asm/reset_trap.S b/IBSW/lib/asm/reset_trap.S new file mode 100644 index 0000000000000000000000000000000000000000..764fa68882efaded5ad7e0e3f1918d4289dd2830 --- /dev/null +++ b/IBSW/lib/asm/reset_trap.S @@ -0,0 +1,75 @@ +/** + * @file asm/reset_trap.S + * @ingroup edac + * @brief this is a function that is called by a custom trap handler to handle + * an EDAC error + */ + + + +#define SAVE_ALL_HEAD \ + sethi %hi(leonbare_trapsetup), %l4; \ + jmpl %l4 + %lo(leonbare_trapsetup), %l6; +#define SAVE_ALL \ + SAVE_ALL_HEAD \ + nop; + + +#define FW_REGS_SZ 0x90 /* 36*4 */ +#define SF_REGS_SZ 0x60 /* 24*4 */ + +/* All traps low-level code here must end with this macro. */ +#define RESTORE_ALL b leonbare_trapreturn; clr %l6; + + + + .text + .align 4 + .globl reset_trap + + + +#define PSR_ET 0x00000020 /* enable traps field */ +#define PSR_PIL_MASK 0x00000F00 /* processor interrupt level */ + +reset_trap: + + /* Since we do not overwrite values either in RAM or in FLASH, we cannot + * continue from the original instruction or the same trap will occur, + * hence we have to point %pc to %npc and increment %npc to the + * following instruction + */ + + mov %l2, %l1 + add %l2, 4, %l2 + + rd %wim, %l3 /* trap setup needs the %wim in %l3 */ + + SAVE_ALL /* create a trap window */ + + /* re-enable traps but not interrupts (set level to max) */ + or %l0, PSR_PIL_MASK, %o0 + wr %o0, PSR_ET, %psr + nop + nop + nop + + call reset + add %sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1 + + + RESTORE_ALL /* also returns */ + + + + + + .globl reset_trap_ignore + +reset_trap_ignore: + + /* see above */ + mov %l2, %l1 + add %l2, 4, %l2 + jmp %l1 + rett %l2 diff --git a/IBSW/lib/asm/trace_trap.S b/IBSW/lib/asm/trace_trap.S new file mode 100644 index 0000000000000000000000000000000000000000..373532dd1d7b2bfdc72a197f23a83d6d7a2aa5fc --- /dev/null +++ b/IBSW/lib/asm/trace_trap.S @@ -0,0 +1,33 @@ +/** + * @file asm/trace_trap.S + * @ingroup stack_trace + * @brief this is a function that is called by a custom trap handler to perform + * a backtrace + */ + + .text + .align 4 + .globl trace_trap + +#define PSR_ET 0x00000020 /* enable traps field */ + +trace_trap: + /* re-enable traps */ + rd %psr, %l0 + wr %l0, PSR_ET,%psr + nop + nop + nop + + /* %sp of trapped function */ + mov %fp, %o0 + + /* %pc of trapped function is stored in %l1 */ + mov %l1, %o1 + call trace + nop + call die + nop +/* if we wanted to return from this: */ +# jmp %l1 +# rett %l2 diff --git a/IBSW/lib/circular_buffer16.c b/IBSW/lib/circular_buffer16.c new file mode 100644 index 0000000000000000000000000000000000000000..90689309c2175798b3e989b3f0719720926daed5 --- /dev/null +++ b/IBSW/lib/circular_buffer16.c @@ -0,0 +1,286 @@ +/** + * @file circular_buffer16.c + * @ingroup circular_buffer16 + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2013 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup circular_buffer16 Circular Buffer (16 bit version) + * + * @brief 16 bit data type circular buffer + * + * @note no spinlocks, effectively limited to one producer, one consumer + * + * @note its probably a good idea to rewrite the core functionalities of + * both 16 and 16 bit buffers as typeof() macros and just create wrapper + * for the particular type for easier maintenance + */ + +#include <stdlib.h> +#include <circular_buffer16.h> + +/** + * @name Declare a circular buffer + * @brief Declares a circular buffers and initializes with zeros + * @param p_buf a pointer to a struct circular_buffer structure + * @param p_buffer_start a pointer to a memory pool + * @param buffer_size number of buffer elements + * @param ptDMAchannel2 DMA channel reserved for circular buffer writes + */ + +int32_t cbuf_init16(struct circular_buffer16 *p_buf, + uint16_t *p_buffer_start, + uint32_t buffer_size) +{ + if (p_buf == NULL) + return -1; + + if (p_buffer_start == NULL) + return -1; + + p_buf->p_buf_start = p_buffer_start; + p_buf->num_elem = buffer_size; + p_buf->read_pos = 0; + p_buf->write_pos = 0; + + return 0; +} + +/** + * @brief resets a circular buffer + * @param p_buf a pointer to a struct circular_buffer structure + */ + +void cbuf_reset16(struct circular_buffer16 *p_buf) +{ + p_buf->read_pos = 0; + p_buf->write_pos = 0; +} + +/** + * @name Read from circular buffer + * @brief Reads elements words from a circular buffer to dest + * @param p_buf a pointer to a struct circular_buffer structure + * @param out dest a pointer to the target memory + * @param in elements number of elements to read from the buffer + * + * @returns number of elements read + */ + +uint32_t cbuf_read16(struct circular_buffer16 *p_buf, + uint16_t *dest, + uint32_t elem) +{ + uint32_t i, j; + uint16_t *cbuf_pos; + + + /* check if size of data already written corresponds to the required + * dump size + */ + if (cbuf_get_used16(p_buf) >= elem) { + if ((p_buf->num_elem - p_buf->read_pos) >= elem) { + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + + for (i = 0; i < elem; i++) + *(dest + i) = *((uint16_t *) cbuf_pos + i); + + p_buf->read_pos += i; + + return i; + } + /* else read to the end */ + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + j = p_buf->num_elem - p_buf->read_pos; + + for (i = 0; i < j; i++) + *(dest + i) = *((uint16_t *) cbuf_pos + i); + + cbuf_pos = p_buf->p_buf_start; + + dest += j; + + for (i = 0; i < (elem - j); i++) + *(dest + i) = *((uint16_t *) cbuf_pos + i); + + p_buf->read_pos = i; + + return i+j; + } + + return 0; +} + + +/** + * @name Write to circular buffer + * @brief Writes elements words from src to a circular buffer + * + * @param p_buf a pointer to a struct circular_buffer structure + * @param in dest a pointer to the source memory + * @param in elements number of elements to write to the circular buffer + * + * @returns number of elements written + */ + +uint32_t cbuf_write16(struct circular_buffer16 *p_buf, uint16_t *src, + uint32_t elem) +{ + uint32_t i, j; + uint16_t *cbuf_pos; + + + if (cbuf_get_free16(p_buf) > elem) { + if ((p_buf->num_elem - p_buf->write_pos) >= elem) { + cbuf_pos = p_buf->p_buf_start + p_buf->write_pos; + + for (i = 0; i < elem; i++) + (*((uint16_t *) cbuf_pos + i)) = (*(src + i)); + + p_buf->write_pos += i; + + return i; + } + + cbuf_pos = p_buf->p_buf_start + p_buf->write_pos; + j = p_buf->num_elem - p_buf->write_pos; + + for (i = 0; i < j; i++) + (*((uint16_t *) cbuf_pos + i)) = (*(src + i)); + + cbuf_pos = p_buf->p_buf_start; + + src += j; + + for (i = 0; i < (elem - j); i++) + (*((uint16_t *) cbuf_pos + i)) = (*(src + i)); + + p_buf->write_pos = i; + + return i + j; + } + + return 0; +} + +/** + * @name peek into circular buffer + * @brief Reads elements words from a circular buffer to dest without + * incrementing the read pointer + * @param p_buf a pointer to a struct circular_buffer structure + * @param out dest a pointer to the target memory + * @param in elements number of elements to read from the buffer + * + * @returns number of elements read + */ + +uint32_t cbuf_peek16(struct circular_buffer16 *p_buf, uint16_t *dest, + uint32_t elem) +{ + uint32_t i, j; + uint16_t *cbuf_pos; + + + /* check if size of data already written corresponds to the required + * dump size + */ + if (cbuf_get_used16(p_buf) >= elem) { + if ((p_buf->num_elem - p_buf->read_pos) >= elem) { + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + + for (i = 0; i < elem; i++) + *(dest + i) = *((uint16_t *) cbuf_pos + i); + + return i; + } + /* else read to the end */ + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + j = p_buf->num_elem - p_buf->read_pos; + + for (i = 0; i < j; i++) + *(dest + i) = *((uint16_t *) cbuf_pos + i); + + cbuf_pos = p_buf->p_buf_start; + + dest += j; + + for (i = 0; i < (elem - j); i++) + *(dest + i) = *((uint16_t *) cbuf_pos + i); + + return i + j; + } + + return 0; +} + + + + +/** + * @name Free space in circular buffer + * @brief Returns the free space in a circular buffer + * + * @param p_buf a pointer to a struct circular_buffer structure + * + * @returns number of free elements in the buffer + */ + +uint32_t cbuf_get_free16(struct circular_buffer16 *p_buf) +{ + return p_buf->num_elem - (p_buf->write_pos + + (p_buf->read_pos > p_buf->write_pos) + * p_buf->num_elem + - p_buf->read_pos); +} + +/** + * @name Used space in circular buffer + * @brief Returns the used space in a circular buffer + * + * @param p_buf a pointer to a struct circular_buffer structure + * + * @returns number of used elements in the buffer + */ + +uint32_t cbuf_get_used16(struct circular_buffer16 *p_buf) +{ + return p_buf->num_elem - cbuf_get_free16(p_buf); +} + + +/** + * @name Forward the read position + * @brief Forwards the read position, effectively removing values from + * the "top" + * + * @param p_buf a pointer to a struct circular_buffer structure + * @param in elements number of elements to forward the buffer's read + * position + * + * @returns number of elements forwarded or 0 if the requested jump + * was too far + */ + +uint32_t cbuf_forward16(struct circular_buffer16 *p_buf, uint32_t elem) +{ + if (cbuf_get_used16(p_buf) >= elem) { + if ((p_buf->num_elem - p_buf->read_pos) >= elem) + p_buf->read_pos += elem; + else + p_buf->read_pos += elem - p_buf->num_elem; + + return elem; + } + + return 0; +} diff --git a/IBSW/lib/circular_buffer8.c b/IBSW/lib/circular_buffer8.c new file mode 100644 index 0000000000000000000000000000000000000000..2d6458cb4c3ebbee0dcb23eb31199f8d71fbabdb --- /dev/null +++ b/IBSW/lib/circular_buffer8.c @@ -0,0 +1,286 @@ +/** + * @file circular_buffer8.c + * @ingroup circular_buffer8 + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2013 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @defgroup circular_buffer8 Circular Buffer (8 bit version) + * + * @brief 8 bit data type circular buffer + * + * @note no spinlocks, effectively limited to one producer, one consumer + * + * @note its probably a good idea to rewrite the core functionalities of + * both 8 and 16 bit buffers as typeof() macros and just create wrapper + * for the particular type for easier maintenance + */ + +#include <stdlib.h> +#include <circular_buffer8.h> + +/** + * @name Declare a circular buffer + * @brief Declares a circular buffers and initializes with zeros + * @param p_buf a pointer to a struct circular_buffer structure + * @param p_buffer_start a pointer to a memory pool + * @param buffer_size number of buffer elements + * @param ptDMAchannel2 DMA channel reserved for circular buffer writes + */ + +int32_t cbuf_init8(struct circular_buffer8 *p_buf, + uint8_t *p_buffer_start, + uint32_t buffer_size) +{ + if (p_buf == NULL) + return -1; + + if (p_buffer_start == NULL) + return -1; + + p_buf->p_buf_start = p_buffer_start; + p_buf->num_elem = buffer_size; + p_buf->read_pos = 0; + p_buf->write_pos = 0; + + return 0; +} + +/** + * @brief resets a circular buffer + * @param p_buf a pointer to a struct circular_buffer structure + */ + +void cbuf_reset8(struct circular_buffer8 *p_buf) +{ + p_buf->read_pos = 0; + p_buf->write_pos = 0; +} + +/** + * @name Read from circular buffer + * @brief Reads elements words from a circular buffer to dest + * @param p_buf a pointer to a struct circular_buffer structure + * @param out dest a pointer to the target memory + * @param in elements number of elements to read from the buffer + * + * @returns number of elements read + */ + +uint32_t cbuf_read8(struct circular_buffer8 *p_buf, + uint8_t *dest, + uint32_t elem) +{ + uint32_t i, j; + uint8_t *cbuf_pos; + + + /* check if size of data already written corresponds to the required + * dump size + */ + if (cbuf_get_used8(p_buf) >= elem) { + if ((p_buf->num_elem - p_buf->read_pos) >= elem) { + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + + for (i = 0; i < elem; i++) + *(dest + i) = *((uint8_t *) cbuf_pos + i); + + p_buf->read_pos += i; + + return i; + } + /* else read to the end */ + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + j = p_buf->num_elem - p_buf->read_pos; + + for (i = 0; i < j; i++) + *(dest + i) = *((uint8_t *) cbuf_pos + i); + + cbuf_pos = p_buf->p_buf_start; + + dest += j; + + for (i = 0; i < (elem - j); i++) + *(dest + i) = *((uint8_t *) cbuf_pos + i); + + p_buf->read_pos = i; + + return i+j; + } + + return 0; +} + + +/** + * @name Write to circular buffer + * @brief Writes elements words from src to a circular buffer + * + * @param p_buf a pointer to a struct circular_buffer structure + * @param in dest a pointer to the source memory + * @param in elements number of elements to write to the circular buffer + * + * @returns number of elements written + */ + +uint32_t cbuf_write8(struct circular_buffer8 *p_buf, uint8_t *src, + uint32_t elem) +{ + uint32_t i, j; + uint8_t *cbuf_pos; + + + if (cbuf_get_free8(p_buf) > elem) { + if ((p_buf->num_elem - p_buf->write_pos) >= elem) { + cbuf_pos = p_buf->p_buf_start + p_buf->write_pos; + + for (i = 0; i < elem; i++) + (*((uint8_t *) cbuf_pos + i)) = (*(src + i)); + + p_buf->write_pos += i; + + return i; + } + + cbuf_pos = p_buf->p_buf_start + p_buf->write_pos; + j = p_buf->num_elem - p_buf->write_pos; + + for (i = 0; i < j; i++) + (*((uint8_t *) cbuf_pos + i)) = (*(src + i)); + + cbuf_pos = p_buf->p_buf_start; + + src += j; + + for (i = 0; i < (elem - j); i++) + (*((uint8_t *) cbuf_pos + i)) = (*(src + i)); + + p_buf->write_pos = i; + + return i + j; + } + + return 0; +} + +/** + * @name peek into circular buffer + * @brief Reads elements words from a circular buffer to dest without + * incrementing the read pointer + * @param p_buf a pointer to a struct circular_buffer structure + * @param out dest a pointer to the target memory + * @param in elements number of elements to read from the buffer + * + * @returns number of elements read + */ + +uint32_t cbuf_peek8(struct circular_buffer8 *p_buf, uint8_t *dest, + uint32_t elem) +{ + uint32_t i, j; + uint8_t *cbuf_pos; + + + /* check if size of data already written corresponds to the required + * dump size + */ + if (cbuf_get_used8(p_buf) >= elem) { + if ((p_buf->num_elem - p_buf->read_pos) >= elem) { + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + + for (i = 0; i < elem; i++) + *(dest + i) = *((uint8_t *) cbuf_pos + i); + + return i; + } + /* else read to the end */ + cbuf_pos = p_buf->p_buf_start + p_buf->read_pos; + j = p_buf->num_elem - p_buf->read_pos; + + for (i = 0; i < j; i++) + *(dest + i) = *((uint8_t *) cbuf_pos + i); + + cbuf_pos = p_buf->p_buf_start; + + dest += j; + + for (i = 0; i < (elem - j); i++) + *(dest + i) = *((uint8_t *) cbuf_pos + i); + + return i + j; + } + + return 0; +} + + + + +/** + * @name Free space in circular buffer + * @brief Returns the free space in a circular buffer + * + * @param p_buf a pointer to a struct circular_buffer structure + * + * @returns number of free elements in the buffer + */ + +uint32_t cbuf_get_free8(struct circular_buffer8 *p_buf) +{ + return p_buf->num_elem - (p_buf->write_pos + + (p_buf->read_pos > p_buf->write_pos) + * p_buf->num_elem + - p_buf->read_pos); +} + +/** + * @name Used space in circular buffer + * @brief Returns the used space in a circular buffer + * + * @param p_buf a pointer to a struct circular_buffer structure + * + * @returns number of used elements in the buffer + */ + +uint32_t cbuf_get_used8(struct circular_buffer8 *p_buf) +{ + return p_buf->num_elem - cbuf_get_free8(p_buf); +} + + +/** + * @name Forward the read position + * @brief Forwards the read position, effectively removing values from + * the "top" + * + * @param p_buf a pointer to a struct circular_buffer structure + * @param in elements number of elements to forward the buffer's read + * position + * + * @returns number of elements forwarded or 0 if the requested jump + * was too far + */ + +uint32_t cbuf_forward8(struct circular_buffer8 *p_buf, uint32_t elem) +{ + if (cbuf_get_used8(p_buf) >= elem) { + if ((p_buf->num_elem - p_buf->read_pos) >= elem) + p_buf->read_pos += elem; + else + p_buf->read_pos += elem - p_buf->num_elem; + + return elem; + } + + return 0; +} diff --git a/IBSW/lib/core1553brm_as250.c b/IBSW/lib/core1553brm_as250.c new file mode 100644 index 0000000000000000000000000000000000000000..7bf582497e6cead6f2fec3d2d403dcfeecaee4b2 --- /dev/null +++ b/IBSW/lib/core1553brm_as250.c @@ -0,0 +1,2255 @@ +/** + * @file core1553brm_as250.c + * @ingroup core1553brm_as250 + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief Driver for the MicroSemi Core 1553 BRM implementing the AS250 + * protocol layer + * + * @defgroup core1553brm_as250 Core1553BRM/AS250 device/protocol driver + * + * + * + * ## Overview + * + * This is a driver for the MicroSemi Core1553BRM implementing the + * __AS250 MIL-STD-1553__ Bus Protocol as specified in + * __DIV.SP.00030.T.ASTR__ _Issue 1 Revision 1_, tailored as specified in + * __CHEOPS-ECE-CSW-ICD-049__ _Issue 4.x_. + * + * The AS250 1553 protocol specification is based on the __ECSS-E-ST-50-13C__ + * standard. + * + * The main differences in this protocol variant are: + * + * - twice as many Acquisition Transfer Requests (ATR) are allowed for the + * Remote Terminal (RT) per major frame + * - the doubled ATR rate results in an increased transfer volume of + * 128kbits per second + * - no confirmations of ATRs are written by the Bus Controller + * - the transfer block counter wraps from 255 to 0 instead of 1 + * - a transfer will be accepted as new as long as the block counter differs + * from the previous one + * + * + * ## Mode of Operation + * + * @see _Core1553BRM v4.1 Handbook_ for a description of the hardware + * interface + * + * Since the protocol requires an response to a data write by the + * _Bus Controller_ (the spacecraft) in the next 1553 minor frame, the least + * involved approach is to operate the 1553 core in _ping-pong_ mode. + * This mode is a double-buffering scheme, in which two buffers are assigned + * per RX and TX subaddress. As the core operates, it will use one of the + * buffers for ongoing transfers, while the other is available to the software + * for reading or writing. In the next minor frame, the buffers will be + * switched and so on. + * + * The interaction with the 1553 core is triggered by interrupts that are + * generated by the former based on its subaddress configuration. The attached + * interrupt service routine (ISR) of the driver then inspects the interrupt log + * list of the 1553 core and processes recorded events. If a transfer occured, + * it reads or writes data from/to the subaddress buffers and handles the + * protocol response. Telecommands (_Distribution Data_ or __DD__) written by + * the spacecraft are stored in @ref packet_tracker buffers that are queried by + * the application software. Telemetry data (_Acquisition Data_ or __AD__) are + * extracted from a @ref cpus_buffer that accepts at most 2 kiB of PUS packets + * from the IASW at any given time. + * + * @image html core1553brm_as250/irq_handler.png "Core1553BRM driver ISR" + * + * + * ### Acquisition Packets + * + * The IASW is by design not able to supply prefabricated transfer frames of + * telemetry packets to the driver directly. Instead, it tries to hand off as + * many of packets as possible in one polling cycle. Therefore, the IBSW + * therefore supplies the @ref cpus_buffer that acts as an intermediate to the + * 1553 driver by properly packing TM data into transfer frames that do not + * split PUS packets across a minor frame transfer, as required by the + * communication protocol. + * + * Aquisition Transfers are issued every time TX subaddress (__SA__) 28 is read + * by the Bus Controller. The inactive ping-pong buffer is determined and a + * frame is constructed and loaded into TX subaddresses 11-26, then the block + * counter in the Acquisition Transfer Request message is updated and the latter + * loaded into SA 28. + * + * @startuml {AT_generation.svg} "Acquisition Transfer Generation" width=10 + * + * start + * + * :get last ATR; + * + * :create transfer frame; + * + * if (no packet) then (yes) + * + * while (packet fits?) + * :add packet; + * endwhile + * + * :update block counter; + * + * while (bytes left?) + * :write SA; + * :next SA; + * endwhile + * + * :write ATR; + * + * endif + * stop + * + * @enduml + * + * + * ### Distribution Packets + * + * Telecommand packets written by the Bus Controller are directed into different + * buffers by inspecting their PUS header for their source ID and stored in two + * @ref packet_tracker buffers. This has to be done in the driver, because the + * the IASW cannot determine the source of a packet itself. Instead, it requires + * an interface supplied by the IBSW for each packet sources it allows. + * + * @image html core1553brm_as250/split_packetstreams_direct_buffer_drop.png "Packet redirection into buffers based on ID" + * + * ## Error Handling + * + * Most errors reported by the 1553 core during run time are either non-critical + * or usually non-recoverable. The latter usually result from breakage on the + * physical layer of the 1553 bus, or from severe misconfiguration of the core. + * In either case, no reports on the state of the device can be expected to + * reach the bus controller. + * + * Errors that may have been raised are reported via the event reporting + * interface. If a critical errors warranting a FDIR response occured, an + * optional, user-supplied reset function is called, which can for example + * result in entering safe mode, where there is a chance to handle + * misconfiguration via the boot software. + * + * Errors in the @ref cpus_buffer or @ref packet_tracker are not critical to + * core operation and result in a full reset of the buffers issued by the driver + * itself, accompanied by an error report. + * + * + * ## Notes + * + * The implementation of the protocol in the driver layer was necessitated due + * to the low-frequency polling-style operating of the application software, + * which would have been too slow to operate the exchange by itself. + * A separate dedicated thread was not an option, because of the FIFO + * scheduling policy selected for the IFSW and also the requirement to allow + * packet priorisation within the IASW. + * + * + * + * @example demo1553_as250.c + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <stdint.h> + +#include <errno.h> + +#include <core1553brm_as250.h> +#include <irq.h> +#include <irq_dispatch.h> + +#include <cpus_buffers.h> +#include <packet_tracker.h> + +#include <errors.h> +#include <compiler.h> +#include <io.h> + +#include <event_report.h> +#include <sysctl.h> + + +/* + * NOTE: we assume untranslated addresses for now, so there is no need for + * alternate space loads. This needs to be added if the MMU and/or + * priviledged memory access is going to be used with the driver + */ + + + + + +static struct { + uint32_t rx_bytes; + uint32_t tx_bytes; + uint32_t bytes_dropped; +} brmstat; + +#if (__sparc__) +#define UINT32_T_FORMAT "%lu" +#else +#define UINT32_T_FORMAT "%u" +#endif + +static ssize_t rxtx_show(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + char *buf) +{ + if (!strcmp(sattr->name, "rx_bytes")) + return sprintf(buf, UINT32_T_FORMAT, brmstat.rx_bytes); + + if (!strcmp(sattr->name, "tx_bytes")) + return sprintf(buf, UINT32_T_FORMAT, brmstat.tx_bytes); + + if (!strcmp(sattr->name, "bytes_dropped")) + return sprintf(buf, UINT32_T_FORMAT, brmstat.bytes_dropped); + + return 0; +} + +static ssize_t rxtx_store(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + __attribute__((unused)) const char *buf, + __attribute__((unused)) size_t len) +{ + if (!strcmp(sattr->name, "rx_bytes")) { + brmstat.rx_bytes = 0; + return 0; + } + + if (!strcmp(sattr->name, "tx_bytes")) { + brmstat.tx_bytes = 0; + return 0; + } + + if (!strcmp(sattr->name, "bytes_dropped")) { + brmstat.bytes_dropped = 0; + return 0; + } + + return 0; +} + +__extension__ +static struct sobj_attribute rx_bytes_attr = __ATTR(rx_bytes, + rxtx_show, + rxtx_store); +__extension__ +static struct sobj_attribute tx_bytes_attr = __ATTR(tx_bytes, + rxtx_show, + rxtx_store); +__extension__ +static struct sobj_attribute dropped_bytes_attr = __ATTR(bytes_dropped, + rxtx_show, + rxtx_store); + +__extension__ +static struct sobj_attribute *brm_attributes[] = {&rx_bytes_attr, + &tx_bytes_attr, + &dropped_bytes_attr, + NULL}; + + + + +/** + * @brief central driver error handling + * @param brm a struct brm_config + * @param s the error severity + */ + +static void brm_handle_error(struct brm_config *brm, enum error_severity s) +{ + event_report(CORE1553BRM, s, (uint32_t) errno); + + if (s == HIGH) + if (brm->rt_reset) + brm->rt_reset(brm->rt_reset_userdata); +} + + +/** + * @brief computes the parity bit for the given RT address + * @retval 1 : for multiple-of-two numbers of high bits + * @retval 0 : otherwise + */ + +static uint8_t rt_parity_bit(uint8_t rt_address) +{ + /* 1) make sure only valid RTA bits are selected + * 2) xor upper nibble with lower nibble to eliminate pairs + * 3) take the lower nibble only, it contains all non-pairs in the byte + * 4) determine parity from precalculated bit field suitable for the + * RTPTY flag. For dumbos: + * 1 = 1 bit, 2 = 1 bit, 3 = 2 bits, 4 = 1 bit, 5 = 2 bits etc... + */ + + rt_address &= BRM_RTA_BITS; + rt_address ^= (rt_address >> 4); + rt_address &= 0x0F; + + return ((0x9669 >> rt_address) & 0x1); +} + + +/** + * @brief queries the MSGTO bit to determine whether ping-pong mode is + * disabled or enabled + * @param brm a struct brm_config + * @retval 1 : enabled + * @retval 0 : disabled + */ + +static int32_t brm_pp_enabled(struct brm_config *brm) +{ + return ioread32be(&brm->regs->ctrl) & BRM_CCR_MSGTO; +} + + +/** + * @brief disable ping-pong mode + * @param brm a struct brm_config + * @note success of operation should always be checked via brm_pp_enabled() + * @see Core1553BRM v4.0 Handbook, p.61 + */ + +static void brm_disable_pp(struct brm_config *brm) +{ + uint32_t ctrl; + + ctrl = ioread32be(&brm->regs->ctrl) & ~BRM_CCR_PPEN; + + iowrite32be(ctrl, &brm->regs->ctrl); +} + + +/** + * @brief enable ping-pong mode + * @param brm a struct brm_config + * @note success of operation should always be checked via brm_pp_enabled() + * @see Core1553BRM v4.0 Handbook, p.61 + * + */ + +static void brm_enable_pp(struct brm_config *brm) +{ + uint32_t ctrl; + + ctrl = ioread32be(&brm->regs->ctrl) | BRM_CCR_PPEN; + + iowrite32be(ctrl, &brm->regs->ctrl); +} + + +/** + * @brief gets offset to currently non-active (secondary) ping-pong data buffer + * of a RX subaddress + * @param brm a struct brm_config + * @param sa a subaddress number + * @returns offset into the buffer + */ + +static uint32_t brm_get_offset_pp_rx_prev(struct brm_config *brm, uint32_t sa) +{ + uint32_t offset; + + if (ioread16be(&brm->rt_mem->sa_rx[sa].CW) & BRM_RT_CW_FLAGS_AB) + offset = (uint32_t) ioread16be(&brm->rt_mem->sa_rx[sa].buf_A); + else + offset = (uint32_t) ioread16be(&brm->rt_mem->sa_rx[sa].buf_B); + + + return (offset + BRM_HEADER_WORDS); +} + + +/** + * @brief gets offset to currently non-active (seconardy) ping-pong data buffer + * of a TX subaddress + * @param brm a struct brm_config + * @param sa a subaddress number + * @returns offset into the buffer + * @note this buffer will be read by the core next when it is polled by the bus + * controller + */ + +static uint32_t brm_get_offset_pp_tx_next(struct brm_config *brm, uint32_t sa) +{ + uint32_t offset; + + if (ioread16be(&brm->rt_mem->sa_tx[sa].CW) & BRM_RT_CW_FLAGS_AB) + offset = (uint32_t) ioread16be(&brm->rt_mem->sa_tx[sa].buf_B); + else + offset = (uint32_t) ioread16be(&brm->rt_mem->sa_tx[sa].buf_A); + + return (offset + BRM_HEADER_WORDS); +} + + +/** + * @brief gets offset to currently active (primary) ping-pong data buffer + * of a TX subaddress + * @param brm a struct brm_config + * @param sa a subaddress number + * @returns offset into the buffer + * @note this buffer is currently marked for reading by the core + */ + +static uint32_t brm_get_offset_pp_tx_curr(struct brm_config *brm, uint32_t sa) +{ + uint32_t offset; + + if (ioread16be(&brm->rt_mem->sa_tx[sa].CW) & BRM_RT_CW_FLAGS_AB) + offset = (uint32_t) ioread16be(&brm->rt_mem->sa_tx[sa].buf_A); + else + offset = (uint32_t) ioread16be(&brm->rt_mem->sa_tx[sa].buf_B); + + return (offset + BRM_HEADER_WORDS); +} + + +/* + * @brief gets offset to currently non-active (secondary) ping-pong data buffer + * of a mode code RX subaddress + * @param brm a struct brm_config + * @param sa a subaddress number + * @returns offset into the buffer + */ + +__attribute__((unused)) +static uint32_t brm_get_offset_pp_mc_rx_prev(struct brm_config *brm, + uint32_t sa) +{ + uint32_t offset; + + if (ioread16be(&brm->rt_mem->mc_rx[sa].CW) & BRM_RT_CW_FLAGS_AB) + offset = (uint32_t) ioread16be(&brm->rt_mem->mc_rx[sa].buf_A); + else + offset = (uint32_t) ioread16be(&brm->rt_mem->mc_rx[sa].buf_B); + + + return (offset + BRM_HEADER_WORDS); +} + + +/** + * @brief gets number of data words in a descriptor + * @param brm a struct brm_config + * @param descriptor a descriptor number + * @returns data word count + * @note the Message Information Word and Time Tag entries are not included in + * the count; this is only sensible to use with RX subaddresses; + */ + +static uint32_t brm_get_wordcount(struct brm_config *brm, uint32_t descriptor) +{ + uint32_t wc; + uint32_t offset; + + if (ioread16be(&brm->rt_mem->descriptors[descriptor].CW) & + BRM_RT_CW_FLAGS_AB) + offset = (uint32_t) + ioread16be(&brm->rt_mem->descriptors[descriptor].buf_A); + else + offset = (uint32_t) + ioread16be(&brm->rt_mem->descriptors[descriptor].buf_B); + + + wc = (uint32_t) BRM_DATAWORDCOUNT(BRM_GET_WCMC(brm->brm_mem[offset])); + + return wc; +} + + +/** + * @brief redirects PUS packets into buffers by source ID + * @param brm a struct brm_config + * @param rx_bytes number of bytes in the internal buffer + * @retval 0 : success + * @retval -1 : error + */ + +static int32_t as250_split_packet_stream(struct brm_config *brm, + uint32_t rx_bytes) +{ + int32_t ret; + uint32_t i = 0; + uint32_t bytes; + + struct packet_tracker *p_pkt = NULL; + + while (i < rx_bytes) { + + bytes = (uint32_t) ptrack_get_pkt_size(&brm->buf.adb_ddb[i]); + + if (bytes > (AS250_TRANSFER_FRAME_SIZE-i)) { + /* discard remaining buffer and return */ + errno = E_BRM_INVALID_PKT_SIZE; + return -1; + } + + switch (ptrack_get_next_pkt_src_id(&brm->buf.adb_ddb[i])) { + + case PUS_ID_GND: + p_pkt = brm->buf.pkt_gnd; + break; + + case PUS_ID_OBC: + p_pkt = brm->buf.pkt_obc; + break; + + default: + /* discard remaining buffer and return */ + errno = E_BRM_INVALID_PKT_ID; + return -1; + } + + ret = ptrack_add_single_pkt(p_pkt, &brm->buf.adb_ddb[i], + (rx_bytes-i)); + + if (ret < 0) { + brmstat.bytes_dropped += rx_bytes; + ptrack_reset(p_pkt); /* reset buffers */ + return -1; /* errno set by call to ptrack_add */ + } + + i += (uint32_t) ret; + } + + return 0; +} + + +/** + * @brief handles bus controller access to the AS250 DTD subaddress + * @param brm a struct brm_config + * @retval 0 : success + * @retval -1 : error + * @note ping-pong mode must already be disabled when this function is called + * @note There are unnecessary copy operations when collecting the (packet) + * data. Unfortunately, this is not easily avoided, so we won't try and + * implement a zero-copy approach given the low data rate + */ + +static int32_t as250_handle_dtd_irq(struct brm_config *brm) +{ + + uint32_t i; + uint32_t bytes; + uint32_t rx_bytes_left; + uint32_t offset; + uint32_t rx_bytes = 0; + + struct transfer_descriptor dtd; + + + offset = brm_get_offset_pp_rx_prev(brm, AS250_SA_RX_DTD); + memcpy(&dtd, &brm->brm_mem[offset], AS250_TRANSFER_DESCRIPTOR_SIZE); + + /* MIL-228/T; CIS-SW-ICD-035 & CIS-SW-ICD-036 protocol reset */ + if (unlikely(dtd.reset)) { + brm->as250.dtd_blk_cnt = dtd.block_counter; + + dtd.qos_err = 0x0; /* MIL-228/T */ + dtd.reset = 0x1; /* MIL-228/T */ + + goto send_dtc; + } + + /* variation from MIL-231/T in CIS-SW-ICD-033: + * accept all block counters not identical to the last one as new + */ + if (likely(dtd.block_counter == brm->as250.dtd_blk_cnt)) + return 0; + + brm->as250.dtd_blk_cnt = dtd.block_counter; + + dtd.qos_err = 0x0; /* default: no error detected */ + + rx_bytes_left = dtd.transfer_size; + + for (i = AS250_SA_RX_DDB_01; i <= AS250_SA_RX_DDB_16; i++) { + + if (!rx_bytes_left) + break; + + offset = brm_get_offset_pp_rx_prev(brm, i); + + if (rx_bytes_left > 64) + bytes = 64; + else + bytes = rx_bytes_left; + + memcpy(&brm->buf.adb_ddb[rx_bytes], + &brm->brm_mem[offset], bytes); + + rx_bytes += bytes; + rx_bytes_left -= bytes; + } + + +send_dtc: /* common exit */ + + offset = brm_get_offset_pp_tx_next(brm, AS250_SA_TX_DTC); + + memcpy(&brm->brm_mem[offset], &dtd, AS250_TRANSFER_DESCRIPTOR_SIZE); + + brmstat.rx_bytes += rx_bytes; + + if (as250_split_packet_stream(brm, rx_bytes) < 0) + return -1; /* errno set in call */ + + return 0; +} + + +/** + * @brief writes a protocol reset ATR + * @param brm a struct brm_config + * @retval 0 : success + * @retval 1 : error occured + * + */ + +static uint32_t as250_reset_protocol(struct brm_config *brm) +{ + uint32_t offset; + uint16_t pp_enabled = 0; + + + if (brm_pp_enabled(brm)) { + pp_enabled = 1; + + brm_disable_pp(brm); +#if (__sparc__) /* This is impossible to unit-test as long as we have static + * functions and must include the c file in the unit test file. + * We can also not just remove it, because it is mandated by + * hardware manual, see Core1553BRM v4.0 Handbook, p.61 + */ + + if (brm_pp_enabled(brm)) { + errno = EFAULT; + return 1; + } +#endif + } + + + brm->as250.atr.word0 = 0x0000; + brm->as250.atr.word1 = 0x4000; /* reset = 1 CIS-SW-ICD-036 */ + + brm->as250.atd_blk_cnt = 0x1; + + offset = brm_get_offset_pp_tx_next(brm, AS250_SA_TX_ATR); + memcpy(&brm->brm_mem[offset], &brm->as250.atr, + AS250_TRANSFER_DESCRIPTOR_SIZE); + + offset = brm_get_offset_pp_tx_curr(brm, AS250_SA_TX_ATR); + memcpy(&brm->brm_mem[offset], &brm->as250.atr, + AS250_TRANSFER_DESCRIPTOR_SIZE); + + brm->as250.atr.word0 = 0x0; + brm->as250.atr.word1 = 0x0; + + if (pp_enabled) { + brm_enable_pp(brm); + +#if (__sparc__) /* see above */ + if (!brm_pp_enabled(brm)) { + errno = EFAULT; + return 1; + } +#endif + } + + return 0; +} + + +/** + * @brief creates a AS250 transfer frame + * @param brm a struct brm_config + * @param atr a struct transfer_descriptor + * @retval -1 : error + * @retval 0 : success + */ + +static int32_t as250_create_transfer_frame(struct brm_config *brm, + struct transfer_descriptor *atr) +{ + int32_t ret; + int32_t bytes; + int32_t tx_bytes_left; + + struct cpus_buffers *p_buf; + + + p_buf = brm->buf.atr_cpus; + + tx_bytes_left = AS250_TRANSFER_FRAME_SIZE; + atr->transfer_size = 0; + + while ((bytes = cpus_next_valid_pkt_size(p_buf))) { + + if (unlikely(bytes < 0)) { + /* no point in counting dropped bytes here, as the + * buffer is not valid and it has to be reset as a + * whole + */ + cpus_reset(p_buf); + return -1; /* errno set in call */ + } + + if (bytes > tx_bytes_left) + break; + + ret = cpus_pop_packet(p_buf, + &brm->buf.adb_ddb[atr->transfer_size]); + + if (unlikely(ret < 1)) { + cpus_reset(p_buf); + return -1; /* errno set in call */ + } + + atr->transfer_size += ret; + tx_bytes_left -= ret; + } + + return 0; +} + + +/** + * @brief prepares the AS250 acquisition data buffer + * @param brm a struct brm_config + * @param atr a struct transfer_descriptor + */ + +static void as250_prepare_adb(struct brm_config *brm, + const struct transfer_descriptor *atr) +{ + int32_t bytes; + int32_t tx_bytes_left; + int32_t tx_bytes; + + uint32_t offset; + uint32_t sa = AS250_SA_TX_ADB_01; + + + tx_bytes_left = atr->transfer_size; + tx_bytes = 0; + + /* CIS-SW-ICD-042 + * if data bytes transferred are not a multiple of two, + * there is one padding byte, clear in ADB + */ + if (tx_bytes_left & 0x1) { + tx_bytes_left += 1; + brm->buf.adb_ddb[tx_bytes_left] = 0x0; + } + + do { + if (!tx_bytes_left) + break; + + offset = brm_get_offset_pp_tx_next(brm, sa); + + if (tx_bytes_left >= BRM_NUM_DATABYTES) + bytes = BRM_NUM_DATABYTES; + else + bytes = tx_bytes_left; + + memcpy(&brm->brm_mem[offset], + &brm->buf.adb_ddb[tx_bytes], (size_t) bytes); + + tx_bytes += bytes; + tx_bytes_left -= bytes; + + } while (sa++ < AS250_SA_TX_ADB_16); +} + +/** + * @brief handles bus controller access to the AS250 ATR subaddress + * @param brm a struct brm_config + * @retval -1 : error + * @retval 0 : success + * @note ping-pong mode must already be disabled when this function is called + * @note There are unnecessary copy operations when writing the data. This is + * relatively easy to fix, we just need a partial read-out mechanism + * for the buffers. It is however not an issue given the data rates. + */ + +static int32_t as250_handle_atr_irq(struct brm_config *brm) +{ + int32_t ret; + + uint32_t offset; + + + /* Set the last buffer accessed to the last valid ATR, otherwise the + * BC will consider the toggling block counter as an error because of + * the PP buffers. + */ + offset = brm_get_offset_pp_tx_next(brm, AS250_SA_TX_ATR); + memcpy(&brm->brm_mem[offset], &brm->as250.atr, + AS250_TRANSFER_DESCRIPTOR_SIZE); + + ret = as250_create_transfer_frame(brm, &brm->as250.atr); + if (ret) + return -1; /* errno set in call */ + + if (!brm->as250.atr.transfer_size) + return 0; + + /** + * CIS-SW-ICD-030 + * CIS-SW-ICD-031 + * MIL-224/T: mode = 0 is default + * MIL-223/T: set mode = 0 for SA 11-26 transfers + * qos = 1 verified data length + * + * note: MIL-251 / T states (n+1) modulo 256, but CASA wants wrap to 1 + */ + + /* AS250_USE_COUNTER_AS_SPECIFIED_NOT_AS_INTENDED_BY_CASA */ + brm->as250.atr.word1 = (0x8B00 | brm->as250.atd_blk_cnt++); + + as250_prepare_adb(brm, &brm->as250.atr); + + /* set the ATR */ + offset = brm_get_offset_pp_tx_next(brm, AS250_SA_TX_ATR); + memcpy(&brm->brm_mem[offset], &brm->as250.atr, + AS250_TRANSFER_DESCRIPTOR_SIZE); + + brmstat.tx_bytes += brm->as250.atr.transfer_size; + + return 0; +} + + +/** + * @brief handles bus controller access to the wrap-around subaddress + * @param brm a struct brm_config + */ + +static void as250_handle_wrap_irq(struct brm_config *brm) +{ + uint32_t bytes; + uint32_t offset_rx; + uint32_t offset_tx; + + offset_rx = brm_get_offset_pp_rx_prev(brm, AS250_SA_RX_DWRAP); + offset_tx = brm_get_offset_pp_tx_next(brm, AS250_SA_TX_DWRAP); + + bytes = brm_get_wordcount(brm, AS250_SA_RX_DWRAP) * sizeof(uint16_t); + + memcpy(&brm->brm_mem[offset_tx], &brm->brm_mem[offset_rx], bytes); +} + + +/** + * @brief handles direct time message subaddress access + * @param brm a struct brm_config + */ + +static void as250_handle_time_message_irq(struct brm_config *brm) +{ + uint32_t offset_rx; + struct time_packet time; + + offset_rx = brm_get_offset_pp_rx_prev(brm, AS250_SA_RX_TIME); + + memcpy(&time, &brm->brm_mem[offset_rx], AS250_TIME_PACKET_SIZE); + + if (brm->set_time != NULL) + brm->set_time(time.coarse_time, time.fine_time, + brm->set_time_userdata); +} + + +/** + * @brief sets the first word in the RT_Health subaddress + * @param brm a struct brm_config + * @param mask a bit mask to set + */ + +static void as250_rt_health_set(struct brm_config *brm, uint16_t mask) +{ + uint32_t offset; + + /* must always set both, they are not updated on access */ + offset = (uint32_t) + ioread16be(&brm->rt_mem->sa_tx[AS250_SA_TX_HLTHMON].buf_A); + offset += BRM_HEADER_WORDS; + brm->brm_mem[offset] = mask; + + offset = (uint32_t) + ioread16be(&brm->rt_mem->sa_tx[AS250_SA_TX_HLTHMON].buf_B); + offset += BRM_HEADER_WORDS; + brm->brm_mem[offset] = mask; +} + + +/** + * @brief sets rt_health bits by mask + * @param brm a struct brm_config + * @param mask a mask with bits to toggle set HIGH + */ + +static void as250_rt_health_set_bits(struct brm_config *brm, uint16_t mask) +{ + uint32_t offset; + + /* must always set both, they are not updated on access */ + offset = (uint32_t) + ioread16be(&brm->rt_mem->sa_tx[AS250_SA_TX_HLTHMON].buf_A); + offset += BRM_HEADER_WORDS; + brm->brm_mem[offset] |= mask; + + offset = (uint32_t) + ioread16be(&brm->rt_mem->sa_tx[AS250_SA_TX_HLTHMON].buf_B); + offset += BRM_HEADER_WORDS; + brm->brm_mem[offset] |= mask; +} + + +/** + * @brief unsets rt_health bits by mask + * @param brm a struct brm_config + * @param mask a mask with bits to clear set HIGH + */ + +static void as250_rt_health_unset_bits(struct brm_config *brm, uint16_t mask) +{ + uint32_t offset; + + /* must always set both, they are not updated on access */ + offset = (uint32_t) + ioread16be(&brm->rt_mem->sa_tx[AS250_SA_TX_HLTHMON].buf_A); + offset += BRM_HEADER_WORDS; + brm->brm_mem[offset] &= ~mask; + + offset = (uint32_t) + ioread16be(&brm->rt_mem->sa_tx[AS250_SA_TX_HLTHMON].buf_B); + offset += BRM_HEADER_WORDS; + brm->brm_mem[offset] &= ~mask; +} + + +/** + * @brief handles terminal configuration commands as per MIL-345/T to MIL-350/T + * @param brm a struct brm_config + */ + +static void as250_handle_termcfg(struct brm_config *brm) +{ + uint16_t rt_health_mask; + uint32_t offset; + + /* no need to check for wordcount here */ + offset = brm_get_offset_pp_rx_prev(brm, AS250_SA_RX_TERMCFG); + rt_health_mask = brm->brm_mem[offset]; + + as250_rt_health_unset_bits(brm, rt_health_mask); +} + + +/** + * @brief RX subaddress IRQ handler for AS250 & ping-pong mode + * @param brm a struct brm_config + * @param descriptor a subaddress/mode code descriptor + */ + +static void as250_handle_rx_irq(struct brm_config *brm, uint32_t descriptor) +{ + uint16_t flags; + + switch (BRM_CALC_SA_RX_DESC(descriptor)) { + + case AS250_SA_RX_TERMCFG: + as250_handle_termcfg(brm); + break; + + /* This is another case of the driver acting too fast. It appears that + * in cases where the DTD SA interrupt is raised by the 1553 core and + * the driver deactivates ping-pong mode, a race condition may occur, + * where the buffer A/B bit may have been toggled by the core, but the + * corresponding buffer is not, so the data may end up in the wrong + * buffer and is consequently not read by the driver. + * T̶h̶i̶s̶ ̶i̶s̶ ̶f̶i̶x̶e̶d̶ ̶b̶y̶ ̶c̶h̶a̶n̶g̶i̶n̶g̶ ̶t̶h̶e̶ ̶i̶n̶t̶e̶r̶r̶u̶p̶t̶i̶n̶g̶ ̶s̶u̶b̶a̶d̶d̶r̶e̶s̶s̶ ̶t̶o̶ ̶D̶T̶D̶ + * s̶u̶b̶a̶d̶d̶r̶e̶s̶s̶ ̶1̶6̶.̶ + * ^- This was a misinterpretation of the minor frame SA access scheme + * and has since been reverted to the previous (correct) trigger on + * DTD SA access. + * + * Note that this behaviour is only observed with the CHEOPS spacecraft + * platform simulator and is p̶o̶s̶s̶i̶b̶l̶y̶ definitely related to the + * asynchronous messaging scheme used, as the ADB/DDB SAs are only + * accessed conditionally if the transfer descriptors change and if a + * transfer fits into the data field of a the first subaddress, only + * that particular subaddress is read. This pattern does not continue, + * i.e. all transfers > 64 bytes will be executed as a read of all 16 + * DDB subaddresses. This is most likely the reason why the race + * condition is usually only observed with packets <= 64 bytes. + * + * An optional delay has been added for such transfers. For performance + * reasons, this may be left out once we have final confirmation + * whether the actual spacecraft link will use asynchronous messaging + * the same way the platform simulator does. + * + * milFrameDelay is an external global and its information is defined + * in the data pool. The global is constantly updated by the cyclical + * task. + */ + + case AS250_SA_RX_DTD: + if (as250_handle_dtd_irq(brm) < 0) + brm_handle_error(brm, LOW); + + break; + + case AS250_SA_RX_TIME: + /* CIS-SW-ICD-037 */ + flags = ioread16be(&brm->rt_mem->sa_rx[AS250_SA_RX_TIME].CW) + & BRM_RT_CW_FLAGS_BRD; + + if (!flags) + as250_handle_time_message_irq(brm); + + break; + + case AS250_SA_RX_DWRAP: + as250_handle_wrap_irq(brm); + break; + + default: + break; + } +} + + +/** + * @brief TX subaddress IRQ handler for AS250 & ping-pong mode + * @param brm a struct brm_config + * @param descriptor a subaddress/mode code descriptor + */ + +static void as250_handle_tx_irq(__attribute__((unused)) struct brm_config *brm, + uint32_t descriptor) +{ + switch (BRM_CALC_SA_TX_DESC(descriptor)) { + + case AS250_SA_TX_ATR: + break; + + default: + break; + } +} + +/** + * @brief mode-code RX subaddress IRQ handler for AS250 & ping-pong mode# + * @param brm a struct brm_config + * @param descriptor a subaddress/mode code descriptor + */ + +static void as250_handle_mc_rx_irq(struct brm_config *brm, uint32_t descriptor) +{ + uint16_t frame_num; + + switch (BRM_CALC_MC_RX_DESC(descriptor)) { + + case AS250_MC_RESET_RT: + if (brm->rt_reset) + brm->rt_reset(brm->rt_reset_userdata); + + break; + + case AS250_MC_SYNC_W_DWORD: + frame_num = brm->brm_mem[brm_get_offset_pp_mc_rx_prev(brm, + AS250_MC_SYNC_W_DWORD)]; + if (brm->rt_sync_with_dword) + brm->rt_sync_with_dword(frame_num, + brm->rt_sync_with_dword_userdata); + /* The driver is too fast for the hardware, at least on the GR712RC + * development board. We would overwrite the ADB SA buffers + * before the hardware reads it, because the the ATR SA irq is tripped + * and its handler executed before the 1553 core can ping-pong even + * the first buffer. + * Usually, we would act after the core accesses the last ADB SA, but + * since the PS polls the ADB SAs only on condition a ATR has been set + * (which the real OBC probably won't do), we can't do that and the + * sync-with-dataword modecode is the only other option. + * Note: this occurs only with high transfer rates, i.e. when setting an + * ATR every minor frame + */ + + if (as250_handle_atr_irq(brm) < 0) + brm_handle_error(brm, LOW); + + break; + + default: + break; + } +} + + +/** + * @brief subaddress IRQ handler for ping-pong mode + * @param brm a struct brm_config + * @param descriptor a subaddress/mode code descriptor + * @retval -1 : error + * @retval 0 : success + * @note uses GNU extension: range expression in switch-statement + */ + +extern unsigned int milFrameDelay; + +__extension__ +static int32_t brm_irq_subad_pp(struct brm_config *brm, uint32_t descriptor) +{ + uint16_t cw; + struct brm_descriptor_table *brm_descriptor; + + + brm_descriptor = &brm->rt_mem->descriptors[descriptor]; + + cw = ioread16be(&brm_descriptor->CW); + + if (!(cw & BRM_RT_CW_FLAGS_BAC)) { + errno = E_BRM_CW_BAC_FLAG; + return -1; + } + + /* see as250_handle_rx_irq() */ + /* 4000 amounts to about 160 µs */ + /* yes, this must be volatile */ + { + volatile uint32_t i = 0; + volatile uint32_t EXTRA_DELAY_BEFORE_PP_DISABLE; + + EXTRA_DELAY_BEFORE_PP_DISABLE = milFrameDelay; + + while (i++ < EXTRA_DELAY_BEFORE_PP_DISABLE) + __asm__ __volatile__("nop"); + } + + + brm_disable_pp(brm); + +#if (__sparc__) /* see as250_reset_protocol() for rationale */ + if (brm_pp_enabled(brm)) { + errno = EFAULT; + return -1; + } +#endif + + /* see Core1553BRM v4.0 Handbook, pp.55 for magic numbers */ + switch (descriptor) { + case 1 ... 32: + as250_handle_rx_irq(brm, descriptor); + break; + case 33 ... 64: + as250_handle_tx_irq(brm, descriptor); + break; + case 65 ... 96: + as250_handle_mc_rx_irq(brm, descriptor); + break; + case 97 ... 128: + /* unused (?) */ + /* as250_handle_mc_tx_irq(brm); */ + break; + default: + break; + } + + cw &= ~BRM_RT_CW_FLAGS_BAC; + + iowrite16be(cw, &brm_descriptor->CW); + + brm_enable_pp(brm); + +#if (__sparc__) /* see above */ + if (!brm_pp_enabled(brm)) { + errno = EFAULT; + return -1; + } +#endif + + return 0; +} + + +/** + * @brief checks and handles error flags set in a irq log entry + * @param brm a struct brm_config + * @param BRM_IRQ error flags to check + */ + +__attribute__((noinline)) +static void brm_handle_log_error(struct brm_config *brm, uint16_t BRM_IRQ) +{ + if (BRM_IRQ & BRM_IRQ_RT_ILLCMD) { + errno = E_BRM_IRQ_RT_ILLCMD; + brm_handle_error(brm, MEDIUM); + } + + if (BRM_IRQ & BRM_IRQ_ILLOP) { + errno = E_BRM_IRQ_ILLOP; + brm_handle_error(brm, MEDIUM); + } + + if (BRM_IRQ & BRM_IRQ_MERR) { + errno = E_BRM_IRQ_MERR; + brm_handle_error(brm, MEDIUM); + } +} + + +/** + * @brief checks and handles error flags set in the hw irq register + * @param brm a struct brm_config + * @param BRM_IRQ error flags to check + */ + +__attribute__((noinline)) +static void brm_handle_irq_error(struct brm_config *brm, uint16_t BRM_IRQ) +{ + if (BRM_IRQ & BRM_IRQ_DMAF) { + errno = E_BRM_IRQ_DMAF; + brm_handle_error(brm, HIGH); + } + + if (BRM_IRQ & BRM_IRQ_WRAPF) { + errno = E_BRM_IRQ_WRAPF; + brm_handle_error(brm, HIGH); + } + + if (BRM_IRQ & BRM_IRQ_TAPF) { + errno = E_BRM_IRQ_TAPF; + brm_handle_error(brm, HIGH); + } + + if (BRM_IRQ & BRM_IRQ_BITF) { + errno = E_BRM_IRQ_BITF; + brm_handle_error(brm, HIGH); + } + + if (BRM_IRQ & BRM_IRQ_MERR) { + errno = E_BRM_IRQ_MERR; + brm_handle_error(brm, HIGH); + } + + if (BRM_IRQ & BRM_IRQ_IXEQ0) { + errno = E_BRM_IRQ_IXEQ0; + brm_handle_error(brm, HIGH); + } + + if (BRM_IRQ & BRM_IRQ_RT_ILLCMD) { + errno = E_BRM_IRQ_RT_ILLCMD; + brm_handle_error(brm, HIGH); + } + + if (BRM_IRQ & BRM_IRQ_ILLOP) { + errno = E_BRM_IRQ_ILLOP; + brm_handle_error(brm, HIGH); + } +} + + +/** + * @brief the main IRQ handler + * @param userdata a pointer to arbitrary data + * @retval 0 : always + */ + +__attribute__((unused)) +static int32_t brm_irq_handler(void *userdata) +{ + uint16_t BRM_IRQ; + + uint32_t descriptor; + uint32_t flags; + + int32_t ret; + + static uint32_t pos; + + struct brm_config *brm; + struct brm_irq_log_entry *log; + + + brm = (struct brm_config *) userdata; + log = brm->rt_mem->irq_log; + + while ((BRM_IRQ = ioread16be(&log[pos].IIW)) + != BRM_IIW_PATTERN_INVALID) { + + iowrite16be(BRM_IIW_PATTERN_INVALID, &log[pos].IIW); + + flags = BRM_IRQ_MERR | BRM_IRQ_RT_ILLCMD | BRM_IRQ_ILLOP; + + if (BRM_IRQ & flags) + brm_handle_log_error(brm, BRM_IRQ); + + if (BRM_IRQ & BRM_IRQ_SUBAD) { + /* offset to address */ + descriptor = ioread16be(&log[pos].IAW) >> 2; + + ret = brm_irq_subad_pp(brm, descriptor); + if (ret < 0) + brm_handle_error(brm, MEDIUM); + + } + + BRM_LOGLIST_INCREMENT_READPOS(pos, BRM_IRQ_LOG_ENTRY_PAGES); + } + + + /* handle hardware IRQs (processing cannot be deferred, + * they are not logged) + */ + + BRM_IRQ = ioread16be(&brm->regs->ipend); + + flags = BRM_IRQ_DMAF | BRM_IRQ_WRAPF | BRM_IRQ_TAPF | BRM_IRQ_BITF + | BRM_IRQ_MERR | BRM_IRQ_IXEQ0 | BRM_IRQ_RT_ILLCMD; + + /* this will be called often, so do one quick check and detailed + * ones only if needed + */ + + if (BRM_IRQ & flags) + brm_handle_irq_error(brm, BRM_IRQ); + + return 0; +} + + +/** + * @brief sets the function to call when a time message arrives + * @param brm a struct brm_config + * @param callback a callback function + * @param userdata a pointer to arbitrary data supplied to the callback function + * @retval 0 : success + * @retval -1 : error + */ + +int32_t as250_set_time_callback(struct brm_config *brm, + void (*callback)(uint32_t coarse_time, + uint32_t fine_time, + void *userdata), + void *userdata) +{ + if (!callback) { + errno = EINVAL; + return -1; + } + + brm->set_time = callback; + brm->set_time_userdata = userdata; + + return 0; +} + +/** + * @brief sets the function to call when a Reset RT mode code arrives + * @param brm a struct brm_config + * @param callback a callback function + * @param userdata a pointer to arbitrary data supplied to the callback function + * @retval 0 : success + * @retval -1 : error + */ + +int32_t as250_set_rt_reset_callback(struct brm_config *brm, + void (*callback)(void *userdata), + void *userdata) +{ + if (!callback) { + errno = EINVAL; + return -1; + } + + brm->rt_reset = callback; + brm->rt_reset_userdata = userdata; + + return 0; +} + +/** + * @brief sets the function to call when a Sync With Dataword mode code arrives + * @param brm a struct brm_config + * @param callback a callback function + * @param userdata a pointer to arbitrary data supplied to the callback function + * @retval 0 : success + * @retval -1 : error + */ + +int32_t as250_set_sync_with_dword_callback(struct brm_config *brm, + void (*callback)(uint16_t frame_num, + void *userdata), + void *userdata) +{ + if (callback == NULL) { + errno = EINVAL; + return -1; + } + + brm->rt_sync_with_dword = callback; + brm->rt_sync_with_dword_userdata = userdata; + + return 0; + +} + + +/** + * @brief sets up the ping pong buffers addresses and interrupt flags as + * needed for AS250 + * @param brm a struct brm_config + */ + +static void brm_rt_configure_pp_buffers(struct brm_config *brm) +{ + uint32_t i, j; + uint16_t flags; + + struct brm_message_circular_buffer *msg_buf[4]; + struct brm_descriptor_table *desc[4]; + + + msg_buf[0] = brm->rt_mem->sa_msgs_rx; + msg_buf[1] = brm->rt_mem->sa_msgs_tx; + msg_buf[2] = brm->rt_mem->mc_msgs_rx; + msg_buf[3] = brm->rt_mem->mc_msgs_tx; + + desc[0] = brm->rt_mem->sa_rx; + desc[1] = brm->rt_mem->sa_tx; + desc[2] = brm->rt_mem->mc_rx; + desc[3] = brm->rt_mem->mc_tx; + + + for (i = 0; i < 4; i++) { + for (j = 0; j < BRM_NUM_SUBADDR; j++) { + desc[i][j].buf_A = BASE_ADDR(msg_buf[i][j].page[0]); + + desc[i][j].buf_B = BASE_ADDR(msg_buf[i][j].page[1]); + + desc[i][j].bcast = BASE_ADDR(msg_buf[i][j].page[0]); + } + } + + flags = BRM_RT_CW_FLAGS_IWA | BRM_RT_CW_FLAGS_AB; + + iowrite16be(flags, &brm->rt_mem->sa_rx[AS250_SA_RX_DTD].CW); + iowrite16be(flags, &brm->rt_mem->sa_rx[AS250_SA_RX_TIME].CW); + iowrite16be(flags, &brm->rt_mem->sa_rx[AS250_SA_RX_TERMCFG].CW); + iowrite16be(flags, &brm->rt_mem->sa_rx[AS250_SA_RX_DWRAP].CW); + + iowrite16be(flags, &brm->rt_mem->mc_rx[AS250_MC_SYNC_W_DWORD].CW); + + flags = BRM_RT_CW_FLAGS_AB; + + iowrite16be(flags, &brm->rt_mem->sa_tx[AS250_SA_TX_HLTHMON].CW); + + flags = BRM_RT_CW_FLAGS_IWA | BRM_RT_CW_FLAGS_IBRD | BRM_RT_CW_FLAGS_AB; + iowrite16be(flags, &brm->rt_mem->mc_rx[AS250_MC_RESET_RT].CW); + + + flags = BRM_CCR_BAEN | BRM_CCR_BBEN | BRM_CCR_BCEN + | BRM_CCR_INEN | BRM_CCR_PPEN; + + iowrite32be(flags, &brm->regs->ctrl); +} + + +/** + * @brief sets desynchronized flag in rt_health + * @param brm a struct brm_config + * @note to be called by external timing management + */ + +void as250_desynchronized(struct brm_config *brm) +{ + as250_rt_health_set_bits(brm, AS250_RT_NOT_SYNCHRIONIZED); +} + + +/** + * @brief unsets desynchronized flag in rt_health + * @param brm a struct brm_config + * @note to be called by external timing management + */ + +void as250_synchronized(struct brm_config *brm) +{ + as250_rt_health_unset_bits(brm, AS250_RT_NOT_SYNCHRIONIZED); +} + + +/** + * @brief configures the remote terminal address and parity bit + * @param brm a struct brm_config + * @param rt_address the remote terminal address to set + */ + +static void brm_rt_config_addr(struct brm_config *brm, uint8_t rt_address) +{ + uint32_t flags; + + flags = BRM_CCR_RTA(rt_address) + | (rt_parity_bit(rt_address) << BRM_CCR_RTPTY_REG) + | BRM_OSR_MSEL_RT; + + iowrite32be(flags, &brm->regs->oper); +} + + +/** + * @brief configures the remote terminal's irq mask + * @param brm a struct brm_config + */ + +static void brm_rt_config_irqmask(struct brm_config *brm) +{ + uint32_t flags; + + flags = BRM_IRQ_RT_ILLCMD | BRM_IRQ_SUBAD | BRM_IRQ_TAPF + | BRM_IRQ_DMAF | BRM_IRQ_WRAPF | BRM_IRQ_MERR; + + iowrite32be(flags, &brm->regs->imask); +} + + +/** + * @brief configures descriptor/command block pointer + * @param brm a struct brm_config + */ + +static void brm_setup_desc_pointer(struct brm_config *brm) +{ + /* point to base of memory area */ + iowrite32be(0x0, &brm->regs->dpoint); +} + + +/** + * @brief configures irq log list pointer + * @param brm a struct brm_config + */ + +static void brm_setup_irq_pointer(struct brm_config *brm) +{ + uint32_t addr; + + /* see p78 Core1553BRM Manual */ + addr = BASE_ADDR(brm->rt_mem->irq_log[0]); + + iowrite32be(addr, &brm->regs->ipoint); +} + + +/** + * @brief informs 1553 core about configured core frequency + * @param brm a struct brm_config + * @param core_freq the core frequency to set + * @retval -1 : error + * @retval 0 : success + */ + +static uint32_t brm_setup_core_freq(struct brm_config *brm, uint32_t core_freq) +{ + switch (core_freq) { + case BRM_FREQ_12MHZ: + case BRM_FREQ_16MHZ: + case BRM_FREQ_20MHZ: + case BRM_FREQ_24MHZ: + break; /* all legal */ + default: + errno = E_BRM_INVALID_COREFREQ; + return 1; + } + + iowrite32be(core_freq, &brm->regs->enhanced); + + return 0; +} + + +/** + * @brief sets up hardware and message irq acknowledge + * @param brm a struct brm_config + * @note see GR712UM, p.162 + */ + +static void gr712_setup_1553_intack(struct brm_config *brm) +{ + uint32_t flags; + + flags = IRQ_ACK_MSG | IRQ_ACK_HW; + + iowrite32be(flags, &brm->regs->w_irqctrl); +} + + +/** + * @brief sets up AHB page address register (i.e. 1553 base memory area) + * @param brm a struct brm_config + * @note see GR712UM, p.162 + */ + +static void gr712_setup_1553_ahbaddr(struct brm_config *brm) +{ + uint32_t addr; + + addr = (uint32_t) brm->brm_mem; + + iowrite32be(addr, &brm->regs->w_ahbaddr); +} + +/** + * @brief pulls up sub-system flag bit (toggles bit in 1553 core low), + * @param brm a struct brm_config + * @note see GR172UM, p.162 + */ + +static void gr712_set_ssysfn(struct brm_config *brm) +{ + uint32_t flags; + + flags = ioread32be(&brm->regs->w_ctrl); + flags |= 0x1; + + iowrite32be(flags, &brm->regs->w_ctrl); +} + +#if (__sparc__) +/** + * @brief configures core frequency on GR712RC eval board + * @param brm a struct brm_config + */ + +void gr712_set_core_freq(void) +{ + /* WONTFIX: magic numbers */ + uint32_t *gpreg = (uint32_t *) 0x80000600; + uint32_t reg; + + /* set core frequency to 20 MHz */ + reg = ioread32be(gpreg) | (((2 << 16) | (0 << 14)) & (~(0 << 18))); + + iowrite32be(reg, gpreg); +} +#endif + + +/** + * @brief illegalize all RT commands + * + * @param brm a struct brm_config + */ + +static void brm_rt_illegalize_all(struct brm_config *brm) +{ + uint32_t i; + uint32_t flags; + + + for (i = 0; i < ARRAY_SIZE(brm->regs->rt_cmd_leg); i++) { + BRM_LEG_CMD_ILLEGALIZE_ALL(flags); + iowrite32be(flags, &brm->regs->rt_cmd_leg[i]); + } +} + + +/** + * @brief legalize a RT command + * + * @param brm a struct brm_config + * @param reg the command register offset + * @param cmd the command to legalize + */ + +static void brm_rt_legalize_cmd(struct brm_config *brm, + uint32_t reg, uint32_t cmd) +{ + uint32_t flags; + + flags = ioread32be(&brm->regs->rt_cmd_leg[reg]); + BRM_LEG_CMD_LEGALIZE(flags, cmd); + iowrite32be(flags, &brm->regs->rt_cmd_leg[reg]); +} + + +/** + * @brief legalize a rx subaddress + * + * @param brm a struct brm_config + * @param sa the subaddress to legalize + */ + +static void brm_rt_legalize_sa_rx(struct brm_config *brm, uint32_t sa) +{ + uint32_t reg = BRM_LEG_CMD_SA_RX__0_15; + + if (sa >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_SA_RX_16_31; + sa -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, sa); +} + + +/** + * @brief legalize a tx subaddress + * + * @param brm a struct brm_config + * @param sa the subaddress to legalize + */ + +static void brm_rt_legalize_sa_tx(struct brm_config *brm, uint32_t sa) +{ + uint32_t reg = BRM_LEG_CMD_SA_TX__0_15; + + if (sa >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_SA_TX_16_31; + sa -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, sa); +} + + +/** + * @brief legalize a broadcast rx subaddress + * + * @param brm a struct brm_config + * @param sa the subaddress to legalize + */ + +static void brm_rt_legalize_sa_bc_rx(struct brm_config *brm, uint32_t sa) +{ + uint32_t reg = BRM_LEG_CMD_SA_BC_RX__0_15; + + if (sa >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_SA_BC_RX_16_31; + sa -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, sa); +} + + +/** + * @brief legalize a broadcast tx subaddress + * + * @param brm a struct brm_config + * @param sa the subaddress to legalize + */ + +__attribute__((unused)) +static void brm_rt_legalize_sa_bc_tx(struct brm_config *brm, uint32_t sa) +{ + uint32_t reg = BRM_LEG_CMD_SA_BC_TX__0_15; + + if (sa >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_SA_BC_TX_16_31; + sa -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, sa); +} + + +/** + * @brief legalize a rx mode code + * + * @param brm a struct brm_config + * @param mc the mode code to legalize + */ + +static void brm_rt_legalize_mc_rx(struct brm_config *brm, uint32_t mc) +{ + uint32_t reg = BRM_LEG_CMD_MC_RX__0_15; + + if (mc >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_MC_RX_16_31; + mc -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, mc); +} + + +/** + * @brief legalize a tx mode code + * + * @param brm a struct brm_config + * @param mc the mode code to legalize + */ + +__attribute__((unused)) +static void brm_rt_legalize_mc_tx(struct brm_config *brm, uint32_t mc) +{ + uint32_t reg = BRM_LEG_CMD_MC_TX__0_15; + + if (mc >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_MC_TX_16_31; + mc -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, mc); +} + + +/** + * @brief legalize a broadcast rx mode code + * + * @param brm a struct brm_config + * @param mc the mode code to legalize + */ + +static void brm_rt_legalize_bc_mc_rx(struct brm_config *brm, uint32_t mc) +{ + uint32_t reg = BRM_LEG_CMD_MC_BC_RX__0_15; + + if (mc >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_MC_BC_RX_16_31; + mc -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, mc); +} + + +/** + * @brief legalize a broadcast tx mode code + * + * @param brm a struct brm_config + * @param mc the mode code to legalize + */ + +__attribute__((unused)) +static void brm_rt_legalize_bc_mc_tx(struct brm_config *brm, uint32_t mc) +{ + uint32_t reg = BRM_LEG_CMD_MC_BC_TX__0_15; + + if (mc >= BMR_LEG_CMDS_PER_REGISTER) { + reg = BRM_LEG_CMD_MC_BC_TX_16_31; + mc -= BMR_LEG_CMDS_PER_REGISTER; + } + + brm_rt_legalize_cmd(brm, reg, mc); +} + + +/** + * @brief sets up legal RT commands + * @param brm a struct brm_config + * @note see Core1553BRM v4.0 Handbook, pp.83 + * + * @note uses GNU extension: binary constants + */ + +__extension__ +static void brm_rt_legalize_as250_commands(struct brm_config *brm) +{ + brm_rt_illegalize_all(brm); + + /* subaddresses according to table 6.7-1 in DIV.SP.00030.T.ASTR */ + + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_TERMCFG); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_01); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_02); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_03); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_04); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_05); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_06); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_07); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_08); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_09); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_10); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_11); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_12); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_13); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_14); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_15); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DDB_16); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DTD); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_TIME); + brm_rt_legalize_sa_rx(brm, AS250_SA_RX_DWRAP); + + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_HLTHMON); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_01); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_02); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_03); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_04); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_05); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_06); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_07); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_08); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_09); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_10); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_11); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_12); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_13); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_14); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_15); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ADB_16); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_DTC); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_ATR); + brm_rt_legalize_sa_tx(brm, AS250_SA_TX_DWRAP); + + brm_rt_legalize_sa_bc_rx(brm, AS250_SA_RX_TIME); + + /* mandatory mode codes according to table 6.3-1 in + * DIV.SP.00030.T.ASTR + */ + + + brm_rt_legalize_mc_rx(brm, BRM_MC_TRANSMIT_STATUS_WORD); + brm_rt_legalize_mc_rx(brm, BRM_MC_TRANSMITTER_SHUTDOWN); + brm_rt_legalize_mc_rx(brm, BRM_MC_OVERRIDE_TRANSMITTER_SHUTDOWN); + brm_rt_legalize_mc_rx(brm, BRM_MC_RESET_REMOTE_TERMINAL); + + /* UVIE bus controller emulation has a broadcast address issue, this may + * be driver related + */ + brm_rt_legalize_mc_rx(brm, BRM_MC_SYNCHRONIZE_WITH_DATA_WORD); + + /* sync with dataword marks the start of a frame, see CIS-SW-ICD-032 + * in CHEOPS-ECE-CSW-ICD-049 + */ + brm_rt_legalize_bc_mc_rx(brm, BRM_MC_SYNCHRONIZE_WITH_DATA_WORD); +} + + +/** + * @brief clears RT irq log + * @param brm a struct brm_config + */ + +static void brm_rt_clear_irq_log(struct brm_config *brm) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(brm->rt_mem->irq_log); i++) { + iowrite16be(BRM_IIW_PATTERN_INVALID, + &brm->rt_mem->irq_log[i].IIW); + iowrite16be(0x0, &brm->rt_mem->irq_log[i].IAW); + } +} + + +/** + * @brief configures the desired RT operating mode + * @param brm a struct brm_config + * @retval 1 : error + * @retval 0 : success + * @note only ping-pong is enabled in this version of the driver + */ + +static uint32_t brm_rt_configure_mode(struct brm_config *brm) +{ + + switch (brm->mode) { + case PING_PONG: + brm_rt_configure_pp_buffers(brm); + break; + default: + errno = EINVAL; + return 1; + } + + return 0; +} + + +/** + * @brief soft-resets remote terminal + * @param brm a struct brm_config + */ + +static void brm_rt_softreset(struct brm_config *brm) +{ + uint32_t flags; + + flags = ioread32be(&brm->regs->ctrl); + flags |= BRM_CCR_SRST; + + iowrite32be(flags, &brm->regs->ctrl); +} + +/** + * @brief starts remote terminal execution + * @param brm a struct brm_config + */ + +static void brm_rt_start(struct brm_config *brm) +{ + uint32_t flags; + + flags = ioread32be(&brm->regs->ctrl); + flags |= BRM_CCR_STEX; + + iowrite32be(flags, &brm->regs->ctrl); +} + + +/** + * @brief points rt memory to allocated brm memory block + * @param brm a struct brm_config + */ + +static void brm_rt_set_mem(struct brm_config *brm) +{ + brm->rt_mem = (void *) brm->brm_mem; +} + + +/** + * @brief intialises remote terminal + * @param brm a struct brm_config + * @param rt_address the address of the remote terminal + * @param core_freq the core frequency to set + * @retval 1 : error + * @retval 0 : success + */ + +uint32_t brm_rt_init(struct brm_config *brm, + uint8_t rt_address, uint32_t core_freq) +{ + __attribute__((unused)) + uint32_t ret; + + + if (brm->buf.adb_ddb == NULL) { + errno = EINVAL; + return 1; + } + + if (brm->buf.atr_cpus == NULL) { + errno = EINVAL; + return 1; + } + + brm_rt_set_mem(brm); + + as250_rt_health_set(brm, 0x0); + + brm_rt_softreset(brm); + + gr712_set_ssysfn(brm); + + brm_rt_config_addr(brm, rt_address); + + brm_rt_config_irqmask(brm); + + brm_setup_desc_pointer(brm); + + brm_setup_irq_pointer(brm); + + if (brm_setup_core_freq(brm, core_freq)) + return 1; /* errno set in call */ + + gr712_setup_1553_intack(brm); + + gr712_setup_1553_ahbaddr(brm); + + brm_rt_legalize_as250_commands(brm); + + brm_rt_clear_irq_log(brm); + + if (brm_rt_configure_mode(brm)) + return 1; /* errno set in call */ + + + brm_rt_start(brm); + + as250_rt_health_set_bits(brm, AS250_INITIALIZATION_COMPLETE); + + /** + * CIS-SW-ICD-034 + * issue a protocol reset immediately at startup + */ + + ret = as250_reset_protocol(brm); +#if (__sparc__) /* return value of failed brm_pp_enabled, cannot be tested + * see as250_reset_protocol() for rationale + */ + if (ret) + return ret; +#endif + + return 0; +} + + +/** + * @brief set the 1kib working buffer + * @param brm a struct brm_config + * @param p_buf the buffer to assign + * @retval -1 : error + * @retval 0 : success + */ + +int32_t brm_set_adb_ddb_buffer(struct brm_config *brm, uint8_t *p_buf) +{ + if (p_buf != NULL) { + brm->buf.adb_ddb = p_buf; + } else { + errno = EINVAL; + return -1; + } + + return 0; +} + +/** + * @brief set the packet tracker for OBC packets + * @param brm a struct brm_config + * @param packet_tracker a struct packet_tracker + * @retval -1 : error + * @retval 0 : success + */ + +int32_t brm_set_packet_tracker_obc(struct brm_config *brm, + struct packet_tracker *pkt_obc) +{ + if (pkt_obc != NULL) { + brm->buf.pkt_obc = pkt_obc; + } else { + errno = EINVAL; + return -1; + } + + return 0; +} + +/** + * @brief sets the packet tracker for GND packets + * @param brm a struct brm_config + * @param packet_tracker a struct packet_tracker + * @retval -1 : error + * @retval 0 : success + */ + +int32_t brm_set_packet_tracker_gnd(struct brm_config *brm, + struct packet_tracker *pkt_gnd) +{ + if (pkt_gnd != NULL) { + brm->buf.pkt_gnd = pkt_gnd; + } else { + errno = EINVAL; + return -1; + } + + return 0; +} + +/** + * @brief sets the sliding window circular PUS packet buffer + * @param brm a struct brm_config + * @param p_cpus a strct cpus_buffers + * @retval -1 : error + * @retval 0 : success + */ + +int32_t as250_set_atr_cpus_buffers(struct brm_config *brm, + struct cpus_buffers *p_cpus) +{ + if (p_cpus != NULL) { + brm->buf.atr_cpus = p_cpus; + } else { + errno = EINVAL; + return -1; + } + + return 0; +} + + + +/** + * @brief enables Core1553BRM + * @param brm a struct brm_config + * @retval -1 : error + * @retval 0 : success + */ + +int32_t brm_1553_enable(struct brm_config *brm) +{ + struct sysobj *sobj; +#if (__sparc__) + /** + * Basic Moron Protector (BMP)™ + * (assume single device, ignore error case) + */ + static enum {DISABLED, ENABLED} brm1553; + + + if (brm1553) + return -1; + + brm1553 = ENABLED; +#endif + if (!brm->regs) { + errno = EINVAL; + return -1; + } + + if (!brm->brm_mem) { + errno = EINVAL; + return -1; + } + + + if (((uint32_t) brm->brm_mem) & BRM_MEM_BLOCK_ALIGN) { + errno = E_BRM_MEM_ADDR_ALIGN; + return -1; + } + + /* explicitly set them null in case the user forgot + * to zero brm_config + */ + brm->set_time = NULL; + brm->rt_reset = NULL; + brm->rt_sync_with_dword = NULL; + + + + + sobj = sysobj_create(); + + if (!sobj) + return -1; + + sobj->sattr = brm_attributes; + + sysobj_add(sobj, NULL, driver_set, "1553"); + + +#if (__sparc__) + irq_dispatch_enable(); + + irl1_register_callback(GR712_IRL1_B1553BRM, PRIORITY_NOW, + &brm_irq_handler, (void *) brm); +#endif + return 0; +} diff --git a/IBSW/lib/cpus_buffer.c b/IBSW/lib/cpus_buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..10b3e42891dcd577dd247ed4e2c7ce4df58b01b2 --- /dev/null +++ b/IBSW/lib/cpus_buffer.c @@ -0,0 +1,603 @@ +/** + * @file cpus_buffer.c + * @ingroup cpus_buffer + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date June, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * + * @defgroup cpus_buffer Circular Sliding Window Buffer + * + * @brief a sliding window buffer for AS250 PUS input packets + * + * + * ## Overview + * + * This module implements functionality to create 1kiB sized frames from + * supplied packets for use with the @ref core1553brm_as250 in order to provide + * a "bandwidth limiting" function to the application software. + * + * + * ## Mode of Operation + * + * ### Buffer Model + * + * The sliding window buffer is implemented using 3 circular buffers: + * one to hold the actual packet data (__Packet__, __[P]__), one to hold the + * size of the next packet (__Size__, __[S]__) and one to set whether the next + * packet is an actual packet or just there for padding a frame to the next + * 1024 byte boundary (__Validity__, __[V]__). + * + * While it may at first glance appear as an issue, the problem of synchronicity + * between the buffers becomes trivial if one considers that the [S] + * buffer as a meta-buffer of the [P] and [V] buffers, as [S] is only written + * after [P] and [V] which in turn are only read after the corresponding + * contents of [S] appear to the reader. + * + * + * @startuml "[S] is a metabuffer \"containing\" [P] and [V]" width=5 + * node "[S]" { + * node "[V]" { + * } + * node "[P]" { + * } + * } + * @enduml + * + * For the @ref circular_buffer16 it is established, that a single + * producer/consumer use of a circular buffer does not necessitate locks, + * it is obvious why there will be no desynchronisation as long as all + * components work correctly and in the right order. The critical section is + * in the access to buffer [S], in particular the read and write pointers of + * the circular buffer, which are however only ever written to by the reader and + * writer respectively and conversely only read by the other, which makes it to + * be not critical at all. + * + * @startuml{valid_packet_exchange.svg} "Example: valid packet exchange" width=10 + * participant Writer + * database Packet + * database Validity + * database Size + * participant Reader + * control "No Action" + * + * Writer -> Packet : put packet + * activate Packet + * + * Reader <-- Size : get packet size + * "No Action" <-- Reader : not ready + * + * Packet -> Validity : put validity + * activate Validity + * + * Reader <-- Size : get packet size + * "No Action" <-- Reader : not ready + * + * Validity -> Size : put size + * activate Size + * + * Reader <-- Size : get packet size + * Reader --> Packet : fetch + * Packet -> Validity : pop packet + * Validity -> Size : pop validity + * Size -> Reader : pop size + * @enduml + * + * + * + * ### ECSS-E-ST-50-13C/AS250 Transfer frame shaping + * The communication scheme used with @ref core1553brm_as250 allows at most + * 1 kiB of telecommand packet data in each 1553 minor frame. Therefore, if a + * packet is added to a buffer, that would make the current fill level exceed + * 1024 bytes, the remaining bytes to the 1024 byte boundary are marked and the + * packet is placed in the following 1025-2048 byte sized segment, thereby + * starting a new transfer frame segment. If a packet exceeds 1024 bytes or + * would fill the buffer beyond the 2048 byte limit, it is refused. + * + * @image html cpus_buffer/sliding_window_buffer.png "Sliding Window Buffer" + * + * + * ### Transfer Frame Size + * + * The legal transfer frame size is limited to 1 kiB of unsegemented PUS packet + * data. The sliding window buffer will fill at most 2 such frames. To query the + * remaining capacity of the current reference frame, cpus_get_free() may be + * called. + * + * @image html cpus_buffer/cpus_get_free.png "Remaining Frame Size" + * + * + * ### Buffer Read/Write Sequences in Detail + * + * + * + * Below are the sequences how the different buffers are written and read. + * + * + @verbatim + push pop + + valid [P]->[V]->[S] [P]->[V]->[S] [1] + + invalid [P]->[S]->[V] [S]->[P]->[V] + @endverbatim + * [1] Note: [S] is read first, but not removed from the buffer until the packet + * is extracted + * + * + * A packet push will hence consist of the following two possible sequences: + * + * + * push invalid -> write valid + * or + * [P]->[S]->[V] : [P]->[V]->[S] + * + * and + * write valid + * or + * [P]->[V]->[S] + * + * which is obviously only a subset of the first sequence. + * + * + * A packet pop will again consist of two possible sequences: + * + * pop invalid -> read valid + * or: + * [S]->[P]->[V] : [P]->[V]->[S] + * + * and + * + * read valid + * or: + * [P]->[V]->[S] + * + * which again is a subset of the first sequence. + * + * + * Since we can ignore the case where the reader is interrupted, we only have to + * look at the (longest possible) write sequence: + * + * + * + @verbatim + W: [S]->[P]->[V]:[P]->[V]->[S] + ---------------------------------------- + R: | | | | | | + | | | | | -> pop invalid -> (no) -> next valid (yes) -> get size -> read + | | | | | + | | | | -> pop invalid -> (no) -> next valid -> (yes) -> get size -> (no) + | | | | + | | | - > pop invalid -> (no) \ + | | | \ + | | -> pop invalid -> (yes) -> next valid -> (no) + | | + | | + | v + | + -> pop invalid -> (no) -> next valid -> (no) + @endverbatim + * + * + * ## PROMELA Model + * + * @verbinclude sliding_window.pml + * + * + * ## Notes + * + * If these buffers need to be accessible from multiple readers/writers, + * locks must be implement to ensure atomicity. + * + * This could have been implemented more efficiently with a + * circular buffer that adds packet information in a custom header per entry, + * but would of course have required extra effort in creating such a buffer. + * Given that the performance overhead is negligible for this particular + * application, this is not necessary. + * A more sensible approach would be to build the transfer frames in the + * application software by concatenating packets into 1024 byte sized + * buffers and handing them over to the driver. The packing could be done + * in a flat buffer and a few lines of code. Now we have effectively >1000 + * sloc (including the circular buffer implementation) and twice the number of + * memory accesses for performing the same task. + */ + + +#include <compiler.h> +#include <errors.h> +#include <cpus_buffers.h> + +#include <stdlib.h> + + + +/** + * @brief forwards the write position without adding elements, effectively + * creating an undefined segment + * @note this is an extension to the circular buffer handling functions + * @param p_buf a struct circular_buffer + * @param elem the number of elements to forward the buffer's + * write position + * @retval -1 : error + * @retval 0 : success + */ + +static int32_t cbuf_forward_write8(struct circular_buffer8 *p_buf, + const uint32_t elem) +{ + if (cbuf_get_free8(p_buf) < elem) { + errno = E_CPUS_FORWARD_WRITE; + return -1; + } + + if ((p_buf->num_elem - p_buf->write_pos) >= elem) + p_buf->write_pos += elem; + else + p_buf->write_pos += elem - p_buf->num_elem; + + return 0; +} + + +/** + * @brief add an invalid padding entry to the buffer + * + * @param cpus a struct cpus_buffers + * @param size the size of the padding + * @retval -1 : error + * @retval 0 : success + */ + +static int32_t cpus_push_invalid(struct cpus_buffers *cpus, uint16_t size) +{ + uint8_t invalid_pattern = CBUF_PUS_INVALID; + + + if (cbuf_forward_write8(&(cpus->pus_pkts), (uint32_t) size)) + return -1; /* errno set in call */ + + if (!cbuf_write16(&(cpus->pus_size), &size, 1)) { + /* no data written (this is critical as buffers + * are now out of sync) + */ + errno = E_CPUS_SIZE_WRITE; + return -1; + } + + if (!cbuf_write8(&(cpus->pus_valid), &invalid_pattern, 1)) { + /* no data written (this is critical as buffers + * are now out of sync) + */ + errno = E_CPUS_PATTERN_WRITE; + return -1; + } + + return 0; +} + + +/** + * @brief check if the next packet in the buffer is a vaild one + * + * @param cpus a struct cpus_buffers + * @retval 1 : valid + * @retval 0 : invalid/empty + */ + +static int32_t cpus_next_is_valid(struct cpus_buffers *cpus) +{ + uint8_t pattern; + + if (!cbuf_peek8(&(cpus->pus_valid), &pattern, 1)) + return 0; /* empty buffer == invalid */ + + if (pattern == CBUF_PUS_VALID) + return 1; + + return 0; +} + +/** + * @brief try to pop the next invalid entry from the buffer + * + * @param cpus a struct cpus_buffers + * @retval -1 : error + * @retval 0 : success + */ + +static int32_t cpus_pop_invalid(struct cpus_buffers *cpus) +{ + uint16_t size; + + if (cpus_next_is_valid(cpus)) + return 0; + + if (!cbuf_read16(&(cpus->pus_size), &size, 1)) + return -1; /* no data in buffer, not critical */ + + /* NOTE: there is no no error checking performed in these functions, + * if we want to detect more desync errors, we have to add them there + */ + + cbuf_forward8(&(cpus->pus_pkts), (uint32_t) size); + cbuf_forward8(&(cpus->pus_valid), 1); + + return 0; +} + +/** + * @brief try to read a valid packet from the buffer + * + * @param cpus a struct cpus_buffers + * @param pus_pkt a buffer to store the packet into + * @retval >0 : packet size + * @retval -1 : error + * @retval 0 : success + */ + +static int32_t cpus_read(struct cpus_buffers *cpus, uint8_t *pus_pkt) +{ + uint16_t size; + uint32_t ret; + + if (!cpus_next_is_valid(cpus)) + return 0; + + /* no size yet */ + if (!cbuf_peek16(&(cpus->pus_size), &size, 1)) + return 0; + + ret = cbuf_read8(&(cpus->pus_pkts), pus_pkt, (uint32_t) size); + + if (ret != (uint32_t) size) { + /* no data in buffer (this is critical as buffers + * are now out of sync) + */ + errno = E_CPUS_PKT_READ; + return -1; + } + + /* NOTE: there is no no error checking performed in these functions, + * if we want to detect more desync errors, we have to add them there + */ + + cbuf_forward8(&(cpus->pus_valid), 1); + cbuf_forward16(&(cpus->pus_size), 1); + + return (int32_t) size; +} + + +/** + * @brief try to write a packet to the buffer + * + * @param cpus a struct cpus_buffers + * @param pus_pkt a buffer to fetch the packet from + * @param size the size of the packet + * @retval -1 : error + * @retval 0 : success + */ + +static int32_t cpus_write(struct cpus_buffers *cpus, + uint8_t *pus_pkt, + uint16_t size) +{ + uint8_t valid_pattern = CBUF_PUS_VALID; + + uint32_t ret; + + + ret = cbuf_write8(&(cpus->pus_pkts), pus_pkt, (uint32_t) size); + + if (ret != size) { + /* no data written (this is NOT critical) */ + errno = E_CPUS_PKT_WRITE; + return -1; + } + + if (!cbuf_write8(&(cpus->pus_valid), &valid_pattern, 1)) { + /* no data written (this is critical as buffers + * are now out of sync) + */ + errno = E_CPUS_PATTERN_WRITE; + return -1; + } + + if (!cbuf_write16(&(cpus->pus_size), &size, 1)) { + /* no data written (this is critical as buffers + * are now out of sync) + */ + errno = E_CPUS_SIZE_WRITE; + return -1; + } + + return 0; +} + + +/** + * @brief sets up the circular buffers to track pus packets + * @note all buffers must be least the defined sizes! + * @param cpus a struct cpus_buffers + * @param p_buf_pkts a 3*1024 byte sized buffer that will hold the pus packets + * @param p_buf_size a 3*1024/12 byte sized buffer that will hold the sizes of + * the pus packets + * @param p_buf_size a 3*1024/12 byte sized buffer that will hold the validity + * flags of the pus packets + */ + +void cpus_init(struct cpus_buffers *cpus, + uint8_t *p_buf_pkts, + uint16_t *p_buf_size, + uint8_t *p_buf_valid) +{ + cbuf_init8(&(cpus->pus_pkts), p_buf_pkts, CBUF_PKTS_ELEM); + cbuf_init8(&(cpus->pus_valid), p_buf_valid, CBUF_VALID_ELEM); + cbuf_init16(&(cpus->pus_size), p_buf_size, CBUF_SIZE_ELEM); +} + + +/** + * @brief resets the cpus buffers + * @param cpus a struct cpus_buffers + */ + +void cpus_reset(struct cpus_buffers *cpus) +{ + cbuf_reset8(&(cpus->pus_pkts)); + cbuf_reset8(&(cpus->pus_valid)); + cbuf_reset16(&(cpus->pus_size)); +} + + +/** + * @brief get free space in cpus buffer + * @param cpus a struct cpus_buffers + * + * @returns free space in bytes + */ + +uint32_t cpus_get_free(struct cpus_buffers *cpus) +{ + uint32_t usage; + + usage = cbuf_get_used8(&(cpus->pus_pkts)); + + if (usage >= AS250_TRANSFER_FRAME_SIZE) + usage = usage - AS250_TRANSFER_FRAME_SIZE; + + if (usage < AS250_TRANSFER_FRAME_SIZE) + usage = AS250_TRANSFER_FRAME_SIZE - usage; + else + usage = 0; + + return usage; +} + +/** + * @brief tries to read a valid packet from the buffer + * @param cpus a struct cpus_buffers + * @note if the next packet is invalid, it is popped from the buffer + * + * @retval >0 : packet size + * @retval 0 : success + */ + +int32_t cpus_pop_packet(struct cpus_buffers *cpus, uint8_t *pus_pkt) +{ + if (cpus_pop_invalid(cpus)) + return 0; + + /* errno/retval set from call */ + return cpus_read(cpus, pus_pkt); +} + + +/** + * @brief try to push a packet into the buffer + * + * @param cpus a struct cpus_buffers + * @param pus_pkt a buffer holding the packet + * @param size the size of the packet + * + * @retval -1 : error + * @retval 0 : success + */ + +int32_t cpus_push_packet(struct cpus_buffers *cpus, + uint8_t *pus_pkt, + uint16_t size) +{ + uint16_t free_bytes; + uint32_t usage; + + + if (size > AS250_TRANSFER_FRAME_SIZE) { + errno = E_CPUS_PKT_SIZE_LIMIT; + return -1; + } + + usage = cbuf_get_used8(&(cpus->pus_pkts)); + + if (usage > (CBUF_PUS_FRAMES * AS250_TRANSFER_FRAME_SIZE)) { + errno = E_CPUS_FULL; + return -1; + } + + if (usage < AS250_TRANSFER_FRAME_SIZE) { + + free_bytes = (AS250_TRANSFER_FRAME_SIZE - usage); + + if (size > free_bytes) { + if (cpus_push_invalid(cpus, free_bytes)) { + /* could be critical error requiring reset */ + errno = E_CPUS_PUSH_INVALID; + return -1; + } + } + + if (cpus_write(cpus, pus_pkt, size)) { + /* could be critical error requiring reset */ + errno = E_CPUS_WRITE; + return -1; + } + } + + if (usage >= AS250_TRANSFER_FRAME_SIZE) { + + free_bytes = AS250_TRANSFER_FRAME_SIZE*CBUF_PUS_FRAMES - usage; + + if (size > free_bytes) { + errno = E_CPUS_FULL; + return -1; + } + + if (cpus_write(cpus, pus_pkt, size)) { + /* could be critical error requiring reset */ + errno = E_CPUS_WRITE; + return -1; + } + } + + return 0; +} + + +/** + * @brief get size of next valid packet + * + * @note if current packet is invalid it will be popped from the buffer + * + * @param cpus a struct cpus_buffers + * + * @retval >0 : packet size + * @retval 0 : success + */ + +int32_t cpus_next_valid_pkt_size(struct cpus_buffers *cpus) +{ + uint16_t size; + + + if (cpus_pop_invalid(cpus)) + return 0; + + if (!cpus_next_is_valid(cpus)) + return 0; + + + if (!cbuf_peek16(&(cpus->pus_size), &size, 1)) + return 0; + + return (int32_t) size; +} diff --git a/IBSW/lib/edac.c b/IBSW/lib/edac.c new file mode 100644 index 0000000000000000000000000000000000000000..d7c3478b17835d4aa808e09f11fcab9c7f084385 --- /dev/null +++ b/IBSW/lib/edac.c @@ -0,0 +1,410 @@ +/** + * @file edac.c + * @ingroup edac + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date February, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup edac EDAC error handling + * @brief Implements EDAC error handling and utility functions + * + * + * ## Overview + * + * This module implements handling of double-bit EDAC errors raised either via + * SPARC v8 data access exception trap 0x9 or the AHB STATUS IRQ 0x1. + * + * ## Mode of Operation + * + * The @ref traps module is needed to install the custom data access exception + * trap handler, the AHB irq handler must be installed via @ref irq_dispatch. + * + * If an error is detected in normal memory, its location is reported. If the + * source of the double bit error is the @ref iwf_flash, the last flash read + * address is identified and reported. + * + * + * @startuml {edac_handler.svg} "EDAC trap handler" width=10 + * :IRQ/trap; + * if (EDAC) then (yes) + * -[#blue]-> + * if (correctable) then (yes) + * :read address; + * if (FLASH) then (yes) + * :get logical address; + * endif + * : report address; + * endif + * endif + * end + * @enduml + * + * + * ## Error Handling + * + * None + * + * ## Notes + * + * - This module provides EDAC checkbit generation that is used in @ref memcfg + * to inject single or double bit errors. + * + */ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include <io.h> +#include <iwf_fpga.h> +#include <iwf_flash.h> +#include <ahb.h> +#include <errors.h> +#include <sysctl.h> +#include <wrap_malloc.h> + +#include <event_report.h> + +/** + * the reset function to call when a critical error is encountered + */ + +static void (*do_reset)(void *userdata); + +/** + * the user data to supply to the reset function + */ + +static void *reset_userdata; + + +static struct { + uint32_t edac_single; + uint32_t edac_double; + uint32_t edac_last_single_addr; + uint32_t edac_last_double_addr; + uint32_t flash_errors; +} edacstat; + +#if (__sparc__) +#define UINT32_T_FORMAT "%lu" +#else +#define UINT32_T_FORMAT "%u" +#endif + +static ssize_t edac_show(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + char *buf) +{ + if (!strcmp(sattr->name, "singlefaults")) + return sprintf(buf, UINT32_T_FORMAT, edacstat.edac_single); + + if (!strcmp(sattr->name, "doublefaults")) + return sprintf(buf, UINT32_T_FORMAT, edacstat.edac_double); + + if (!strcmp(sattr->name, "lastsingleaddr")) + return sprintf(buf, UINT32_T_FORMAT, + edacstat.edac_last_single_addr); + + if (!strcmp(sattr->name, "lastdoubleaddr")) + return sprintf(buf, UINT32_T_FORMAT, + edacstat.edac_last_double_addr); + + if (!strcmp(sattr->name, "flash_errors")) + return sprintf(buf, UINT32_T_FORMAT, + edacstat.flash_errors); + + + return 0; +} + + +__extension__ +static struct sobj_attribute singlefaults_attr = __ATTR(singlefaults, + edac_show, + NULL); +__extension__ +static struct sobj_attribute doublefaults_attr = __ATTR(doublefaults, + edac_show, + NULL); +__extension__ +static struct sobj_attribute lastsingleaddr_attr = __ATTR(lastsingleaddr, + edac_show, + NULL); +__extension__ +static struct sobj_attribute lastdoubleaddr_attr = __ATTR(lastdoubleaddr, + edac_show, + NULL); +__extension__ +static struct sobj_attribute flash_errors_attr = __ATTR(flash_errors, + edac_show, + NULL); +__extension__ +static struct sobj_attribute *edac_attributes[] = {&singlefaults_attr, + &doublefaults_attr, + &doublefaults_attr, + &lastsingleaddr_attr, + &lastdoubleaddr_attr, + &flash_errors_attr, + NULL}; + + + +/** + * @brief generate an BCH EDAC checkbit + * + * @param value the 32 bit value to generate the checkbit for + * @param bits an array of bit indices to XOR + * @param len the lenght of the bit index array + * + * @return a checkbit + * + * @note see GR712-UM v2.3 p. 60 + */ + +static uint8_t edac_checkbit_xor(const uint32_t value, + const uint32_t *bits, + const uint32_t len) +{ + uint8_t val = 0; + + uint32_t i; + + + for (i = 0; i < len; i++) + val ^= (value >> bits[i]); + + return (val & 0x1); +} + + +/** + * @brief generate BCH EDAC checkbits + * + * @param value the 32 bit value to generate the checkbits for + * + * @return bch the checkbits + * + * @note see GR712-UM v2.3 p. 60 + * + */ + +uint8_t edac_checkbits(const uint32_t value) +{ + uint8_t bch = 0; + + static const uint32_t CB[8][16] = { + {0, 4, 6, 7, 8, 9, 11, 14, 17, 18, 19, 21, 26, 28, 29, 31}, + {0, 1, 2, 4, 6, 8, 10, 12, 16, 17, 18, 20, 22, 24, 26, 28}, + {0, 3, 4, 7, 9, 10, 13, 15, 16, 19, 20, 23, 25, 26, 29, 31}, + {0, 1, 5, 6, 7, 11, 12, 13, 16, 17, 21, 22, 23, 27, 28, 29}, + {2, 3, 4, 5, 6, 7, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}, + {8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}, + {0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31}, + }; + + + bch |= edac_checkbit_xor(value, &CB[0][0], 16) << 0; + bch |= edac_checkbit_xor(value, &CB[1][0], 16) << 1; + bch |= (~edac_checkbit_xor(value, &CB[2][0], 16) & 0x1) << 2; + bch |= (~edac_checkbit_xor(value, &CB[3][0], 16) & 0x1) << 3; + bch |= edac_checkbit_xor(value, &CB[4][0], 16) << 4; + bch |= edac_checkbit_xor(value, &CB[5][0], 16) << 5; + bch |= edac_checkbit_xor(value, &CB[6][0], 16) << 6; + bch |= edac_checkbit_xor(value, &CB[7][0], 16) << 7; + + + return bch & 0x7f; +} + + +/** + * @brief check if the failing address is in a critical segment + * + * @param addr the address to check + * + * @return 0 if not critical, not null otherwise + * + * @note critical sections are: CPU stack space, SW image in RAM + */ + +static uint32_t edac_error_in_critical_section(uint32_t addr) +{ + + /* stack grows down */ + if ((SRAM1_CPU_0_STACK_BASE - addr) < SRAM1_CPU_0_STACK_SIZE) + return 1; + + if ((SRAM1_CPU_1_STACK_BASE - addr) < SRAM1_CPU_1_STACK_SIZE) + return 1; + + if ((addr - SRAM1_SW_ADDR) < SRAM1_SW_SIZE) + return 1; + + + return 0; +} + + +/** + * @brief investigate AHB status for source of error + * + * @return 1 if source was edac error, 0 otherwise + * + * @note turns out the AHB irq is raised on single bit errors after all; + * sections 5.10.3 and 7 in the GR712-UM docs are a bit ambiguous + * regarding that; since we should not correct errors while the other + * CPU is running, we'll continue to use the scrubbing mechanism as before + */ + +static uint32_t edac_error(void) +{ + static uint32_t addr; + + uint32_t block, page, offset; + + + /* was not EDAC related, ignore */ + if (!ahbstat_new_error()) + return 0; + + + addr = ahbstat_get_failing_addr(); + + ahbstat_clear_new_error(); + + /* ignore correctable errors, but update statistics */ + if (ahbstat_correctable_error()) { + edacstat.edac_single++; + edacstat.edac_last_single_addr = addr; + return 0; + } + + + + edacstat.edac_double++; + edacstat.edac_last_double_addr = addr; + + switch (addr) { + case IWF_FPGA_FLASH_1_DATA_BASE: + edacstat.flash_errors++; + flash_get_read_addr(0, &block, &page, &offset); + addr = flash_gen_logical_addr(block, page, offset); + event_report(EDAC, MEDIUM, addr); + break; + case IWF_FPGA_FLASH_2_DATA_BASE: + edacstat.flash_errors++; + flash_get_read_addr(1, &block, &page, &offset); + addr = flash_gen_logical_addr(block, page, offset); + event_report(EDAC, MEDIUM, addr); + break; + case IWF_FPGA_FLASH_3_DATA_BASE: + edacstat.flash_errors++; + flash_get_read_addr(2, &block, &page, &offset); + addr = flash_gen_logical_addr(block, page, offset); + event_report(EDAC, MEDIUM, addr); + break; + case IWF_FPGA_FLASH_4_DATA_BASE: + edacstat.flash_errors++; + flash_get_read_addr(3, &block, &page, &offset); + addr = flash_gen_logical_addr(block, page, offset); + event_report(EDAC, MEDIUM, addr); + break; + default: + event_report(EDAC, MEDIUM, addr); + if (edac_error_in_critical_section(addr)) + if (do_reset) + do_reset(reset_userdata); + break; + } + + + return 1; +} + + +/** + * set up: + * + * trap_handler_install(0x9, data_access_exception_trap); + * register edac trap to ahb irq + * + * for testing with grmon: + * dsu_clear_cpu_break_on_trap(0); + * dsu_clear_cpu_break_on_error_trap(0); + * + * @note this is not triggered for single faults in RAM (needs manual checking) + * but still raised by the FPGA if the FLASH error is correctable + */ + +void edac_trap(void) +{ + edac_error(); +} + + +/** + * @brief AHB irq handler for EDAC interrupts + */ + +int32_t edac_ahb_irq(__attribute__((unused)) void *userdata) +{ + edac_error(); + + return 0; +} + + +/** + * @brief set the reset function to call on critical error + * + * @param callback a callback function + * @param userdata a pointer to arbitrary data supplied to the callback function + */ + +int32_t edac_set_reset_callback(void (*callback)(void *userdata), + void *userdata) +{ + if (!callback) { + errno = EINVAL; + return -1; + } + + do_reset = callback; + reset_userdata = userdata; + + return 0; +} + + +/** + * @brief initialise the sysctl entries for the edac module + * + * @return -1 on error, 0 otherwise + */ + +int32_t edac_init_sysctl(void) +{ + struct sysobj *sobj; + + + sobj = sysobj_create(); + + if (!sobj) + return -1; + + sobj->sattr = edac_attributes; + + sysobj_add(sobj, NULL, sys_set, "edac"); + + return 0; +} diff --git a/IBSW/lib/error_log.c b/IBSW/lib/error_log.c new file mode 100644 index 0000000000000000000000000000000000000000..f02bc70f2cfc272d3c3129f763cbb09982cdcefb --- /dev/null +++ b/IBSW/lib/error_log.c @@ -0,0 +1,243 @@ +/** + * @file error_log.c + * @ingroup error_log + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup error_log Error Log Management + * @brief Manages the RAM/Flash error log + * + * + * ## Overview + * + * This component implements access to the Error Log stores in RAM. + * + * ## Mode of Operation + * + * The error log consists of ERROR_LOG_MAX_ENTRIES that store timestamps, + * error id and ERR_LOG_N2 bytes of extra information per error. + * + * The log is accessed like a ring buffer, with one entry acting as a guard + * for the read and write pointer, thus reducing the real number of entries to + * be at most ERROR_LOG_MAX_USABLE. + * + * As the log is circular, the oldest entry will be overwritten if a new entry + * is added when the log is full. + * + * + * + * @startuml {error_log_add_entry.svg} "Adding an error to the log" width=10 + * start + * if (write pointer invalid) then (yes) + * :reset log; + * endif + * :add entry; + * :forward write pointer; + * if (write == read) then (yes) + * :forward read pointer; + * endif + * + * stop + * @enduml + * + * + * + * + * @see + * _CHEOPS-IWF-INST-ICD-009 Section 5.3.3_ and _DPU-SICD-IF-3540_ for how + * to use the error log. + * + * ## Error Handling + * + * If corrupted memory modifies the log index beyond legal size, the log is + * reset to prevent corruption of memory by the mechanism itself. + * + * ## Notes + * + * Access to the error log for the IASW was dumbed down on request. An + * uncoditional reverse-dump of all entries starting from the last written entry + * has been added. The original per-entry access functionality has been kept for + * the the error log transfer to flash in order to avoid a coding mess by + * keeping log management contained in this component. + * + * @example demo_error_log.c + */ + +#include <stdlib.h> +#include <string.h> +#include <error_log.h> + + + +/** + * @brief initialises the error log location + * + * @param log a struct error log pointer location + * + * @note Ignores retval on malloc, log location is at a fixed position + * for regular operation. Index values are NOT set (DBS initialises the + * table) + */ + +void error_log_init(struct error_log **log) +{ + (*log) = (struct error_log *) RAM_ERROR_LOG_BASE; +} + +static void error_log_forward_index(uint32_t *idx) +{ + if ((*idx) < ERROR_LOG_MAX_USABLE) + (*idx)++; + else + (*idx) = 0; +} + + +/** + * @brief adds an entry to the error log + * @param error_log a pointer to the error log + * @param[in] time a time stamp + * @param[in] error_id an error or event id + * @param[in] error_log_info a pointer to a buffer of size ERR_LOG_N2, + * unused bytes must be zero + * @note the error log is a circular fifo + */ + +void error_log_add_entry(struct error_log *log, struct event_time *time, + uint16_t error_id, uint8_t *error_log_info) +{ + uint32_t idx; + + + idx = log->err_log_next; + + log->entry[idx].err_evt_id = error_id; + + memcpy(&log->entry[idx].time, time, sizeof(struct event_time)); + + memcpy(log->entry[idx].err_log_info, error_log_info, + ERR_LOG_N2); + + error_log_forward_index(&log->err_log_next); + + if (log->err_log_next == log->err_log_next_unsaved) + error_log_forward_index(&log->err_log_next_unsaved); +} + + +/** + * @brief read the next unsaved entry in the error log + * @param error_log a pointer to the error log + * @param[out] log_entry a struct error_log_entry + * + * @return 0: no entry read, 1: entry read + */ + +uint32_t error_log_read_entry_raw(struct error_log *log, + struct error_log_entry *log_entry) +{ + uint32_t idx; + + + idx = log->err_log_next_unsaved; + + if (idx == log->err_log_next) + return 0; + + memcpy(log_entry, &log->entry[idx], sizeof(struct error_log_entry)); + + error_log_forward_index(&log->err_log_next_unsaved); + + return 1; +} + + +/** + * @brief read out the next unsaved entry in the error log + * @param error_log a pointer to the error log + * @param[out] time a time stamp + * @param[out] error_id an error or event id + * @param[out] error_log_info a pointer to a buffer of size ERR_LOG_N2 + * + * @return 0: no entry read, 1: entry read + */ + +uint32_t error_log_read_entry(struct error_log *log, struct event_time *time, + uint16_t *error_id, uint8_t *error_log_info) +{ + struct error_log_entry log_entry; + + + if (!error_log_read_entry_raw(log, &log_entry)) + return 0; + + + (*error_id) = log_entry.err_evt_id; + + memcpy(time, &log_entry.time, sizeof(struct event_time)); + + memcpy(error_log_info, log_entry.err_log_info, ERR_LOG_N2); + + return 1; +} + + +/** + * @brief count the number of entries in the error log + * @param error_log a pointer to the error log + * + * @return number of active entries in log + */ + +uint32_t error_log_num_entries(struct error_log *log) +{ + int32_t num; + + + num = log->err_log_next - log->err_log_next_unsaved; + + if (num < 0) + return (ERROR_LOG_MAX_USABLE + num); + else + return num; +} + + + +/** + * @brief dump the error log in reverse, starting from the last write + * @param error_log a pointer to the error log + * @param buf a buffer where the error log will be dumped into + */ + +void error_log_dump_reverse(struct error_log *log, uint8_t *buf) +{ + int32_t idx; + + uint32_t i; + + + idx = (int32_t) log->err_log_next - 1; + + for (i = 0; i < ERROR_LOG_MAX_ENTRIES; i++) { + + if (idx < 0) + idx = ERROR_LOG_MAX_USABLE; + + memcpy(buf + i * sizeof(struct error_log_entry), + (uint8_t *) &log->entry[idx], + sizeof(struct error_log_entry)); + + idx--; + } +} diff --git a/IBSW/lib/event_report.c b/IBSW/lib/event_report.c new file mode 100644 index 0000000000000000000000000000000000000000..97f19a7b9c612e141a1988473756e37539065885 --- /dev/null +++ b/IBSW/lib/event_report.c @@ -0,0 +1,276 @@ +/** + * @file event_report.c + * @ingroup event_report + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at), + * Armin Luntzer (roland.ottensamer@univie.ac.at) + * @date 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup event_report Central event report transation interface to IASW + * + * @brief IBSW error translation to IASW events + * + * + * ## Overview + * + * Since it is required that a horizontal hierarchial topology with partially + * reverse dependencies is forced on what is clearly vertical partitioning in + * the supplied abstraction levels of hardware and software functionality of + * the IBSW component, it is sensible to at least minimise the adaption points. + * + * This component provides a central translation interface and submission of + * event reports generated by the IBSW to the IASW event reporting interface. + * + * + * ## Mode of Operation + * + * This report arguments passed to this interface are (for obvious reasons) + * similar to those used in the IASW. Since the IASW will crash if a + * combination of error id and severity is not defined, the arguments are + * filtered, so only legal combinations are passed to the IASW interface. + * + * If IASW definitions are changed, these filters must be updated accordingly. + * + * Given that the IASW errors do not actually contain useful information by + * themselves, relevant error information (defined as errno-extensions) are + * passed via the event data payload of an error. + * + * + * ## Error Handling + * + * None + * + * + * ## Notes + * + * From a design perspective, the IBSW should rather maintain its own + * independent error message buffer, which is queried by the IASW as desired. + * Instead, any error reported by the IBSW must invoke IASW functionality even + * from interrupt contexts wich makes such calls unpredictable and effectively + * destabilises the IBSW, as all IASW defects regarding event report and/or + * packet manangement immediately-back propagate or even halt the operation of + * the IBSW. + * + */ + + +#include <event_report.h> + + +#if (!__sparc__) + +void CrIaEvtRaise(__attribute__((unused)) uint8_t subtype, + __attribute__((unused)) uint16_t id, + __attribute__((unused)) uint16_t *data, + __attribute__((unused)) uint32_t data_size) +{ +} + +#endif + + +/** + * @brief translate normal level errors + * @param errno an error number + * + * @return the IASW level identifier of the error class + */ + +static uint16_t event_report_translate_class_norm(enum error_class c) +{ + uint16_t id = 0; + + switch (c) { + case INIT: + id = CRIA_SERV5_EVT_INIT_SUCC; + break; + case NOTIFY: + break; + case FBF: + break; + case EDAC: + break; + case CORE1553BRM: + break; + case GRSPW2: + break; + case ERRLOG: + break; + case SYNC: + break; + } + + return id; +} + + +/** + * @brief translate low level errors + * @param c the error class + * + * @return the IASW level identifier of the error class + */ + +static uint16_t event_report_translate_class_low(enum error_class c) +{ + uint16_t id = 0; + + switch (c) { + case INIT: + break; + case NOTIFY: + break; + case FBF: + break; + case EDAC: + id = CRIA_SERV5_EVT_SBIT_ERR; + break; + case CORE1553BRM: + id = CRIA_SERV5_EVT_1553_ERR_L; + break; + case GRSPW2: + id = CRIA_SERV5_EVT_SPW_ERR_L; + break; + case ERRLOG: + break; + case SYNC: + break; + } + + return id; +} + + +/** + * @brief translate medium level errors + * @param c the error class + * + * @return the IASW level identifier of the error class + */ + +static uint16_t event_report_translate_class_med(enum error_class c) +{ + uint16_t id = 0; + + switch (c) { + case INIT: + break; + case NOTIFY: + break; + case FBF: + break; + case EDAC: + id = CRIA_SERV5_EVT_DBIT_ERR; + break; + case CORE1553BRM: + id = CRIA_SERV5_EVT_1553_ERR_M; + break; + case GRSPW2: + id = CRIA_SERV5_EVT_SPW_ERR_M; + break; + case ERRLOG: + break; + case SYNC: + id = CRIA_SERV5_EVT_SYNC_LOSS; + break; + } + + return id; +} + + +/** + * @brief translate high level errors + * @param c the error class + * + * @return the IASW level identifier of the error class + */ + +static uint16_t event_report_translate_class_high(enum error_class c) +{ + uint16_t id = 0; + + switch (c) { + case INIT: + id = CRIA_SERV5_EVT_INIT_FAIL; + break; + case NOTIFY: + break; + case FBF: + id = CRIA_SERV5_EVT_FL_FBF_ERR; + break; + case EDAC: + break; + case CORE1553BRM: + id = CRIA_SERV5_EVT_1553_ERR_H; + break; + case GRSPW2: + id = CRIA_SERV5_EVT_SPW_ERR_H; + break; + case ERRLOG: + id = CRIA_SERV5_EVT_FL_EL_ERR; + break; + case SYNC: + break; + } + + return id; +} + + +/** + * @brief event report interface to IASW + * @param c the error class + * @param s the erorr severity + * @param errno an error number + * + */ + +void event_report(enum error_class c, enum error_severity s, uint32_t err) +{ + uint16_t class_id; + uint16_t event_data[2] = {0, 0}; + + + event_data[0] = (uint16_t) (err >> 16) & 0xffff; + event_data[1] = (uint16_t) err & 0xffff; + + + switch (s) { + case NORMAL: + class_id = event_report_translate_class_norm(c); + if (class_id) + CrIaEvtRaise(CRIA_SERV5_EVT_NORM, + class_id, event_data, 4); + break; + case LOW: + class_id = event_report_translate_class_low(c); + if (class_id) + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_LOW_SEV, + class_id, event_data, 4); + break; + case MEDIUM: + class_id = event_report_translate_class_med(c); + if (class_id) + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_MED_SEV, + class_id, event_data, 4); + break; + case HIGH: + class_id = event_report_translate_class_high(c); + if (class_id) + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_HIGH_SEV, + class_id, event_data, 4); + break; + default: + break; + } +} diff --git a/IBSW/lib/fpe.c b/IBSW/lib/fpe.c new file mode 100644 index 0000000000000000000000000000000000000000..6a89ccf6176771d2950d42a7d4fe618305520af4 --- /dev/null +++ b/IBSW/lib/fpe.c @@ -0,0 +1,447 @@ +/** + * @file fpe.c + * @ingroup edac + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date September, 2018 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include <io.h> + +#include <event_report.h> + +#include "CrIaDataPool.h" +#include "CrIaDataPoolId.h" +#include "Services/General/CrIaConstants.h" +#include "CrIaIasw.h" + +#include <ibsw_interface.h> +#include <iwf_fpga.h> + +#include <asm/leon.h> + +/** + * @brief high level floating point exception trap handler. + * signals a trap by setting the IRL1 and 2 in the data pool. + */ + +#define MAX_FQ 8 + +unsigned int TrapThres = 3; + +/* NOTE: in case the CPU2 traps also need to be handled, duplicate the whole function */ + +void fpe_trap(void) +{ + unsigned short fpTraps; + uint16_t event_data[2] = {0, 0}; + unsigned int i; + + struct doubleword { + unsigned int hi; + unsigned int lo; + } ; + + typedef union { + double d; + struct doubleword ww; + } dqueue ; + + volatile unsigned int fsrval = 0; + volatile dqueue dval; + volatile unsigned int value = 0; + volatile float fzero = 0.0f; + + dval.ww.hi = 0; + dval.ww.lo = 0; + + /* the FQ must be emptied until the FSR says empty */ + for (i=0; i < MAX_FQ; i++) + { + /* read FSR */ + __asm__ __volatile__("st %%fsr, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&fsrval)); + + if (fsrval & 0x00002000) /* FQ is set in FSR */ + { + /* read FQ */ + __asm__ __volatile__("std %%fq, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&dval.d)); + + /* for the first trap, we report the PC of the origin of the trap */ + if (i == 0) + { + /* raise event for dval.ww.hi (has the PC) */ + event_data[0] = (uint16_t) (dval.ww.hi >> 16) & 0xffff; + event_data[1] = (uint16_t) dval.ww.hi & 0xffff; + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_HIGH_SEV, CRIA_SERV5_EVT_INIT_FAIL, event_data, 4); + } + } + else + { + break; + } + } + + /* cure all denormalized numbers in the 32 f registers + by checking if (for nonzero numbers) the exponent is all 0, then setting to 0.0 */ + + /* f0 */ + __asm__ __volatile__("st %%f0, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f0 \n\t" + ::"r"(&fzero)); + } + + /* f1 */ + __asm__ __volatile__("st %%f1, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f1 \n\t" + ::"r"(&fzero)); + } + + /* f2 */ + __asm__ __volatile__("st %%f2, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f2 \n\t" + ::"r"(&fzero)); + } + + /* f3 */ + __asm__ __volatile__("st %%f3, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f3 \n\t" + ::"r"(&fzero)); + } + + /* f4 */ + __asm__ __volatile__("st %%f4, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f4 \n\t" + ::"r"(&fzero)); + } + + /* f5 */ + __asm__ __volatile__("st %%f5, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f5 \n\t" + ::"r"(&fzero)); + } + + /* f6 */ + __asm__ __volatile__("st %%f6, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f6 \n\t" + ::"r"(&fzero)); + } + + /* f7 */ + __asm__ __volatile__("st %%f7, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f7 \n\t" + ::"r"(&fzero)); + } + + /* f8 */ + __asm__ __volatile__("st %%f8, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f8 \n\t" + ::"r"(&fzero)); + } + + /* f9 */ + __asm__ __volatile__("st %%f9, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f9 \n\t" + ::"r"(&fzero)); + } + + /* f10 */ + __asm__ __volatile__("st %%f10, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f10 \n\t" + ::"r"(&fzero)); + } + + /* f11 */ + __asm__ __volatile__("st %%f11, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f11 \n\t" + ::"r"(&fzero)); + } + + /* f12 */ + __asm__ __volatile__("st %%f12, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f12 \n\t" + ::"r"(&fzero)); + } + + /* f13 */ + __asm__ __volatile__("st %%f13, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f13 \n\t" + ::"r"(&fzero)); + } + + /* f14 */ + __asm__ __volatile__("st %%f14, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f14 \n\t" + ::"r"(&fzero)); + } + + /* f15 */ + __asm__ __volatile__("st %%f15, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f15 \n\t" + ::"r"(&fzero)); + } + + /* f16 */ + __asm__ __volatile__("st %%f16, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f16 \n\t" + ::"r"(&fzero)); + } + + /* f17 */ + __asm__ __volatile__("st %%f17, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f17 \n\t" + ::"r"(&fzero)); + } + + /* f18 */ + __asm__ __volatile__("st %%f18, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f18 \n\t" + ::"r"(&fzero)); + } + + /* f19 */ + __asm__ __volatile__("st %%f19, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f19 \n\t" + ::"r"(&fzero)); + } + + /* f20 */ + __asm__ __volatile__("st %%f20, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f20 \n\t" + ::"r"(&fzero)); + } + + /* f21 */ + __asm__ __volatile__("st %%f21, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f21 \n\t" + ::"r"(&fzero)); + } + + /* f22 */ + __asm__ __volatile__("st %%f22, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f22 \n\t" + ::"r"(&fzero)); + } + + /* f23 */ + __asm__ __volatile__("st %%f23, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f23 \n\t" + ::"r"(&fzero)); + } + + /* f24 */ + __asm__ __volatile__("st %%f24, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f24 \n\t" + ::"r"(&fzero)); + } + + /* f25 */ + __asm__ __volatile__("st %%f25, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f25 \n\t" + ::"r"(&fzero)); + } + + /* f26 */ + __asm__ __volatile__("st %%f26, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f26 \n\t" + ::"r"(&fzero)); + } + + /* f27 */ + __asm__ __volatile__("st %%f27, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f27 \n\t" + ::"r"(&fzero)); + } + + /* f28 */ + __asm__ __volatile__("st %%f28, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f28 \n\t" + ::"r"(&fzero)); + } + + /* f29 */ + __asm__ __volatile__("st %%f29, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f29 \n\t" + ::"r"(&fzero)); + } + + /* f30 */ + __asm__ __volatile__("st %%f30, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f30 \n\t" + ::"r"(&fzero)); + } + + /* f31 */ + __asm__ __volatile__("st %%f31, [%0] \n\t" + "nop; nop \n\t" + ::"r"(&value)); + if ((value & 0x7fffffff) & ((value & 0x7F800000) == 0)) + { + __asm__ __volatile__("ld [%0], %%f31 \n\t" + ::"r"(&fzero)); + } + + + /* Reporting */ + if (leon3_cpuid() == 0) + { + /* update nr of traps in IRL1 */ + CrIaCopy(IRL1_ID, &fpTraps); + fpTraps += 1; + CrIaPaste(IRL1_ID, &fpTraps); + } + else + { + /* update nr of traps in IRL2 */ + CrIaCopy(IRL2_ID, &fpTraps); + fpTraps += 1; + CrIaPaste(IRL2_ID, &fpTraps); + } + + /* Command a SW reset of EXCEPTION type */ + if ((TrapThres != 0) && fpTraps >= TrapThres) + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_EX); + + return; +} diff --git a/IBSW/lib/grspw2.c b/IBSW/lib/grspw2.c new file mode 100644 index 0000000000000000000000000000000000000000..9bb7f7f540fbbd08c3129ffd77c655f10af1969c --- /dev/null +++ b/IBSW/lib/grspw2.c @@ -0,0 +1,1787 @@ +/** + * @file grspw2.c + * @ingroup grspw2 + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup grspw2 GRSPW2 driver + * @brief Driver for the GRSPW2 IP core + * + * ## Overview + * + * This is a driver for the GRSPW2 IP core that operates without interrupts + * in normal mode and with internally managed interrupts in packet routing mode. + * It maintains its own ring-buffer-like tables of transfer descriptors that are + * used by the GRSPW2 core. These can store up to 64 TX and 128 RX packets at a + * time. + * + * ## Mode of Operation + * + * @see _GR712RC user manual v2.7 chapter 16_ for information on the SpW IP core + * + * The transfer descriptors are managed by tracking their usage status in + * doubly-linked lists and moving their references between a free and a busy + * list. + * + * @startuml{grspw2_add_pkt.svg} "add TX packet" width=10 + * actor User + * database Free + * database Busy + * entity SpW + * + * Free <- Busy : free + * note left + * processed descriptors + * are moved to free list + * end note + * + * User <- Free : retrieve + * User -> Busy : activate + * + * Busy --> SpW : send + * note left + * SpW core is notified + * about new descriptors + * end note + * @enduml + * + * + * TX packets are sent (and hence freed) as fast as possible by the core. + * RX packets are accumulated by the device until all unused descriptors + * are filled up, after which the core will no longer accept packets on its link + * interface, until at least one stored entry is fetched by the user. Because of + * how the SpaceWire protocol works, no packet loss will occur on the link + * level. Transfers just pause until continued. + * + * @startuml{grspw2_get_pkt.svg} "get RX packet" width=10 + * actor User + * database Free + * database Busy + * entity SpW + * + * Busy <- SpW : receive + * + * note right + * used descriptors are + * marked by the core + * end note + * + * hnote over SpW: ... + * + * User <-- Busy : check status + * + * hnote over User: ... + * + * User <- Busy : fetch + * User -> Free : release + * Free --> Busy : reactivate + * + * note left + * during typical + * operation + * end note + * + * + * + * + * @enduml + * + * While not strictly necessary, RX descriptors are tracked in a free/busy list + * as well to allow the same level of control as with TX descriptors. + * + * + * ### Routing mode + * + * There is support for direct routing of packets between SpW cores. Since + * immediate re-transmission is required for low-latency, low packet rate + * configurations, the routing is by default set up to generate one interrupt + * per received packet. For alternative applications with either constant high + * packet rates or high latency tolerance, the routing could be reconfigured to + * swap whole packet buffers on a table-basis rather than of individual + * descriptors. + * + * A route is configured by linking the configuration of one SpaceWire core to + * another and activating interrupt controlled mode. Incoming packets are then + * passed into the outgoing queue of the "routing" link. Routes are always + * defined unidirectionally. + * + * The number of TX descriptors in a basic setup effectively limits the use of + * the RX descriptors to be the same, otherwise stalls may occur when the number + * of RX packets exceed the supply of TX descriptors. + * + * + * ## Error Handling + * + * Configuration errors are indicated during setup. If an operational error + * (e.g. DMA, cable disconnect, ...) occurs, it is reported and cleared. The + * core is not reset or reconfigured, persistent faults will therefore raise + * errors periodically. + * + * + * ## Notes + * + * - there is currently support for only one DMA channel, as the core is not + * implemented with more channels on the GR712RC + * - if more 64 TX or 128 RX packet slots are needed, descriptor table switching + * must be implemented + * - routing is implemented inefficiently, since incoming packets are always + * copied to the output. The conceivably much faster zero-copy method of + * exchanging descriptors is not possible due to the differing descriptor + * layouts. Another solution would be the exchange of data buffer references, + * but this requires one of either: + * - the use of the MMU with a functioning malloc/free system + * - a pointer tracking system within the driver + * . + * In CHEOPS, the routing functionality is needed only for testing and + * calibration purposes on ground, so the copy implementation is sufficient. + * + * + * + * @example demo_spw.c + */ + +#include <errno.h> +#include <string.h> +#include <stdlib.h> + +#include <io.h> +#include <errors.h> +#include <compiler.h> +#include <grspw2.h> +#include <irq_dispatch.h> +#include <sysctl.h> +#include <leon/irq.h> + +#include <event_report.h> +#include <stdio.h> + + +#if (__sparc__) +#define UINT32_T_FORMAT "%lu" +#else +#define UINT32_T_FORMAT "%u" +#endif + +__extension__ +static ssize_t rxtx_show(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + char *buf) +{ + struct grspw2_core_cfg *cfg; + + + cfg = container_of(sobj, struct grspw2_core_cfg, sobj); + + if (!strcmp(sattr->name, "rx_bytes")) + return sprintf(buf, UINT32_T_FORMAT, cfg->rx_bytes); + + if (!strcmp(sattr->name, "tx_bytes")) + return sprintf(buf, UINT32_T_FORMAT, cfg->tx_bytes); + + return 0; +} + +__extension__ +static ssize_t rxtx_store(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + __attribute__((unused)) const char *buf, + __attribute__((unused)) size_t len) +{ + struct grspw2_core_cfg *cfg; + + + cfg = container_of(sobj, struct grspw2_core_cfg, sobj); + + if (!strcmp(sattr->name, "rx_bytes")) { + cfg->rx_bytes = 0; + return 0; + } + + if (!strcmp(sattr->name, "tx_bytes")) { + cfg->tx_bytes = 0; + return 0; + } + + return 0; +} + +__extension__ +static struct sobj_attribute rx_bytes_attr = __ATTR(rx_bytes, + rxtx_show, + rxtx_store); +__extension__ +static struct sobj_attribute tx_bytes_attr = __ATTR(tx_bytes, + rxtx_show, + rxtx_store); + +__extension__ +static struct sobj_attribute *grspw2_attributes[] = {&rx_bytes_attr, + &tx_bytes_attr, + NULL}; + + +/** + * @brief central error handling + */ + +static void grspw2_handle_error(enum error_severity s) +{ + event_report(GRSPW2, s, (uint32_t) errno); +} + + +/** + * @brief dma error interrupt callback + * @note the error bits are cleared by *writing* with a 1, see GR712RC-UM p.128 + */ + +static int32_t grspw2_dma_error(void *userdata) +{ + uint32_t dmactrl; + struct grspw2_core_cfg *cfg; + + + cfg = (struct grspw2_core_cfg *) userdata; + + dmactrl = ioread32be(&cfg->regs->dma[0].ctrl_status); + + if (dmactrl & GRSPW2_DMACONTROL_RA) { + errno = E_SPW_RX_AHB_ERROR; + grspw2_handle_error(MEDIUM); + dmactrl &= GRSPW2_DMACONTROL_RA; + } + + if (dmactrl & GRSPW2_DMACONTROL_TA) { + errno = E_SPW_TX_AHB_ERROR; + grspw2_handle_error(MEDIUM); + dmactrl &= GRSPW2_DMACONTROL_TA; + } + + iowrite32be(dmactrl, &cfg->regs->dma[0].ctrl_status); + + return 0; +} + + +/** + * @brief link error interrupt callback + */ + +static int32_t grspw2_link_error(void *userdata) +{ + uint32_t tmp; + uint32_t status; + struct grspw2_core_cfg *cfg; + + + cfg = (struct grspw2_core_cfg *) userdata; + + status = ioread32be(&cfg->regs->status); + + /* fast check if any bit is set, check details later */ + tmp = status & (GRSPW2_STATUS_IA | GRSPW2_STATUS_PE | GRSPW2_STATUS_DE + | GRSPW2_STATUS_ER | GRSPW2_STATUS_CE); + + if (!tmp) + return 0; + + + if (status & GRSPW2_STATUS_IA) { + errno = E_SPW_INVALID_ADDR_ERROR; + grspw2_handle_error(MEDIUM); + status &= GRSPW2_STATUS_IA; + } + + if (status & GRSPW2_STATUS_PE) { + errno = E_SPW_PARITY_ERROR; + grspw2_handle_error(MEDIUM); + status &= GRSPW2_STATUS_PE; + } + + if (status & GRSPW2_STATUS_DE) { + errno = E_SPW_DISCONNECT_ERROR; + grspw2_handle_error(MEDIUM); + status &= GRSPW2_STATUS_DE; + } + + if (status & GRSPW2_STATUS_ER) { + errno = E_SPW_ESCAPE_ERROR; + grspw2_handle_error(MEDIUM); + status &= GRSPW2_STATUS_ER; + } + + if (status & GRSPW2_STATUS_CE) { + errno = E_SPW_CREDIT_ERROR; + grspw2_handle_error(MEDIUM); + status &= GRSPW2_STATUS_CE; + } + + iowrite32be(status, &cfg->regs->status); + + return 0; +} + + +/** + * + * @brief stop DMA channel operation + * - preserve channel settings (bits 12-16) + * - set abort TX bit (9) + * - clear status and descriptor bits (all others) + */ + +static void grspw2_dma_stop(struct grspw2_regs *regs, uint32_t channel) +{ + uint32_t dmactrl; + + + dmactrl = ioread32be(®s->dma[channel].ctrl_status); + dmactrl &= (GRSPW2_DMACONTROL_LE | GRSPW2_DMACONTROL_SP + | GRSPW2_DMACONTROL_SA | GRSPW2_DMACONTROL_EN + | GRSPW2_DMACONTROL_NS); + dmactrl |= GRSPW2_DMACONTROL_AT; + + iowrite32be(dmactrl, ®s->dma[channel].ctrl_status); +} + + +/** + * @brief reset a DMA channel + */ + +static void grspw2_dma_reset(struct grspw2_regs *regs, uint32_t channel) +{ + uint32_t dmactrl; + + + dmactrl = ioread32be(®s->dma[channel].ctrl_status); + dmactrl &= (GRSPW2_DMACONTROL_LE | GRSPW2_DMACONTROL_EN); + + iowrite32be(dmactrl, ®s->dma[channel].ctrl_status); + + iowrite32be(GRSPW2_DEFAULT_MTU, ®s->dma[channel].rx_max_pkt_len); + iowrite32be(0x0, ®s->dma[channel].tx_desc_table_addr); + iowrite32be(0x0, ®s->dma[channel].rx_desc_table_addr); +} + + +/** + * @brief enable AHB error interrupt generation + */ +static void grspw2_set_ahb_irq(struct grspw2_core_cfg *cfg) +{ + uint32_t dmactrl; + + dmactrl = ioread32be(&cfg->regs->dma[0].ctrl_status); + dmactrl |= GRSPW2_DMACONTROL_AI; + iowrite32be(dmactrl, &cfg->regs->dma[0].ctrl_status); +} + +#if (__unused__) +/** + * @brief disable AHB error interrupt generation + */ +static void grspw2_unset_ahb_irq(struct grspw2_core_cfg *cfg) +{ + uint32_t dmactrl; + + dmactrl = ioread32be(&cfg->regs->dma[0].ctrl_status); + dmactrl &= ~GRSPW2_DMACONTROL_AI; +} +#endif + +/** + * @brief soft reset a SpW core + * - do NOT touch control register! + * - clear status bits + * - clear timer register + */ + +static void grspw2_spw_softreset(struct grspw2_regs *regs) +{ + uint32_t ctrl, status, i; + + + ctrl = ioread32be(®s->ctrl); + + for (i = 0; i < GRSPW2_CTRL_GET_NCH(ctrl); i++) + grspw2_dma_reset(regs, i); + + status = ioread32be(®s->status); + status |= (GRSPW2_STATUS_TO | GRSPW2_STATUS_CE | GRSPW2_STATUS_ER + | GRSPW2_STATUS_DE | GRSPW2_STATUS_PE | GRSPW2_STATUS_IA + | GRSPW2_STATUS_EE); + + iowrite32be(status, ®s->status); + iowrite32be(0x0, ®s->time); +} + + +/** + * @brief hard reset a SpW core + * - set reset bit high + * - clear timer register + */ + +void grspw2_spw_hardreset(struct grspw2_regs *regs) +{ + uint32_t ctrl; + + + ctrl = ioread32be(®s->ctrl); + ctrl |= GRSPW2_CTRL_RS; + + iowrite32be(ctrl, ®s->ctrl); + iowrite32be(0x0, ®s->time); +} + +/** + * stop operation on a particular SpW link + * - stop all of the links DMA channels + * - keep link enabled (and do not touch the reset bit) + * - disable interrrupts + * - disable promiscuous mode + * - disable timecode reception/transmission + * - keep port force/select setting + * => RMAP operation is not stopped on RMAP-capable links + */ + +static void grspw2_spw_stop(struct grspw2_regs *regs) +{ + uint32_t ctrl, i; + + + ctrl = ioread32be(®s->ctrl); + + for (i = 0; i < GRSPW2_CTRL_GET_NCH(ctrl); i++) + grspw2_dma_stop(regs, i); + + ctrl &= (GRSPW2_CTRL_LD | GRSPW2_CTRL_LS | GRSPW2_CTRL_NP + | GRSPW2_CTRL_AS | GRSPW2_CTRL_RE | GRSPW2_CTRL_RD + | GRSPW2_CTRL_PS | GRSPW2_CTRL_NP); + + iowrite32be(ctrl, ®s->ctrl); +} + +/** + * @brief set the address of a SpW node + */ + +static void grspw2_set_node_addr(struct grspw2_regs *regs, uint8_t nodeaddr) +{ + iowrite32be((nodeaddr & GRSPW2_DMA_CHANNEL_ADDR_REG_MASK), + ®s->nodeaddr); +} + + +/** + * @brief enable promiscuous mode + */ + +void grspw2_set_promiscuous(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl |= GRSPW2_CTRL_PM; + + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +/** + * @brief disable promiscuous mode + */ + +void grspw2_unset_promiscuous(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl &= ~GRSPW2_CTRL_PM; + + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +/** + * @brief enable autostart + */ + +static void grspw2_set_autostart(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl |= GRSPW2_CTRL_AS; + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +#if (__unused__) +/** + * @brief disable autostart + */ + +static void grspw2_unset_autostart(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl &= ~GRSPW2_CTRL_AS; + iowrite32be(ctrl, &cfg->regs->ctrl); +} +#endif + + +/** + * @brief enable linkstart + */ + +static void grspw2_set_linkstart(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl |= GRSPW2_CTRL_LS; + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +#if (__unused__) +/** + * @brief disable linkstart + */ + +static void grspw2_unset_linkstart(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl &= ~GRSPW2_CTRL_LS; + iowrite32be(ctrl, &cfg->regs->ctrl); +} +#endif + + +/** + * @brief enable link error interrupts + */ + +void grspw2_set_link_error_irq(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl |= GRSPW2_CTRL_LI | GRSPW2_CTRL_IE; + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +/** + * @brief disable link error interrupts + */ + +void grspw2_unset_link_error_irq(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl &= ~(GRSPW2_CTRL_LI | GRSPW2_CTRL_IE); + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +/** + * @brief enable time code reception + */ + +void grspw2_set_time_rx(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl |= GRSPW2_CTRL_TR; + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +/** + * @brief enable time code transmission + */ + +static void grspw2_set_time_tx(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl |= GRSPW2_CTRL_TT; + iowrite32be(ctrl, &cfg->regs->ctrl); +} + + +#if (__unused__) +/** + * @brief disable time code transmission + */ + +static void grspw2_unset_time_tx(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl &= ~GRSPW2_CTRL_TT; + iowrite32be(ctrl, &cfg->regs->ctrl); +} +#endif + + + +/** + * @brief clear status register bits + */ + +static void grspw2_clear_status(struct grspw2_core_cfg *cfg) +{ + uint32_t status; + + status = ioread32be(&cfg->regs->status); + status |= GRSPW2_STATUS_CLEAR_MASK; + iowrite32be(status, &cfg->regs->status); +} + +/** + * @brief set Receive Interrupt enable bit in the DMA register + */ +__attribute__((unused)) +static void grspw2_rx_interrupt_enable(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = ioread32be(&cfg->regs->dma[0].ctrl_status); + flags |= GRSPW2_DMACONTROL_RI; + + iowrite32be(flags, &cfg->regs->dma[0].ctrl_status); +} + +/** + * @brief clear Receive Interrupt enable bit in the DMA register + */ + +__attribute__((unused)) +static void grspw2_rx_interrupt_disable(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = ioread32be(&cfg->regs->dma[0].ctrl_status); + flags &= ~GRSPW2_DMACONTROL_RI; + + iowrite32be(flags, &cfg->regs->dma[0].ctrl_status); +} + + +#if (__unused__) +/** + * @brief set Transmit Interrupt enable bit in the DMA register + */ + +static void grspw2_tx_interrupt_enable(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = ioread32be(&cfg->regs->dma[0].ctrl_status); + flags |= GRSPW2_DMACONTROL_TI; + + iowrite32be(flags, &cfg->regs->dma[0].ctrl_status); +} +#endif + + +#if (__unused__) +/** + * @brief clear Transmit Interrupt enable bit in the DMA register + */ + +static void grspw2_tx_interrupt_disable(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = ioread32be(&cfg->regs->dma[0].ctrl_status); + flags &= ~GRSPW2_DMACONTROL_TI; + + iowrite32be(flags, &cfg->regs->dma[0].ctrl_status); +} +#endif + + +/** + * @brief enable tick out interrupt + */ + +void grspw2_tick_out_interrupt_enable(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = ioread32be(&cfg->regs->ctrl); + flags |= GRSPW2_CTRL_TQ; + + iowrite32be(flags, &cfg->regs->ctrl); + +} + + +/** + * @brief set SpW clock divisor + * + * Note: divides the external clock + * Note: inputs are ACTUAL divisor values + */ + +static int32_t grspw2_set_clockdivs(struct grspw2_regs *regs, + uint8_t link_start, + uint8_t link_run) +{ + uint32_t clkdiv; + + if (link_start && link_run) { + /** (actual divisor value = reg value + 1) */ + clkdiv = ((link_start - 1) << GRSPW2_CLOCKDIV_START_BIT) + & GRSPW2_CLOCKDIV_START_MASK; + clkdiv |= (link_run - 1) & GRSPW2_CLOCKDIV_RUN_MASK; + + iowrite32be(clkdiv, ®s->clkdiv); + + return 0; + + } else { + errno = E_SPW_CLOCKS_INVALID; + return -1; + } +} + + +/** + * @brief set the rx descriptor table address; can be used to + * switch between multiple descriptor tables + */ + +static int32_t grspw2_set_rx_desc_table_addr(struct grspw2_core_cfg *cfg, + uint32_t *mem) +{ + if (!mem) { + errno = EINVAL; + return -1; + } + + if (((uint32_t) mem) & GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN) { + errno = E_SPW_RX_DESC_TABLE_ALIGN; + return -1; + } + + iowrite32be(((uint32_t) mem), &cfg->regs->dma[0].rx_desc_table_addr); + + return 0; +} + + +/** + * @brief set the tx descriptor table address; can be used to + * switch between multiple descriptor tables + */ + +static int32_t grspw2_set_tx_desc_table_addr(struct grspw2_core_cfg *cfg, + uint32_t *mem) +{ + if (!mem) { + errno = EINVAL; + return -1; + } + + if (((uint32_t) mem) & GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN) { + errno = E_SPW_TX_DESC_TABLE_ALIGN; + return -1; + } + + iowrite32be(((uint32_t) mem), &cfg->regs->dma[0].tx_desc_table_addr); + + return 0; +} + + +/** + * @brief init rx descriptor table pointers and attach to "free" list + */ + +int32_t grspw2_rx_desc_table_init(struct grspw2_core_cfg *cfg, + uint32_t *mem, uint32_t tbl_size, + uint8_t *pkt_buf, uint32_t pkt_size) +{ + size_t i; + + uint32_t idx; + uint32_t num_desc; + + + if (!pkt_buf) { + errno = EINVAL; + return -1; + } + + if (grspw2_set_rx_desc_table_addr(cfg, mem)) + return -1; /* errno set in call */ + + INIT_LIST_HEAD(&cfg->rx_desc_ring_used); + INIT_LIST_HEAD(&cfg->rx_desc_ring_free); + + num_desc = tbl_size / GRSPW2_RX_DESC_SIZE; + + if (num_desc > GRSPW2_RX_DESCRIPTORS) + num_desc = GRSPW2_RX_DESCRIPTORS; + + for (i = 0; i < num_desc; i++) { + + idx = i * GRSPW2_RX_DESC_SIZE / sizeof(uint32_t); + cfg->rx_desc_ring[i].desc = (struct grspw2_rx_desc *) &mem[idx]; + + idx = i * pkt_size; + cfg->rx_desc_ring[i].desc->pkt_addr = (uint32_t) &pkt_buf[idx]; + + /* control flags must be set elsewhere */ + cfg->rx_desc_ring[i].desc->pkt_ctrl = pkt_size; + + list_add_tail(&cfg->rx_desc_ring[i].node, + &cfg->rx_desc_ring_free); + } + + return 0; +} + + +/** + * @brief init tx descriptor table pointers and attach to "free" list + */ + +int32_t grspw2_tx_desc_table_init(struct grspw2_core_cfg *cfg, + uint32_t *mem, uint32_t tbl_size, + uint8_t *hdr_buf, uint32_t hdr_size, + uint8_t *data_buf, uint32_t data_size) +{ + uint32_t i; + uint32_t idx; + uint32_t num_desc; + + + if (!data_buf) { + errno = EINVAL; + return -1; + } + + if (hdr_size && !hdr_buf) { + errno = EINVAL; + return -1; + } + + if (grspw2_set_tx_desc_table_addr(cfg, mem)) + return -1; /* errno set in call */ + + INIT_LIST_HEAD(&cfg->tx_desc_ring_used); + INIT_LIST_HEAD(&cfg->tx_desc_ring_free); + + num_desc = tbl_size / GRSPW2_TX_DESC_SIZE; + + if (num_desc > GRSPW2_TX_DESCRIPTORS) + num_desc = GRSPW2_TX_DESCRIPTORS; + + for (i = 0; i < num_desc; i++) { + + idx = i * GRSPW2_TX_DESC_SIZE / sizeof(uint32_t); + cfg->tx_desc_ring[i].desc = (struct grspw2_tx_desc *) &mem[idx]; + + idx = i * hdr_size; + cfg->tx_desc_ring[i].desc->hdr_addr = (uint32_t) &hdr_buf[idx]; + + idx = i * data_size; + cfg->tx_desc_ring[i].desc->data_addr = (uint32_t) + &data_buf[idx]; + + cfg->tx_desc_ring[i].desc->hdr_size = hdr_size; + cfg->tx_desc_ring[i].desc->data_size = data_size; + + /* clear packet control field, so random bits do not + * mark the descriptor as enabled + */ + cfg->tx_desc_ring[i].desc->pkt_ctrl = 0; + + list_add_tail(&cfg->tx_desc_ring[i].node, + &cfg->tx_desc_ring_free); + } + + return 0; +} + +/** + * @brief inform the core that new rx descriptors are available + */ + + +static void grspw2_rx_desc_new_avail(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = ioread32be(&cfg->regs->dma[0].ctrl_status); + flags |= GRSPW2_DMACONTROL_RD | GRSPW2_DMACONTROL_RE; + + iowrite32be(flags, &cfg->regs->dma[0].ctrl_status); +} + + +/** + * @brief inform the core that new tx descriptors are available + */ + +static void grspw2_tx_desc_new_avail(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = ioread32be(&cfg->regs->dma[0].ctrl_status); + flags |= GRSPW2_DMACONTROL_TE; + + iowrite32be(flags, &cfg->regs->dma[0].ctrl_status); +} + + +/** + * @brief move a rx descriptor to the free ring + */ + +static void grspw2_rx_desc_move_free(struct grspw2_core_cfg *cfg, + struct grspw2_rx_desc_ring_elem *p_elem) +{ + list_move_tail(&p_elem->node, &cfg->rx_desc_ring_free); +} + + +/** + * @brief move a tx descriptor to the free ring + */ + +static void grspw2_tx_desc_move_free(struct grspw2_core_cfg *cfg, + struct grspw2_tx_desc_ring_elem *p_elem) +{ + list_move_tail(&p_elem->node, &cfg->tx_desc_ring_free); +} + + +/** + * @brief move all inactive tx descriptors to the free ring + */ + +__attribute__((unused)) +static void grspw2_tx_desc_move_free_all(struct grspw2_core_cfg *cfg) +{ + struct grspw2_tx_desc_ring_elem *p_elem; + struct grspw2_tx_desc_ring_elem *p_tmp; + + list_for_each_entry_safe(p_elem, p_tmp, + &cfg->tx_desc_ring_used, node) { + + if (p_elem->desc->pkt_ctrl & GRSPW2_TX_DESC_EN) + break; + + grspw2_tx_desc_move_free(cfg, p_elem); + } +} + + +/* + * @brief clear the busy ring of all rx descriptors (and move them + * to the free ring) + */ + +__attribute__((unused)) +static void grspw2_rx_desc_clear_all(struct grspw2_core_cfg *cfg) +{ + struct grspw2_rx_desc_ring_elem *p_elem; + struct grspw2_rx_desc_ring_elem *p_tmp; + + list_for_each_entry_safe(p_elem, p_tmp, + &cfg->rx_desc_ring_used, node) { + + grspw2_rx_desc_move_free(cfg, p_elem); + } +} + + +/** + * @brief move a rx descriptor to the busy ring + */ + +static void grspw2_rx_desc_move_busy(struct grspw2_core_cfg *cfg, + struct grspw2_rx_desc_ring_elem *p_elem) +{ + list_move_tail(&p_elem->node, &cfg->rx_desc_ring_used); +} + + +/** + * @brief move a tx descriptor to the busy ring + */ + +static void grspw2_tx_desc_move_busy(struct grspw2_core_cfg *cfg, + struct grspw2_tx_desc_ring_elem *p_elem) +{ + list_move_tail(&p_elem->node, &cfg->tx_desc_ring_used); + +} + + + +/** + * @brief retrieve a free rx descriptor + */ + +static struct grspw2_rx_desc_ring_elem + *grspw2_rx_desc_get_next_free(struct grspw2_core_cfg *cfg) +{ + struct grspw2_rx_desc_ring_elem *p_elem; + + if (likely(list_filled(&cfg->rx_desc_ring_free))) { + p_elem = list_entry((&cfg->rx_desc_ring_free)->next, + struct grspw2_rx_desc_ring_elem, node); + return p_elem; + } else { + return NULL; + } +} + +/** + * @brief retrieve a busy rx descriptor + */ + +static struct grspw2_rx_desc_ring_elem + *grspw2_rx_desc_get_next_used(struct grspw2_core_cfg *cfg) +{ + struct grspw2_rx_desc_ring_elem *p_elem; + + if (likely(list_filled(&cfg->rx_desc_ring_used))) { + p_elem = list_entry((&cfg->rx_desc_ring_used)->next, + struct grspw2_rx_desc_ring_elem, node); + return p_elem; + } else { + return NULL; + } +} + + +/** + * @brief retrieve a free tx descriptor + */ + +static struct grspw2_tx_desc_ring_elem + *grspw2_tx_desc_get_next_free(struct grspw2_core_cfg *cfg) +{ + struct grspw2_tx_desc_ring_elem *p_elem; + + if (likely(list_filled(&cfg->tx_desc_ring_free))) { + p_elem = list_entry((&cfg->tx_desc_ring_free)->next, + struct grspw2_tx_desc_ring_elem, node); + return p_elem; + } else { + return NULL; + } +} + + +/** + * @brief set tx descriptor active + * @note per-packet interrupt are enabled by default, enable rx irq + * in dma control register to have them actually fire + */ + +static void grspw2_rx_desc_set_active(struct grspw2_rx_desc_ring_elem *p_elem) +{ + p_elem->desc->pkt_ctrl |= GRSPW2_RX_DESC_IE | GRSPW2_RX_DESC_EN; +} + + +/** + * @brief set tx descriptor active + */ + +static void grspw2_tx_desc_set_active(struct grspw2_tx_desc_ring_elem *p_elem) +{ + p_elem->desc->pkt_ctrl |= GRSPW2_TX_DESC_IE | GRSPW2_TX_DESC_EN; +} + +/** + * @brief check if there are rx descriptors in the free ring + * + * @return 1 if available, 0 if ring is empty + */ + +static int32_t grspw2_rx_desc_avail(struct grspw2_core_cfg *cfg) +{ + if (likely(list_filled(&cfg->rx_desc_ring_free))) + return 1; + else + return 0; +} + + +#if (__unused__) +/** + * @brief check if there are tx descriptors in the free ring + * + * @return 1 if available, 0 if ring is empty + */ + +static int32_t grspw2_tx_desc_avail(struct grspw2_core_cfg *cfg) +{ + if (likely(list_filled(&cfg->tx_desc_ring_free))) + return 1; + else + return 0; +} +#endif + + +/** + * @brief try to activate a free descriptor + * @return 0 on success, -1 if no descriptor is available + * + * @note There is no check for NULL on grspw2_rx_desc_get_next_free(), because + * it would be redundant, since a positive return on + * grspw2_rx_desc_avail() guarantees the availability of a descriptor + * element. (Unless someone maliciously fiddles with our lists + * externally). We could of course check anyway, but this function should + * be snappy, if we can avoid something clearly useless, we should. + */ + +static int32_t grspw2_rx_desc_add(struct grspw2_core_cfg *cfg) +{ + struct grspw2_rx_desc_ring_elem *p_elem; + + + if (!grspw2_rx_desc_avail(cfg)) + return -1; + /* + The case p_elem == NULL is taken care for by the above check. + Also see the note in the function description. + */ + p_elem = grspw2_rx_desc_get_next_free(cfg); + + grspw2_rx_desc_set_active(p_elem); + + grspw2_rx_desc_move_busy(cfg, p_elem); + + grspw2_rx_desc_new_avail(cfg); + + return 0; +} + + +static void grswp2_rx_desc_add_all(struct grspw2_core_cfg *cfg) +{ + size_t i; + + for (i = 0; i < GRSPW2_RX_DESCRIPTORS; i++) { + if (grspw2_rx_desc_add(cfg)) + break; + } +} + + +#if (__unused__) +/** + * @brief set up a RX descriptor with a custom address and control field + * + * @return 0 on success, -1 if no descriptors were available + */ + +static int32_t grspw2_rx_desc_add_custom(struct grspw2_core_cfg *cfg, + uint32_t pkt_ctrl, + uint32_t pkt_addr) +{ + + struct grspw2_rx_desc_ring_elem *p_elem; + + p_elem = grspw2_rx_desc_get_next_free(cfg); + + if (unlikely(!p_elem)) { + errno = E_SPW_NO_RX_DESC_AVAIL; + return -1; + } + + /* ALWAYS set packet address first! */ + p_elem->desc->pkt_addr = pkt_addr; + p_elem->desc->pkt_ctrl = pkt_ctrl; + + list_move_tail(&p_elem->node, &cfg->rx_desc_ring_used); + + grspw2_rx_desc_new_avail(cfg); + + return 0; +} +#endif + + +/** + * @brief release and try to reactivate a descriptor + * @return 0 on success, -1 if no descriptor is available + */ + +static int32_t grspw2_rx_desc_readd(struct grspw2_core_cfg *cfg, + struct grspw2_rx_desc_ring_elem *p_elem) +{ + grspw2_rx_desc_move_free(cfg, p_elem); + + return grspw2_rx_desc_add(cfg); +} + +/** + * @brief try to activate a free descriptor and copy the data from the + * supplied buffer + * + * @return 0 on success, -1 on failure + * + * @note USE WITH CARE: does not perform any size checks on the buffers + * + */ + +static int32_t grspw2_tx_desc_add_pkt(struct grspw2_core_cfg *cfg, + const void *hdr_buf, + uint32_t hdr_size, + const void *data_buf, + uint32_t data_size) +{ + struct grspw2_tx_desc_ring_elem *p_elem; + + + /* this is a little excessive, remove on your own risk */ + + if (hdr_size && !hdr_buf) { + errno = EINVAL; + return -1; + } + + if (data_size && !data_buf) { + errno = EINVAL; + return -1; + } + + grspw2_tx_desc_move_free_all(cfg); + + p_elem = grspw2_tx_desc_get_next_free(cfg); + + + if (unlikely(!p_elem)) { + errno = E_SPW_NO_TX_DESC_AVAIL; + return -1; + } + + if (hdr_buf != NULL) + memcpy((void *) p_elem->desc->hdr_addr, hdr_buf, hdr_size); + + if (data_buf != NULL) + memcpy((void *) p_elem->desc->data_addr, data_buf, data_size); + + p_elem->desc->hdr_size = hdr_size; + p_elem->desc->data_size = data_size; + + grspw2_tx_desc_set_active(p_elem); + + grspw2_tx_desc_move_busy(cfg, p_elem); + + grspw2_tx_desc_new_avail(cfg); + + return 0; + +} + + +#if (__unused__) +/** + * @brief set up a TX descriptor with a custom header/data and control field. + * + * @return 0 on success, -1 if no descriptors were available + */ + +static int32_t grspw2_tx_desc_add_custom(struct grspw2_core_cfg *cfg, + uint32_t pkt_ctrl, + uint32_t hdr_size, + uint32_t hdr_addr, + uint32_t data_size, + uint32_t data_addr) +{ + struct grspw2_tx_desc_ring_elem *p_elem; + + + grspw2_tx_desc_move_free_all(cfg); + + p_elem = grspw2_tx_desc_get_next_free(cfg); + + if (unlikely(!p_elem)) { + errno = E_SPW_NO_TX_DESC_AVAIL; + return -1; + } + + p_elem->desc->hdr_size = hdr_size; + p_elem->desc->hdr_addr = hdr_addr; + + p_elem->desc->data_size = data_size; + p_elem->desc->data_addr = data_addr; + + p_elem->desc->pkt_ctrl = pkt_ctrl; + + list_move_tail(&p_elem->node, &cfg->tx_desc_ring_used); + + grspw2_tx_desc_new_avail(cfg); + + return 0; +} +#endif + +/** + * @brief configure maximum transmission unit + */ + +static void grspw2_set_mtu(struct grspw2_core_cfg *cfg, uint32_t mtu) +{ + iowrite32be(mtu, &cfg->regs->dma[0].rx_max_pkt_len); +} + + +/** + * @brief default dma configuration, see GR712RC UM, p.128 for flags + */ + +static void grspw2_configure_dma(struct grspw2_core_cfg *cfg) +{ + uint32_t flags; + + flags = GRSPW2_DMACONTROL_AI | GRSPW2_DMACONTROL_PS + | GRSPW2_DMACONTROL_PR | GRSPW2_DMACONTROL_TA + | GRSPW2_DMACONTROL_RA | GRSPW2_DMACONTROL_NS; + + iowrite32be(flags, &cfg->regs->dma[0].ctrl_status); +} + + +/** + * @brief get timecnt field of grspw2 time register + */ + +uint32_t grspw2_get_timecnt(struct grspw2_core_cfg *cfg) +{ + return ioread32be(&cfg->regs->time) & GRSPW2_TIME_TIMECNT; +} + + + +/** + * @brief get link status + */ + +uint32_t grspw2_get_link_status(struct grspw2_core_cfg *cfg) +{ + return GRSPW2_STATUS_GET_LS(ioread32be(&cfg->regs->status)); +} + + + +/** + * @brief transmit a SpW time code; there should be at least 4 system + * clocks and 25 transmit clocks inbetween calls, see GR712RC UM, p.108 + */ + +void grspw2_tick_in(struct grspw2_core_cfg *cfg) +{ + uint32_t ctrl; + + ctrl = ioread32be(&cfg->regs->ctrl); + ctrl |= GRSPW2_CTRL_TI; + + iowrite32be(ctrl, &cfg->regs->ctrl); +} + +#if (__SPW_ROUTING__) +/** + * @brief interrupt handler for packet routing + * @note only a single node is supported at the moment + */ + +int32_t grspw2_route(void *userdata) +{ + int32_t ret; + + struct grspw2_core_cfg *cfg; + + struct grspw2_rx_desc_ring_elem *p_elem; + struct grspw2_rx_desc_ring_elem *p_tmp; + + cfg = (struct grspw2_core_cfg *) userdata; + + list_for_each_entry_safe(p_elem, p_tmp, &cfg->rx_desc_ring_used, node) { + + if (p_elem->desc->pkt_ctrl & GRSPW2_RX_DESC_EN) + break; + + /* copy to output if there is a free tx descriptor */ + ret = grspw2_tx_desc_add_pkt(cfg->route[0], + NULL, + 0, + (void *) p_elem->desc->pkt_addr, + p_elem->desc->pkt_size); + + if (unlikely(ret)) + break; + + grspw2_rx_desc_readd(cfg, p_elem); + } + + grspw2_tx_desc_move_free_all(cfg->route[0]); + + return 0; +} + + +/** + * @brief enable routing between SpW cores + */ + +int32_t grspw2_enable_routing(struct grspw2_core_cfg *cfg, + struct grspw2_core_cfg *route) +{ + size_t i; + + + cfg->route[0] = route; + + irl2_register_callback(cfg->core_irq, PRIORITY_NOW, + grspw2_route, (void *) cfg); + + + grspw2_set_promiscuous(cfg); + grspw2_rx_interrupt_enable(cfg); + + /* only allow as many rx descriptors as there are tx descriptors + * or we could run into a jam, because we do not use interrupts on TX + * and hence do not reload the ring if it happens + */ + grspw2_rx_desc_clear_all(cfg); + + for (i = 0; i < GRSPW2_TX_DESCRIPTORS; i++) + grspw2_rx_desc_add(cfg); + + return 0; +} + + +/** + * @brief enable interactive routing between SpW cores + * @note call grspw2_route() to route received descriptors + */ + +int32_t grspw2_enable_routing_noirq(struct grspw2_core_cfg *cfg, + struct grspw2_core_cfg *route) +{ + cfg->route[0] = route; + + grspw2_set_promiscuous(cfg); + + return 0; +} + + + +/** + * @brief disable routing between SpW cores + */ + +int32_t grspw2_disable_routing(struct grspw2_core_cfg *cfg) +{ + irl2_deregister_callback(cfg->core_irq, grspw2_route, + (void *) cfg->route[0]); + + grspw2_unset_promiscuous(cfg); + grspw2_rx_interrupt_disable(cfg); + + return 0; +} +#endif /* (__SPW_ROUTING__) */ + + +/** + * @brief retrieve number of packets available + */ + +uint32_t grspw2_get_num_pkts_avail(struct grspw2_core_cfg *cfg) +{ + uint32_t i = 0; + + struct grspw2_rx_desc_ring_elem *p_elem; + struct grspw2_rx_desc_ring_elem *p_tmp; + + list_for_each_entry_safe(p_elem, p_tmp, &cfg->rx_desc_ring_used, node) { + if (p_elem->desc->pkt_ctrl & GRSPW2_RX_DESC_EN) + break; + i++; + } + + return i; +} + + +/** + * @brief get number of available free tx descriptors + */ + +uint32_t grspw2_get_num_free_tx_desc_avail(struct grspw2_core_cfg *cfg) +{ + uint32_t i = 0; + + struct grspw2_tx_desc_ring_elem *p_elem; + struct grspw2_tx_desc_ring_elem *p_tmp; + + list_for_each_entry_safe(p_elem, p_tmp, &cfg->tx_desc_ring_free, node) { + i++; + } + + return i; +} + + +/** + * @brief retrieve the size of the next packet + */ + +uint32_t grspw2_get_next_pkt_size(struct grspw2_core_cfg *cfg) +{ + uint32_t pkt_size; + + struct grspw2_rx_desc_ring_elem *p_elem; + + + p_elem = grspw2_rx_desc_get_next_used(cfg); + + if (!p_elem) + return 0; + + /* still active */ + if (p_elem->desc->pkt_ctrl & GRSPW2_RX_DESC_EN) + return 0; + + pkt_size = p_elem->desc->pkt_size - cfg->strip_hdr_bytes; + + return pkt_size; +} + + + +/** + * @brief retrieve a packet + */ + +uint32_t grspw2_get_pkt(struct grspw2_core_cfg *cfg, uint8_t *pkt) +{ + uint32_t pkt_size; + + struct grspw2_rx_desc_ring_elem *p_elem; + + + p_elem = grspw2_rx_desc_get_next_used(cfg); + + if (!p_elem) + return 0; + + /* still active */ + if (p_elem->desc->pkt_ctrl & GRSPW2_RX_DESC_EN) + return 0; + + pkt_size = p_elem->desc->pkt_size - cfg->strip_hdr_bytes; + + cfg->rx_bytes += p_elem->desc->pkt_size; + + memcpy((void *) pkt, + (void *) (p_elem->desc->pkt_addr + cfg->strip_hdr_bytes), + pkt_size); + + grspw2_rx_desc_readd(cfg, p_elem); + + return pkt_size; +} + +/** + * @brief drop a packet + * @return 1 if packet was dropped, 0 otherwise + */ + +uint32_t grspw2_drop_pkt(struct grspw2_core_cfg *cfg) +{ + struct grspw2_rx_desc_ring_elem *p_elem; + + + p_elem = grspw2_rx_desc_get_next_used(cfg); + + if (!p_elem) + return 0; + + /* still active */ + if (p_elem->desc->pkt_ctrl & GRSPW2_RX_DESC_EN) + return 0; + + cfg->rx_bytes += p_elem->desc->pkt_size; + + grspw2_rx_desc_readd(cfg, p_elem); + + return 1; +} + + + +/** + * @brief add a packet + */ + +int32_t grspw2_add_pkt(struct grspw2_core_cfg *cfg, + const void *hdr, uint32_t hdr_size, + const void *data, uint32_t data_size) +{ + int32_t ret; + + ret = grspw2_tx_desc_add_pkt(cfg, hdr, hdr_size, data, data_size); + + if (unlikely(ret)) { + grspw2_handle_error(LOW); + return -1; + } + + cfg->tx_bytes += hdr_size + data_size; + + return 0; +} + + +/** + * @brief start core operation + */ + +void grspw2_core_start(struct grspw2_core_cfg *cfg) +{ + grswp2_rx_desc_add_all(cfg); + grspw2_clear_status(cfg); + grspw2_set_linkstart(cfg); + grspw2_set_autostart(cfg); +} + + +/** + * @brief (re)initialise a grswp2 core + */ +#define SYSCTL_STRING_SIZE 8 + +#if (__sparc__) +#define SYSCTL_NAME_FORMAT "spw%lu" +#else +#define SYSCTL_NAME_FORMAT "spw%u" +#endif + + +int32_t grspw2_core_init(struct grspw2_core_cfg *cfg, uint32_t core_addr, + uint8_t node_addr, uint8_t link_start, + uint8_t link_run, uint32_t mtu, + uint32_t core_irq, uint32_t ahb_irq, + uint32_t strip_hdr_bytes) +{ + int32_t ret; + + char *buf; + + + irq_dispatch_enable(); + + cfg->regs = (struct grspw2_regs *) core_addr; + cfg->core_irq = core_irq; + cfg->ahb_irq = ahb_irq; + + cfg->strip_hdr_bytes = strip_hdr_bytes; + + grspw2_spw_stop(cfg->regs); + grspw2_spw_softreset(cfg->regs); + grspw2_set_node_addr(cfg->regs, node_addr); + + + irl1_deregister_callback(cfg->ahb_irq, grspw2_dma_error, cfg); + irl2_deregister_callback(cfg->core_irq, grspw2_link_error, cfg); + + + ret = grspw2_set_clockdivs(cfg->regs, link_start, link_run); + if (ret) + return -1; + + grspw2_set_mtu(cfg, mtu); + grspw2_configure_dma(cfg); + grspw2_set_time_tx(cfg); + + grspw2_set_ahb_irq(cfg); + grspw2_set_link_error_irq(cfg); + + irl1_register_callback(cfg->ahb_irq, PRIORITY_NOW, + grspw2_dma_error, cfg); + + irl2_register_callback(cfg->core_irq, PRIORITY_NOW, + grspw2_link_error, cfg); + + cfg->rx_bytes = 0; + cfg->tx_bytes = 0; + + /* as sysctl does not provide a _remove() function, make + * sure that we do not re-add the same object to the sysctl tree + */ + if (cfg->sobj.sattr) + return 0; + + sysobj_init(&cfg->sobj); + + cfg->sobj.sattr = grspw2_attributes; + + /* derive the spw link number from the interrupt number */ + buf = (char *) malloc(SYSCTL_STRING_SIZE * sizeof(char)); + + snprintf(buf, SYSCTL_STRING_SIZE * sizeof(char), SYSCTL_NAME_FORMAT, + core_irq - GR712_IRL2_GRSPW2_0); + + sysobj_add(&cfg->sobj, NULL, driver_set, buf); + + return 0; + + /* NOTE: here CLANG scan-view reports a false positive + * about buf being a memory leak + */ +} + + +#if (__sparc__) +/** + * set the external clock to the grspw2 core + * does not actually belong here... + */ + +void set_gr712_spw_clock(void) +{ + uint32_t *gpreg = (uint32_t *) 0x80000600; + + /** set input clock to 100 MHz INCLK */ + (*gpreg) = (ioread32be(gpreg) & (0xFFFFFFF8)); +} +#endif diff --git a/IBSW/lib/ibsw_init/ibsw_init.c b/IBSW/lib/ibsw_init/ibsw_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d9689cb94d21b224118da6f0193d89e9bad63350 --- /dev/null +++ b/IBSW/lib/ibsw_init/ibsw_init.c @@ -0,0 +1,158 @@ +/** + * @file ibsw.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup ibsw_config IBSW initialisation + * @brief Setup and init functions for the various IBSW components + * + * This is the default IBSW configuration procedure: + * + * - configure IBSW timers + * - initialise interrupts + * - configure the error log location + * - configure SpaceWire devices + * - set up packet buffers + * - configure the 1553 core + * - run CrIaInit() + * - configure memscrub + * - enable edac + * - set up cyclical timing and sync pulse + * - enable FBF operations + * - enable CPU load measurements + * - enable watchdog + * + */ + + +#include <stdint.h> +#include <stdlib.h> + + +#include <string.h> +#include <stdio.h> + + +#include <leon/irq.h> +#include <leon/irq_dispatch.h> + +#include <ibsw.h> +#include <memcfg.h> +#include <iwf_fpga.h> +#include <wrap_malloc.h> +#include <sysctl.h> +#include <clkgate.h> +#include <memscrub.h> + +#include <ibsw_interface.h> + + +#define GND_PKTS (32 * 1024) +#define OBC_PKTS (32 * 1024) +#define SPW_1_ADDR 36 +#define SPW_1_STRIP_HDR_BYTES 4 + +#if (__SPW_ROUTING__) +#define SPW_0_ADDR 0x15 +#define SPW_0_STRIP_HDR_BYTES 0 +#endif + +#define SES_HEADER_BYTES 4 + + + + +/** + * @brief ibsw initalisation + * @return 0 on success, otherwise error + */ + +ssize_t ibsw_init(struct ibsw_config *cfg) +{ + struct grtimer_uptime time0, time1; + + + /* clear the configuration structure*/ + bzero(cfg, sizeof(struct ibsw_config)); + + sysctl_init(); + + if (malloc_enable_syscfg()) + return -1; + + ibsw_configure_timing(&cfg->timer, &cfg->brm, + &cfg->spw1); + + /* measure boot time from timer initialisation */ + grtimer_longcount_get_uptime(cfg->timer.rtu, &time0); + + irq_dispatch_enable(); + + ibsw_configure_error_log(&cfg->error_log); + + if (ibsw_configure_spw(&cfg->spw1, GRSPW2_BASE_CORE_1, + GR712_IRL2_GRSPW2_1, SPW_1_ADDR, SES_HEADER_BYTES, + SPW_1_STRIP_HDR_BYTES, CLKGATE_GRSPW1)) + return -1; + +#if (__SPW_ROUTING__) + if (ibsw_configure_spw(&cfg->spw0, GRSPW2_BASE_CORE_0, + GR712_IRL2_GRSPW2_0, SPW_0_ADDR, SES_HEADER_BYTES, + SPW_0_STRIP_HDR_BYTES, CLKGATE_GRSPW0)) + return -1; +#endif + + + if (ibsw_configure_cpus(&cfg->pus_buf)) + return -1; + + if (ibsw_configure_ptrack(&cfg->pkt_gnd, GND_PKTS)) + return -1; + + if (ibsw_configure_ptrack(&cfg->pkt_obc, OBC_PKTS)) + return -1; + + if (ibsw_configure_1553(&cfg->brm, &cfg->pus_buf, + &cfg->pkt_gnd, &cfg->pkt_gnd, + &cfg->timer)) + return -1; + + + if (CrIaInit() != 0) + return -1; + + /* ... scrubbing is carried out at the end of the cyclical + * thread instead + */ + memscrub_init(); + + ibsw_configure_1553_sync(&cfg->brm, &cfg->timer); + + if (ibsw_configure_edac()) + return -1; + + timekeeper_set_signal_callback(&cfg->timer, &cyclical_notification, + &cfg->timer); + + /* enable FBF operations */ + flash_operation.isReady = 1; + + grtimer_longcount_get_uptime(cfg->timer.rtu, &time1); + + ibsw_init_cpu_0_idle_timing(cfg); + + CrIbEnableWd(); + + return 0; +} diff --git a/IBSW/lib/ibsw_init/ibsw_mainloop.c b/IBSW/lib/ibsw_init/ibsw_mainloop.c new file mode 100644 index 0000000000000000000000000000000000000000..58624742f27d5dd6156c1c52ef9b7d33ef39ab3e --- /dev/null +++ b/IBSW/lib/ibsw_init/ibsw_mainloop.c @@ -0,0 +1,287 @@ +/** + * @file ibsw_mainloop.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief IBSW main loop running on CPU 0 + * + * + * ## Overview + * + * This is the main loop of the IBSW. It is entered after initialisation + * has completed. Since the IFSW does not use threads, it functions as a + * collaborative scheduler stand-in. It represents the "highest priority" + * thread and hence controls the sleep state of the CPU and measures the CPU + * load. + * + * ## Mode of Operation + * + * + * ### Main Loop + * + * @startuml {ibsw_mainloop.svg} "IBSW Mainloop" width=10 + * start + * + * repeat + * if (reset sampling window) then (yes) + * :record sampling start time stamp; + * endif + * + * :record power down timestamp; + * :issue CPU power down; + * + * note + * The CPU is now powered down until an interrupt occurs. + * end note + * + * if (IASW tick) then (yes) + * :execute IASW cyclical; + * :execute error log flush; + * :execute FBF operation; + * endif + * + * :update sampling time window; + * :update idle time; + * + * if (sampling time > 125 ms) then (yes) + * :update CPU load; + * endif + * + * repeat while () + * + * + * @enduml + * + * By default, the loop enters CPU power down mode. If woken by any interrupt, + * the "notification" counter for the IASW cycle is checked. If a value is set, + * a IASW cycle is executed and the counter is decremented, followed by an + * @ref error_log flush to @ref iwf_flash and a flash-based-file read or write + * cycle (see @ref ibsw_interface, execute_flash_op(), CrIbFbfReadBlock(), + * CrIbFbfWriteBlock()). + * + * The CPU load is measured by recording the CPU power down time. Before the + * power down command is issued, the current time is recorded. The wake up time + * is taken in ibsw_update_cpu_0_idle() which is attached to the interrupts used + * in the IFSW and set at most once after a wake up from power down. This + * ensures that the timestamp is no updated in any subsequent interrupts while + * the CPU is busy. The power down time measurements are stacked withing a + * sampling window of at least 125 ms (the granularity of a IASW cycle is + * sufficient) and the load is calculated from + * + * \f[ + * load = int \left(100.0 \times \left[1.0 - \frac{t_{idle}}{t_{window}}\right]\right) + * \f] + * + * + * ### Cyclical Notifications + * + * A call to cyclical_notification() increments the notification counter used + * in the main loop. This function records a time stamp that is passed to + * execute_flash_op() as a cycle start reference together with a run time limit. + * This ensures that flash operations will not exceed the IASW cycle time window + * that starts with the notification (not the actual execution start time of the + * IASW cyclical activities). + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + */ + + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <leon/irq.h> +#include <leon/irq_dispatch.h> +#include <asm/leon.h> +#include <core1553brm_as250.h> +#include <grspw2.h> +#include <cpus_buffers.h> +#include <packet_tracker.h> + +#include <leon3_gptimer.h> +#include <leon3_grtimer.h> +#include <watchdog.h> +#include <syncpulse.h> + +#include <error_log.h> +#include <clkgate.h> +#include <sysctl.h> + +#include <traps.h> +#include <edac.h> +#include <leon3_dsu.h> +#include <memcfg.h> +#include <memscrub.h> +#include <iwf_fpga.h> +#include <wrap_malloc.h> +#include <ibsw_interface.h> + + + + +#include <timing.h> +#include <leon3_grtimer_longcount.h> + + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + + + +static uint32_t iasw_tick; +static struct grtimer_uptime cyc_start; + + +/** + * @brief cyclical notification callback + * + * @brief userdata a pointer to arbitrary userdata + */ + +void cyclical_notification(void *userdata) +{ + struct time_keeper *timer = (struct time_keeper *) userdata; + + /* get the time of the cyclical notification for cycle overrun detection */ + if (!iasw_tick) + grtimer_longcount_get_uptime(timer->rtu, &cyc_start); + + iasw_tick++; +} + + +/** + * @brief the main IBSW loop + * + * @param ibsw_cfg a struct ibsw_config + * + * This is the main IBSW loop after initalisation is complete. + * It will power down the LEON while no interrupts and/or threads are running. + * CPU load is measured via the processor idle time. A timestamp is taken before + * issuing powerdown mode, any subsequent (registered) interrupt will update + * the time of the wakeup. The idle times are accumulated until the + * sampling window is at least one second long. The computed cpu load is then + * stored as an integer with a load granularity of 1 percent + */ + +void ibsw_mainloop(struct ibsw_config *cfg) +{ + uint32_t reset = 1; + + double idle = 0.0; + double window, tmp; + double trem; + + struct grtimer_uptime in; + struct grtimer_uptime out; + struct grtimer_uptime start; + + + while (1) { + + if (reset) { + /* IASW polling rate = 8 Hz */ + grtimer_longcount_get_uptime(cfg->timer.rtu, + &start); + + reset = 0; + idle = 0.0; + } + + + grtimer_longcount_get_uptime(cfg->timer.rtu, &in); + leon3_powerdown_safe(0x40000000); + + + if (iasw_tick) { + /* execute RTCONT_CYC */ + execute_cyclical(); + + /* execute RTCONT_ERRLOG only if enough time is left */ + grtimer_longcount_get_uptime(cfg->timer.rtu, &out); + + trem = grtimer_longcount_difftime(ibsw_cfg.timer.rtu, + out, cyc_start); + if (trem < RUNBEFORE_ERRLOG) + execute_log_move_to_flash(); + + /* execute RTCONT_FLASH only if enough time is left */ + + /* NOTE: the block erase operation can take up to 10ms, + plus 3 ms per page write. Consequently, we have to + allow at least 13 ms here (1 erase + 1 page write). + This is, because the CrIbFbfWriteBlock writes at most + 1 page (4 kw = 16 kB) per call and at the beginning + of a block this can result in one block erase plus + one page write. */ + + grtimer_longcount_get_uptime(cfg->timer.rtu, &out); + + trem = grtimer_longcount_difftime(ibsw_cfg.timer.rtu, + out, cyc_start); + if (trem < RUNBEFORE_FLASH) + execute_flash_op(cyc_start); + + iasw_tick--; + } + + /* get the "wake up" time when main() actually continues to + * determine the size of the sampling window; + * the time stamp when actually leaving power down mode will be + * registered in ibsw_update_cpu_0_idle() + */ + grtimer_longcount_get_uptime(cfg->timer.rtu, &out); + + + /* in case we are woken by something that is not covered + * by the ISR + */ + if (!cfg->cpu_0_idle_exit.coarse) + if (!cfg->cpu_0_idle_exit.fine) + continue; + + idle += grtimer_longcount_difftime(cfg->timer.rtu, + cfg->cpu_0_idle_exit, + in); + + tmp = grtimer_longcount_difftime(cfg->timer.rtu, + out, start); + + /* IASW polling rate = 8 Hz */ + if (tmp > (1.0/8.0)) { + + window = grtimer_longcount_difftime(cfg->timer.rtu, + out, + start); + + tmp = 100.0 * (1.0 - idle / window); + + cfg->cpu0_load = (uint32_t) tmp; + + reset = 1; + } + + /* reset wake-up timestamp */ + cfg->cpu_0_idle_exit.coarse = 0; + cfg->cpu_0_idle_exit.fine = 0; + } +} diff --git a/IBSW/lib/ibsw_init/init_1553.c b/IBSW/lib/ibsw_init/init_1553.c new file mode 100644 index 0000000000000000000000000000000000000000..4ea562ac589c79dd66bb321deaa83bf0a0593dbc --- /dev/null +++ b/IBSW/lib/ibsw_init/init_1553.c @@ -0,0 +1,182 @@ +/** + * @file init_1553.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief Configuration of the 1553 interface + * + * + * ## Overview + * + * This is the configuration procedure of the 1553 interface. + * The device is ungated and configured as a remote terminal in ping-pong + * buffer mode with the address read from the @ref iwf_fpga. + * The run-time memory block of the 1553 device must be aligned properly, + * so a memory are of size (BRM_MEM_BLOCK_SIZE_BYTES + BRM_MEM_BLOCK_ALIGN_SIZE) + * is allocated and aligned to BRM_MEM_BLOCK_ALIGN. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + */ + + +#include <stdint.h> +#include <sys/types.h> +#include <stdlib.h> +#include <string.h> + +#include <ibsw_interface.h> + +#include <timing.h> +#include <errors.h> +#include <clkgate.h> +#include <core1553brm_as250.h> +#include <iwf_fpga.h> + + +/** + * @brief configures the 1553 interface + * + * @param brm a struct brm_config + * @param pus_buf a struct cpus_buffers + * @param pkt_gnd a struct packet_tracker + * @param pkt_obc a struct packet_tracker + * @param timer a struct time_keeper + * + * @return -1 on error, 0 otherwise + */ + +ssize_t ibsw_configure_1553(struct brm_config *brm, + struct cpus_buffers *pus_buf, + struct packet_tracker *pkt_gnd, + struct packet_tracker *pkt_obc, + struct time_keeper *timer) +{ + uint8_t *adb_ddb; + uint16_t rt_addr; + uint32_t flags; + uint32_t mem; + + + mem = (uint32_t) malloc(BRM_MEM_BLOCK_SIZE_BYTES + + BRM_MEM_BLOCK_ALIGN_SIZE); + + if (!mem) { + errno = ENOMEM; + return -1; + } + + bzero((void *) mem, + BRM_MEM_BLOCK_SIZE_BYTES + BRM_MEM_BLOCK_ALIGN_SIZE); + + adb_ddb = (uint8_t *) malloc(AS250_TRANSFER_FRAME_SIZE + * sizeof(uint8_t)); + + if (!adb_ddb) { + errno = ENOMEM; + return -1; + } + + + /* address to brm devices register */ + brm->regs = (struct brm_reg *) CORE1553BRM_REG_BASE; + + /* operating mode */ + brm->mode = PING_PONG; + + /* align memory to boundary */ + brm->brm_mem = (uint16_t *) ((mem + BRM_MEM_BLOCK_ALIGN) + & ~BRM_MEM_BLOCK_ALIGN); + + + /* ungate the 1553 core, see GR712RC UM pp. 228 */ + flags = ioread32be(&clkgate->unlock); + flags |= CLKGATE_1553BRM; + iowrite32be(flags, &clkgate->unlock); + + flags = ioread32be(&clkgate->core_reset); + flags |= CLKGATE_1553BRM; + iowrite32be(flags, &clkgate->core_reset); + + flags = ioread32be(&clkgate->clk_enable); + flags |= CLKGATE_1553BRM; + iowrite32be(flags, &clkgate->clk_enable); + + flags = ioread32be(&clkgate->core_reset); + flags &= ~CLKGATE_1553BRM; + iowrite32be(flags, &clkgate->core_reset); + + flags = ioread32be(&clkgate->unlock); + flags &= ~CLKGATE_1553BRM; + iowrite32be(flags, &clkgate->unlock); + + + /* enable the brm */ + if (brm_1553_enable(brm)) + return -1; + + /* assign the sliding pus buffer */ + if (as250_set_atr_cpus_buffers(brm, pus_buf)) + return -1; + + /* assign the packet buffers */ + if (brm_set_packet_tracker_gnd(brm, pkt_gnd)) + return -1; + + if (brm_set_packet_tracker_obc(brm, pkt_obc)) + return -1; + + /* assign the work buffer */ + if (brm_set_adb_ddb_buffer(brm, adb_ddb)) + return -1; + + /* set callback for time message */ + if (as250_set_time_callback(brm, &timekeeper_set_1553_time, timer)) + return -1; + + /* set callback for rt-reset modecode */ + if (as250_set_rt_reset_callback(brm, &rt_reset, NULL)) + return -1; + + rt_addr = fpga_dpu_get_rt_addr(); + + /* allow only 9 (nominal) or 10 (redundant), otherwise fall back to + * nominal address (e.g. if address selector is not plugged in + */ + + switch (rt_addr) { + case 9: + case 10: + break; + default: + rt_addr = 9; + break; + } + + if (brm_rt_init(brm, rt_addr, BRM_FREQ_20MHZ)) + return -1; + + + return 0; +} diff --git a/IBSW/lib/ibsw_init/init_cpu_0_idle_timing.c b/IBSW/lib/ibsw_init/init_cpu_0_idle_timing.c new file mode 100644 index 0000000000000000000000000000000000000000..e3550284ed0f8bc52c27b950d6a2c61a77662edb --- /dev/null +++ b/IBSW/lib/ibsw_init/init_cpu_0_idle_timing.c @@ -0,0 +1,94 @@ +/** + * @file init_cpu_0_idle_timing.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief CPU 0 idle time recording + * + * ## Overview + * + * Here the CPU power down exit time stamp is recorded. + * + * ## Mode of Operation + * + * The function ibsw_update_cpu_0_idle() is attached to a set of interrupts + * during init. It is subsequently called every time one of these interrupts + * is raised. If the timestamp is not set, it is updated. The timestamp + * is reset in ibsw_mainloop(). + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + */ + + +#include <stdint.h> + +#include <leon/irq.h> +#include <leon/irq_dispatch.h> + +#include <ibsw.h> +#include <leon3_grtimer_longcount.h> + +#include <ibsw_interface.h> + + +/** + * @brief ISR to record time when cpu 0 exits idle mode + * + * @param userdata a pointer to arbitrary user data + */ + +int32_t ibsw_update_cpu_0_idle(void *userdata) +{ + struct ibsw_config *cfg = (struct ibsw_config *) userdata; + + if (!cfg->cpu_0_idle_exit.coarse) + if (!cfg->cpu_0_idle_exit.fine) + grtimer_longcount_get_uptime(cfg->timer.rtu, + &cfg->cpu_0_idle_exit); + + return 0; +} + + +/** + * @brief initialise CPU 0 idle timing interrupts + * + * @param ibsw_cfg a struct ibsw_config + */ + +void ibsw_init_cpu_0_idle_timing(struct ibsw_config *cfg) +{ + cfg->cpu_0_idle_exit.coarse = 0; + cfg->cpu_0_idle_exit.fine = 0; + + irl1_register_callback(GR712_IRL1_GPIO6, PRIORITY_NOW, + ibsw_update_cpu_0_idle, cfg); + irl1_register_callback(GR712_IRL1_AHBSTAT, PRIORITY_NOW, + ibsw_update_cpu_0_idle, cfg); + irl1_register_callback(GR712_IRL1_GPTIMER_0, PRIORITY_NOW, + ibsw_update_cpu_0_idle, cfg); + irl1_register_callback(GR712_IRL1_GPTIMER_1, PRIORITY_NOW, + ibsw_update_cpu_0_idle, cfg); + irl1_register_callback(GR712_IRL1_GPTIMER_2, PRIORITY_NOW, + ibsw_update_cpu_0_idle, cfg); + irl1_register_callback(GR712_IRL1_B1553BRM, PRIORITY_NOW, + ibsw_update_cpu_0_idle, cfg); +} + diff --git a/IBSW/lib/ibsw_init/init_cpus.c b/IBSW/lib/ibsw_init/init_cpus.c new file mode 100644 index 0000000000000000000000000000000000000000..361e191a70cdb5d89fc928f55c7edbddf6eaab30 --- /dev/null +++ b/IBSW/lib/ibsw_init/init_cpus.c @@ -0,0 +1,74 @@ +/** + * @file init_cpus.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief configures the sliding window tx buffers for the 1553 interface + * + * ## Overview + * + * Here the buffers for use with the @ref cpus_buffer are allocated and + * configured. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + */ + + +#include <stdint.h> +#include <stdlib.h> +#include <sys/types.h> + +#include <errors.h> +#include <cpus_buffers.h> + + +/** + * @brief configures the sliding window tx buffers for the 1553 interface + * + * @param pus_buf a reference to a struct cpus_buffers + * + * @return -1 on error, 0 otherwise + */ + +ssize_t ibsw_configure_cpus(struct cpus_buffers *pus_buf) +{ + uint8_t *p_pkts; + uint8_t *p_valid; + + uint16_t *p_size; + + p_pkts = (uint8_t *) malloc(CBUF_PKTS_ELEM * sizeof(uint8_t)); + p_valid = (uint8_t *) malloc(CBUF_VALID_ELEM * sizeof(uint8_t)); + p_size = (uint16_t *) malloc(CBUF_SIZE_ELEM * sizeof(uint16_t)); + + if (!p_pkts || !p_valid || !p_size) { + errno = ENOMEM; + return -1; + } + + cpus_init(pus_buf, p_pkts, p_size, p_valid); + + return 0; +} diff --git a/IBSW/lib/ibsw_init/init_edac.c b/IBSW/lib/ibsw_init/init_edac.c new file mode 100644 index 0000000000000000000000000000000000000000..d2513f2ebeea9c04621b02c3d76e5a08fb484827 --- /dev/null +++ b/IBSW/lib/ibsw_init/init_edac.c @@ -0,0 +1,75 @@ +/** + * @file init_edac.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief configures the EDAC and error trap handlers + * + * ## Overview + * + * Here the memory EDAC is enabled. A trap handler is installed to handle data + * exception traps and the AHBSTAT interrupt is enabled. + * Trap handlers for FP exception and traps that must trigger a controlled reset + * are also enabled here. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + */ + +#include <stdlib.h> + +#include <leon/irq.h> +#include <leon/irq_dispatch.h> + +#include <ibsw_interface.h> + +#include <traps.h> +#include <edac.h> +#include <leon3_dsu.h> +#include <memcfg.h> +#include <traps.h> + + +/** + * @brief configure EDAC and error trap handlers + */ + +int32_t ibsw_configure_edac(void) +{ + edac_set_reset_callback(&fdir_reset, NULL); + + if (edac_init_sysctl()) + return -1; + + memcfg_enable_ram_edac(); + trap_handler_install(0x9, data_access_exception_trap); /* EDAC */ + + trap_handler_install(0x8, floating_point_exception_trap); + + trap_handler_install(0x2, reset_trap); + + irl1_register_callback(GR712_IRL1_AHBSTAT, PRIORITY_NOW, + edac_ahb_irq, NULL); + + return 0; +} diff --git a/IBSW/lib/ibsw_init/init_error_log.c b/IBSW/lib/ibsw_init/init_error_log.c new file mode 100644 index 0000000000000000000000000000000000000000..ebc95195db918522c65239cb97298cc29b83ed88 --- /dev/null +++ b/IBSW/lib/ibsw_init/init_error_log.c @@ -0,0 +1,47 @@ +/** + * @file init_error_log.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief initialises the error log + * + * ## Overview + * + * Here the @ref error_log is configured. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + */ + +#include <error_log.h> + + +/** + * @brief init the error log + * @param error log a pointer to the error log + */ + +void ibsw_configure_error_log(struct error_log **error_log) +{ + error_log_init(error_log); +} diff --git a/IBSW/lib/ibsw_init/init_ptrack.c b/IBSW/lib/ibsw_init/init_ptrack.c new file mode 100644 index 0000000000000000000000000000000000000000..e20bef58c8bda399c3fc85d26c43973fc83cb329 --- /dev/null +++ b/IBSW/lib/ibsw_init/init_ptrack.c @@ -0,0 +1,76 @@ +/** + * @file init_ptrack.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief configures the rx packet buffers for the 1553 interface + * + * ## Overview + * + * Here the buffers for use with the @ref packet_tracker are allocated and + * configured. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + */ + + +#include <stdint.h> +#include <stdlib.h> +#include <sys/types.h> + +#include <errors.h> +#include <packet_tracker.h> + +/** + * @brief configures the rx packet buffers for the 1553 interface + * + * @param pkt a reference to a struct packet_tracker + * + * @param pkts the number of packets to allocate space for + * + * @return -1 on error, 0 otherwise + */ + +ssize_t ibsw_configure_ptrack(struct packet_tracker *pkt, uint32_t pkts) +{ + uint8_t *p_pkts; + + uint16_t *p_size; + + + p_pkts = (uint8_t *) malloc(pkts * PUS_PKT_MIN_SIZE * sizeof(uint8_t)); + p_size = (uint16_t *) malloc(pkts * sizeof(uint16_t)); + + + if (!p_pkts || !p_size) { + errno = ENOMEM; + return -1; + } + + ptrack_init(pkt, + p_pkts, pkts * PUS_PKT_MIN_SIZE, + p_size, pkts); + + return 0; +} diff --git a/IBSW/lib/ibsw_init/init_spw.c b/IBSW/lib/ibsw_init/init_spw.c new file mode 100644 index 0000000000000000000000000000000000000000..61202377cb71c09e0c076685cc24b9a9649cca5a --- /dev/null +++ b/IBSW/lib/ibsw_init/init_spw.c @@ -0,0 +1,186 @@ +/** + * @file init_spw.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief configures the SpW cores + * + * ## Overview + * + * This is the configuration procedure of the SpW interface. + * The device is ungated and the descriptor tables are allocated. + * The descriptor tables of the SpW device must be aligned properly, + * so memory blocks of size + * (GRSPW2_DESCRIPTOR_TABLE_SIZE + GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN) + * are allocated and aligned to GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + */ + +#include <stdint.h> +#include <stdlib.h> + +#include <io.h> +#include <clkgate.h> +#include <grspw2.h> +#include <errors.h> +#include <leon/irq.h> + + +/** + * @brief configure the SpW cores + * + * @param spw a struct grspw2_core_cfg + * @param spw_core_addr the SpW core (hardware) address + * @param spw_core_irq the IRQ number of the SpW core + * @param spw_addr the SpW node address + * @param tx_hdr_size the size of the transmission header + * @param spw_strip_hdr_bytes the number of header bytes to strip in RX packets + * @param gate the SpW core's clock gate in the GR712RC + * + * @return -1 on error, 0 otherwise + */ + +ssize_t ibsw_configure_spw(struct grspw2_core_cfg *spw, uint32_t spw_core_addr, + uint32_t spw_core_irq, uint32_t spw_addr, + uint32_t tx_hdr_size, uint32_t spw_strip_hdr_bytes, + uint32_t gate) +{ + uint32_t flags; + uint32_t mem; + uint32_t *rx_desc_tbl; + uint32_t *tx_desc_tbl; + uint8_t *rx_descs; + uint8_t *tx_descs; + uint8_t *tx_hdr = NULL; + + + /* ungate the spw cores, see GR712RC UM pp. 228 */ + + + flags = ioread32be(&clkgate->unlock); + flags |= gate; + iowrite32be(flags, &clkgate->unlock); + + flags = ioread32be(&clkgate->core_reset); + flags |= gate; + iowrite32be(flags, &clkgate->core_reset); + + flags = ioread32be(&clkgate->clk_enable); + flags |= gate; + iowrite32be(flags, &clkgate->clk_enable); + + flags = ioread32be(&clkgate->core_reset); + flags &= ~gate; + iowrite32be(flags, &clkgate->core_reset); + + flags = ioread32be(&clkgate->unlock); + flags &= ~gate; + iowrite32be(flags, &clkgate->unlock); + + + /** + * malloc a rx and tx descriptor table buffer and align to + * 1024 bytes (GR712UMRC, p. 111) + * + * dynamically allocate memory + 1K for alignment (worst case) + * 1 buffer per dma channel (gr712 cores only implement one) + */ + + mem = (uint32_t) malloc(GRSPW2_DESCRIPTOR_TABLE_SIZE + + GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN); + if (!mem) { + errno = ENOMEM; + return -1; + } + + rx_desc_tbl = (uint32_t *) ((mem + + GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN) + & ~GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN); + + mem = (uint32_t) malloc(GRSPW2_DESCRIPTOR_TABLE_SIZE + + GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN); + if (!mem) { + errno = ENOMEM; + return -1; + } + + tx_desc_tbl = (uint32_t *) ((mem + + GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN) + & ~GRSPW2_DESCRIPTOR_TABLE_MEM_BLOCK_ALIGN); + + /** + * malloc rx and tx data buffers: decriptors * packet size + */ + rx_descs = (uint8_t *) malloc(GRSPW2_RX_DESCRIPTORS + * GRSPW2_DEFAULT_MTU); + + tx_descs = (uint8_t *) malloc(GRSPW2_TX_DESCRIPTORS + * GRSPW2_DEFAULT_MTU); + + if (!rx_descs || !tx_descs) { + errno = ENOMEM; + return -1; + } + + + if (tx_hdr_size) { + tx_hdr = (uint8_t *) malloc(GRSPW2_TX_DESCRIPTORS + * tx_hdr_size); + + if (!tx_hdr) { + errno = ENOMEM; + return -1; + } + } + + /* start: 10 Mhz, run: 10 Mhz */ + /* dpu SpW are already clocked at 10 MHz */ + grspw2_core_init(spw, spw_core_addr, spw_addr, 1, 1, + GRSPW2_DEFAULT_MTU, spw_core_irq, + GR712_IRL1_AHBSTAT, spw_strip_hdr_bytes); + + grspw2_rx_desc_table_init(spw, + rx_desc_tbl, GRSPW2_DESCRIPTOR_TABLE_SIZE, + rx_descs, GRSPW2_DEFAULT_MTU); + + grspw2_tx_desc_table_init(spw, + tx_desc_tbl, GRSPW2_DESCRIPTOR_TABLE_SIZE, + tx_hdr, tx_hdr_size, + tx_descs, GRSPW2_DEFAULT_MTU); + grspw2_core_start(spw); + + + + spw->alloc.rx_desc_tbl = rx_desc_tbl; + spw->alloc.tx_desc_tbl = tx_desc_tbl; + spw->alloc.rx_descs = rx_descs; + spw->alloc.tx_descs = tx_descs; + spw->alloc.tx_hdr = tx_hdr; + spw->alloc.tx_hdr_size = tx_hdr_size; + + + return 0; +} diff --git a/IBSW/lib/ibsw_init/init_sync_timing.c b/IBSW/lib/ibsw_init/init_sync_timing.c new file mode 100644 index 0000000000000000000000000000000000000000..aeedf79259bca5875fab10f37ba6305651b56687 --- /dev/null +++ b/IBSW/lib/ibsw_init/init_sync_timing.c @@ -0,0 +1,116 @@ +/** + * @file init_sync_timing.c + * @ingroup ibsw_config + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief configures timers, syncpulse and 1553 time callback + * + * + * ## Overview + * + * This is the configuration procedure of syncpulse and timing functions. + * GPIO6 is enabled for reception of the sync pulse and callback functions + * are registered to update the synchronisation status. + * + * System timers 1 and 2 are configured for desynchronisation detection and + * recovery and IASW cyclical notification source respectively. + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + */ + + +#include <stdint.h> +#include <stdlib.h> + +#include <leon/leon_reg.h> +#include <timing.h> +#include <leon/irq.h> +#include <leon/irq_dispatch.h> +#include <leon3_gptimer.h> +#include <syncpulse.h> +#include <core1553brm_as250.h> + +#include <ibsw_interface.h> + +/** + * @brief configures the timers + * + * @param timer a struct time_keeper + * @param brm a struct brm_config + * @param spw a struct grspw2_core_cfg + */ + +void ibsw_configure_timing(struct time_keeper *timer, + struct brm_config *brm, + struct grspw2_core_cfg *spw) +{ + timekeeper_init(timer, + (struct gptimer_unit *) LEON3_BASE_ADDRESS_GPTIMER, + (struct grtimer_unit *) LEON3_BASE_ADDRESS_GRTIMER, + brm, spw); +} + + +/** + * @brief configure the syncpulse and 1553 time callback + * + * @param brm a struct brm_config (if configuring for eval board) + * @param timer a struct time_keeper + * + * @note struct time_keeper should be zeroed before calling this function + */ + +void ibsw_configure_1553_sync(struct brm_config __attribute__((unused)) *brm, + struct time_keeper *timer) +{ + grtimer_set_latch_irq(timer->rtu, GR712_IRL1_GPIO6); + + syncpulse_configure_gpio(GR712_IRL1_GPIO6, LEON3_BASE_ADDRESS_GRGPIO_1); + + irl1_register_callback(GR712_IRL1_GPIO6, PRIORITY_NOW, + syncpulse, timer); + + irq_set_level(GR712_IRL1_GPIO6, 1); + + syncpulse_status_set_callback(timer, CrIbSetSyncFlag); + + irl1_register_callback(GR712_IRL1_GPTIMER_2, PRIORITY_NOW, + syncpulse_notification_timer_underflow, timer); + + /* configure syncpulse standin timer, it will fire + * after 1 second + tolerance and execute a similar ISR as the + * syncpulse. + */ + irl1_register_callback(GR712_IRL1_GPTIMER_1, PRIORITY_NOW, + syncpulse_missed, timer); + + gptimer_start(timer->ptu, 1, GPTIMER_TICKS_PER_SEC + T_SYNC_TOL); + + /* start GPTIMER3 in free running mode to guarantee the IASW is running + * even if the sync pulse never arrives + */ + gptimer_start(timer->ptu, 2, T_CYC1); + + irq_set_level(GR712_IRL1_GPTIMER_1, 1); + irq_set_level(GR712_IRL1_GPTIMER_2, 1); +} diff --git a/IBSW/lib/ibsw_interface/ibsw_1553.c b/IBSW/lib/ibsw_interface/ibsw_1553.c new file mode 100644 index 0000000000000000000000000000000000000000..8237db32e72362567eba70e3d34d53754758b644 --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_1553.c @@ -0,0 +1,247 @@ +/** + * @file ibsw_1553.c + * @ingroup ibsw_interface + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements a IBSW <> IASW interface to the 1553 bus + * + * + * ## Overview + * + * ## Mode of Operation + * + * ### CrIbIsMilBusPcktAvail() + * + * This function checks if packets received via the 1553 bus are available. + * + * + * @startuml {CrIbMilBusPcktAvail.svg} "CrIbMilBusPcktAvail()" width=10 + * start + * + * if (GND|OBC) then (yes) + * if (packet in buffer) then (yes) + * :return true; + * stop + * endif + * endif + * :return false; + * stop + * @enduml + * + * Note that this function implements the call interface functionality of: + * + * - CrIbIsObcPcktAvail + * - CrIbIsGrdPcktAvail + * + * as defined in CHEOPS-PNP-INST-DD-001 Rev 4, Section 5.1, to provide a working + * interface, given that the IASW does not adhere to it's own design document. + * + * + * ### CrIbMilBusPcktCollect() + * + * This function returns packets received via the 1553 bus. Usable buffer space + * must be provided by the IASW. + * + * @startuml {CrIbMilBusPcktCollect.svg} "CrIbMilBusPcktCollect()" width=10 + * start + * if (GND|OBC) then (yes) + * if (packet in buffer) then (no) + * :return NULL; + * stop + * endif + * if (pkt = CrFwPcktMake()) then (no) + * :return NULL; + * stop + * endif + * if (get packet) then (no) + * :release pkt; + * :return NULL; + * stop + * endif + * :return pkt; + * stop + * endif + * :return NULL; + * stop + * @enduml + * + * Note that this function implements the call interface functionality of: + * + * - CrIbIsObcPcktCollect + * - CrIbIsGrdPcktCollect + * + * as defined in CHEOPS-PNP-INST-DD-001 Rev 4, Section 5.1, to provide a working + * interface, given that the IASW does not adhere to it's own design document. + + * + * ### CrIbMilBusPcktHandover() + * + * This function attempts to add packet to the outgoing 1553 @ref cpus_buffer. + * If all transfer frames are out of capacity and the packet cannot be added, + * the function returns 0 (false) or not 0 (true). + * + * @startuml {CrIbMilBusPcktHandover.svg} "CrIbMilBusPcktHandover()" width=10 + * start + * :get packet size; + * if (add packet) then (yes) + * :return 1; + * stop + * endif + * + * :return 0; + * stop + * @enduml + * + * + * ### CrIbMilBusGetLinkCapacity() + * + * This function returns the remaining number of bytes relative to the next + * legal 1 kiB sized AS250 transfer frame boundary available in the @ref + * cpus_buffer + * + * @startuml {CrIbMilBusGetLinkCapacity.svg} "CrIbMilBusGetLinkCapacity()" width=10 + * start + * :return frame size; + * stop + * @enduml + * + * ## Error Handling + * + * The caller is responsible to handle errors. If the IASW cannot provide + * a valid buffer via CrFwPcktMake() (which will return a NULL pointer) as + * needed by CrIbMilBusPcktCollect() nothing can be done by the interface and + * a NULL pointer is hence returned. + * + * ## Notes + * + */ + + +#include <stdint.h> + +#include <packet_tracker.h> +#include <cpus_buffers.h> +#include <core1553brm_as250.h> + +#include <ibsw_interface.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <CrConfigIa/CrFwUserConstants.h> + + + +/** + * @brief check if there is a packet available from the 1553 interface + * @return 0 if no packet is available, 1 otherwise + */ + +CrFwBool_t CrIbIsMilBusPcktAvail(CrFwDestSrc_t src) +{ + struct packet_tracker *pkt; + + + switch (src) { + case CR_FW_CLIENT_GRD: + pkt = &ibsw_cfg.pkt_gnd; + break; + case CR_FW_CLIENT_OBC: + pkt = &ibsw_cfg.pkt_obc; + break; + default: + return 0; + } + + if (ptrack_peek_next_pkt_size(pkt)) + return 1; + + return 0; +} + + +/** + * @brief retrieve a packet received via the 1553 bus + * @return pointer to a packet buffer + */ + +CrFwPckt_t CrIbMilBusPcktCollect(CrFwDestSrc_t src) +{ + uint8_t *buf; + int32_t elem; + + struct packet_tracker *pkt; + + + switch (src) { + case CR_FW_CLIENT_GRD: + pkt = &ibsw_cfg.pkt_gnd; + break; + case CR_FW_CLIENT_OBC: + pkt = &ibsw_cfg.pkt_obc; + break; + default: + return NULL; + } + + elem = ptrack_peek_next_pkt_size(pkt); + + if (!elem) + return NULL; + + buf = (uint8_t *) CrFwPcktMake((CrFwPcktLength_t) elem); + + if (!buf) + return NULL; + + elem = ptrack_get_next_pkt(pkt, buf); + + if (!elem) { + CrFwPcktRelease((CrFwPckt_t) buf); + return NULL; + } + + return (CrFwPckt_t) buf; +} + + +/** + * @brief hand over a packet to be put on the 1553 bus + * @return 1 if the packet was accepted, 0 otherwise + */ + +CrFwBool_t CrIbMilBusPcktHandover(CrFwPckt_t pckt) +{ + uint16_t size; + int32_t ret; + + size = ptrack_get_pkt_size((uint8_t *) pckt); + + ret = cpus_push_packet(&ibsw_cfg.pus_buf, (uint8_t *) pckt, size); + + if (ret) + return 0; + + return 1; +} + + +/** + * @brief get the number of bytes available in the current transfer frame + * @return number of bytes available + */ + +uint32_t CrIbMilBusGetLinkCapacity(void) +{ + return cpus_get_free(&ibsw_cfg.pus_buf); +} diff --git a/IBSW/lib/ibsw_interface/ibsw_datapool_update.c b/IBSW/lib/ibsw_interface/ibsw_datapool_update.c new file mode 100644 index 0000000000000000000000000000000000000000..e04f3b8e5b6764fb232f85bd2df82a5062b829a2 --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_datapool_update.c @@ -0,0 +1,458 @@ +/** + * @file ibsw_datapool_update.c + * @ingroup ibsw_interface + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to the IASW datapool + * + */ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> + + +#include <iwf_fpga.h> +#include <iwf_flash.h> +#include <sysctl.h> +#include <error_log.h> +#include <leon/irq.h> + +#include <ibsw_interface.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> +#include <IfswConversions.h> + + + +/** + * @brief fill the datapool with stuff + */ + +void CrIbUpdateDataPoolVariablesWithValuesFromIbswSysctlTree(uint32_t hz) +{ + uint8_t ui8; + uint16_t ui16; + uint32_t ui32; + + struct grtimer_uptime in; + + char buf[256]; + + + ui8 = (uint8_t) ibsw_cfg.timer.watchdog_enabled & 0xff; + CrIaPaste(ISWATCHDOGENABLED_ID, &ui8); + + /* update the synchronization flag ISSYNCHRONIZED_ID */ + CrIbSetSyncFlag(ibsw_cfg.timer.synced & 0x01); + + CrIaPaste(MISSEDMSGCNT_ID, &ibsw_cfg.timer.miltime_desync_cnt); + CrIaPaste(MISSEDPULSECNT_ID, &ibsw_cfg.timer.pulse_desync_cnt); + + ui16 = get_error_log_entires_made_since_IBSW_IASW_started(); + CrIaPaste(NOFERRLOGENTRIES_ID, &ui16); + + ui8 = (uint8_t) ibsw_cfg.cpu0_load & 0xff; + CrIaPaste(CORE0LOAD_ID, &ui8); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + "irl1", buf); + /* reset statistic */ + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + "irl1", "", 0); + ui32 = atoi(buf) * hz; /* to rate per second */ + CrIaPaste(INTERRUPTRATE_ID, &ui32); + + + ui8 = (uint8_t) CrIbGetNotifyCnt(); + CrIaPaste(CYCLICALACTIVITIESCTR_ID, &ui8); + + grtimer_longcount_get_uptime(ibsw_cfg.timer.rtu, &in); + CrIaPaste(UPTIME_ID, &in.coarse); + + + ui32 = ptrack_get_packets_in_buffer(&ibsw_cfg.pkt_obc); + CrIaPaste(OBCINPUTBUFFERPACKETS_ID, &ui32); + ui32 = ptrack_get_packets_in_buffer(&ibsw_cfg.pkt_gnd); + CrIaPaste(GRNDINPUTBUFFERPACKETS_ID, &ui32); + + /* We don't count that. The outgoing packet buffer is only + * dropped when it contains invalid packets. Since we cannot + * tell how many packets are in the buffer because we cannot + * distinguish which are which, this does not make sense. + * OBCOUTDROPPEDPACKETS_ID + * + * same here, packets are dropped by either the SEM or by + * the application software, but never by the driver. + * If we cannot accept a packet to be sent to the SEM, + * the IASW must hold it until a time a TX slot is + * available. + * SEMDROPPEDPACKETS_ID + */ + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_B1553BRM), buf); + /* reset statistic */ + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_B1553BRM), "", 0); + ui8 = (uint8_t)(atoi(buf) * hz & 0xff); /* per second */ + CrIaPaste(IRL1_B1553BRM_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/1553"), + "rx_bytes", buf); + ui32 = atoi(buf); + CrIaPaste(MILBUSBYTESIN_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/1553"), + "tx_bytes", buf); + ui32 = atoi(buf); + CrIaPaste(MILBUSBYTESOUT_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/1553"), + "bytes_dropped", buf); + ui16 = atoi(buf); + CrIaPaste(MILBUSDROPPEDBYTES_ID, &ui16); + + /* set in ibsw interface callback + * SEMROUTE_ID + */ + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/spw0"), + "rx_bytes", buf); + ui32 = atoi(buf); + CrIaPaste(SPW0BYTESIN_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/spw0"), + "tx_bytes", buf); + ui32 = atoi(buf); + CrIaPaste(SPW0BYTESOUT_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/spw1"), + "rx_bytes", buf); + ui32 = atoi(buf); + CrIaPaste(SPW1BYTESIN_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/spw1"), + "tx_bytes", buf); + ui32 = atoi(buf); + CrIaPaste(SPW1BYTESOUT_ID, &ui32); + + + ui8 = (uint8_t) grspw2_get_num_free_tx_desc_avail(&ibsw_cfg.spw0) + & 0xff; + CrIaPaste(SPW0TXDESCAVAIL_ID, &ui8); + + ui8 = (uint8_t) grspw2_get_num_pkts_avail(&ibsw_cfg.spw0) & 0xff; + CrIaPaste(SPW0RXPCKTAVAIL_ID, &ui8); + + ui8 = (uint8_t) grspw2_get_num_free_tx_desc_avail(&ibsw_cfg.spw1) + & 0xff; + CrIaPaste(SPW1TXDESCAVAIL_ID, &ui8); + + ui8 = (uint8_t) grspw2_get_num_pkts_avail(&ibsw_cfg.spw1) & 0xff; + CrIaPaste(SPW1RXPCKTAVAIL_ID, &ui8); + + + /* IRL timer interrupts, multiplied by 8 to get Hz */ + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_0), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_0), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL1_GPTIMER_0_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_1), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_1), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL1_GPTIMER_1_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_2), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_2), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL1_GPTIMER_2_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_3), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPTIMER_3), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL1_GPTIMER_3_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GRTIMER), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GRTIMER), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL1_GRTIMER_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_IRQMP), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_IRQMP), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL1_IRQMP_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/secondary"), + __stringify(GR712_IRL2_GRSPW2_0), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/secondary"), + __stringify(GR712_IRL2_GRSPW2_0), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL2_GRSPW2_0_ID, &ui8); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/secondary"), + __stringify(GR712_IRL2_GRSPW2_1), buf); + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/secondary"), + __stringify(GR712_IRL2_GRSPW2_1), "", 0); + ui8 = (uint8_t)((hz * atoi(buf)) & 0xff); + CrIaPaste(IRL2_GRSPW2_1_ID, &ui8); + + + CrIaPaste(MILCUCCOARSETIME_ID, &ibsw_cfg.timer.mil_cuc_coarse); + + ui16 = (uint16_t) ibsw_cfg.timer.mil_cuc_fine; + CrIaPaste(MILCUCFINETIME_ID, &ui16); + + CrIaPaste(CUCCOARSETIME_ID, &ibsw_cfg.timer.cuc_coarse); + + ui16 = (uint16_t) ibsw_cfg.timer.cuc_fine; + CrIaPaste(CUCFINETIME_ID, &ui16); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_AHBSTAT), buf); + /* reset statistic */ + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_AHBSTAT), "", 0); + + ui8 = (uint8_t) ((atoi(buf) * hz) & 0xff); /* rate per second */ + CrIaPaste(IRL1_AHBSTAT_ID, &ui8); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPIO6), buf); + /* reset statistic */ + sysobj_store_attr(sysset_find_obj(sys_set, "/sys/irq/primary"), + __stringify(GR712_IRL1_GPIO6), "", 0); + + ui8 = (uint8_t) (atoi(buf) & 0xff); + CrIaPaste(IRL1_GRGPIO_6_ID, &ui8); + + + /* dynamic buffers */ + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "dbs", buf); + ui32 = atoi(buf); + CrIaPaste(S1ALLOCDBS_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "sw", buf); + ui32 = atoi(buf); + CrIaPaste(S1ALLOCSW_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "heap", buf); + ui32 = atoi(buf); + CrIaPaste(S1ALLOCHEAP_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "flash", buf); + ui32 = atoi(buf); + CrIaPaste(S1ALLOCFLASH_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "aux", buf); + ui32 = atoi(buf); + CrIaPaste(S1ALLOCAUX_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "res", buf); + ui32 = atoi(buf); + CrIaPaste(S1ALLOCRES_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "swap", buf); + ui32 = atoi(buf); + CrIaPaste(S1ALLOCSWAP_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/mem"), "sdb", buf); + ui32 = atoi(buf); + CrIaPaste(S2ALLOCSCIHEAP_ID, &ui32); + + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/edac"), + "singlefaults", buf); + ui16 = (uint16_t) atoi(buf); + CrIaPaste(EDACSINGLEFAULTS_ID, &ui16); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/edac"), + "doublefaults", buf); + ui8 = (uint8_t) atoi(buf); + CrIaPaste(EDACDOUBLEFAULTS_ID, &ui8); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/edac"), + "lastsingleaddr", buf); + ui32 = atoi(buf); + CrIaPaste(EDACLASTSINGLEFAIL_ID, &ui32); + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/edac"), + "lastdoubleaddr", buf); + ui32 = atoi(buf); + CrIaPaste(EDACDOUBLEFADDR_ID, &ui32); + + + ui8 = ibsw_cfg.isErrLogValid; + CrIaPaste(ISERRLOGVALID_ID, &ui8); +} + + +/** + * @brief data pool update function for FPGA analog values + */ + +void CrIbUpdateDataPoolVariablesWithFpgaValues(void) +{ + uint16_t adcval; + float fval; + + uint16_t tmp16; + + /* BEE and SEM PSU Supply Voltages */ + adcval = fpga_adc_get_adc_p3v3(); + CrIaPaste(ADC_P3V3_RAW_ID, &adcval); + fval = convertToVoltEngVal_DPU(adcval, ADC_P3V3_ID); + CrIaPaste(ADC_P3V3_ID, &fval); + + adcval = fpga_adc_get_adc_p5v(); + CrIaPaste(ADC_P5V_RAW_ID, &adcval); + fval = convertToVoltEngVal_DPU(adcval, ADC_P5V_ID); + CrIaPaste(ADC_P5V_ID, &fval); + + adcval = fpga_adc_get_adc_p1v8(); + CrIaPaste(ADC_P1V8_RAW_ID, &adcval); + fval = convertToVoltEngVal_DPU(adcval, ADC_P1V8_ID); + CrIaPaste(ADC_P1V8_ID, &fval); + + adcval = fpga_adc_get_adc_p2v5(); + CrIaPaste(ADC_P2V5_RAW_ID, &adcval); + fval = convertToVoltEngVal_DPU(adcval, ADC_P2V5_ID); + CrIaPaste(ADC_P2V5_ID, &fval); + + adcval = fpga_adc_get_adc_n5v(); + CrIaPaste(ADC_N5V_RAW_ID, &adcval); + fval = convertToVoltEngVal_DPU(adcval, ADC_N5V_ID); + CrIaPaste(ADC_N5V_ID, &fval); + + adcval = fpga_adc_get_adc_pgnd(); + CrIaPaste(ADC_PGND_RAW_ID, &adcval); + fval = convertToVoltEngVal_DPU(adcval, ADC_PGND_ID); + CrIaPaste(ADC_PGND_ID, &fval); + + adcval = fpga_adc_get_adc_temp1(); + CrIaPaste(ADC_TEMP1_RAW_ID, &adcval); + fval = convertToTempEngVal_DPU(adcval) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMP1_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh1a(); + CrIaPaste(ADC_TEMPOH1A_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH1A_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH1A_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh1b(); + CrIaPaste(ADC_TEMPOH1B_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH1B_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH1B_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh2a(); + CrIaPaste(ADC_TEMPOH2A_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH2A_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH2A_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh2b(); + CrIaPaste(ADC_TEMPOH2B_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH2B_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH2B_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh3a(); + CrIaPaste(ADC_TEMPOH3A_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH3A_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH3A_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh3b(); + CrIaPaste(ADC_TEMPOH3B_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH3B_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH3B_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh4a(); + CrIaPaste(ADC_TEMPOH4A_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH4A_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH4A_ID, &fval); + + adcval = fpga_adc_get_adc_tempoh4b(); + CrIaPaste(ADC_TEMPOH4B_RAW_ID, &adcval); + fval = convertToTempEngVal(adcval, ADC_TEMPOH4B_ID) + CONVERT_KTODEGC; + CrIaPaste(ADC_TEMPOH4B_ID, &fval); + + adcval = fpga_adc_get_sem_p15v(); + CrIaPaste(SEM_P15V_RAW_ID, &adcval); + fval = convertToVoltEngVal_PSU(adcval, SEM_P15V_ID); + CrIaPaste(SEM_P15V_ID, &fval); + + adcval = fpga_adc_get_sem_p30v(); + CrIaPaste(SEM_P30V_RAW_ID, &adcval); + fval = convertToVoltEngVal_PSU(adcval, SEM_P30V_ID); + CrIaPaste(SEM_P30V_ID, &fval); + + adcval = fpga_adc_get_sem_p5v0(); + CrIaPaste(SEM_P5V0_RAW_ID, &adcval); + fval = convertToVoltEngVal_PSU(adcval, SEM_P5V0_ID); + CrIaPaste(SEM_P5V0_ID, &fval); + + adcval = fpga_adc_get_sem_p7v0(); + CrIaPaste(SEM_P7V0_RAW_ID, &adcval); + fval = convertToVoltEngVal_PSU(adcval, SEM_P7V0_ID); + CrIaPaste(SEM_P7V0_ID, &fval); + + adcval = fpga_adc_get_sem_n5v0(); + CrIaPaste(SEM_N5V0_RAW_ID, &adcval); + fval = convertToVoltEngVal_PSU(adcval, SEM_N5V0_ID); + CrIaPaste(SEM_N5V0_ID, &fval); + + + tmp16 = (uint16_t) (fpga_version_reg_get() & 0xFFFF); + CrIaPaste(FPGA_VERSION_ID, &tmp16); + + tmp16 = (uint16_t) (fpga_dpu_status_reg_get() & 0xFFFF); + CrIaPaste(FPGA_DPU_STATUS_ID, &tmp16); + + tmp16 = (uint16_t) (fpga_dpu_addr_reg_get() & 0xFFFF); + CrIaPaste(FPGA_DPU_ADDRESS_ID, &tmp16); + + tmp16 = (uint16_t) (fpga_reset_status_get() & 0xFFFF); + CrIaPaste(FPGA_RESET_STATUS_ID, &tmp16); + + tmp16 = (uint16_t) (fpga_sem_status_reg_get() & 0xFFFF); + CrIaPaste(FPGA_SEM_STATUS_ID, &tmp16); + + tmp16 = (uint16_t) (fpga_oper_heater_status_reg_get() & 0xFFFF); + CrIaPaste(FPGA_OPER_HEATER_STATUS_ID, &tmp16); + + + return; +} + diff --git a/IBSW/lib/ibsw_interface/ibsw_error_log.c b/IBSW/lib/ibsw_interface/ibsw_error_log.c new file mode 100644 index 0000000000000000000000000000000000000000..b4f0ac7c9d715bf9df2ec4f1d5d0e2c14c7436f2 --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_error_log.c @@ -0,0 +1,547 @@ +/** + * @file ibsw_error_log.c + * @ingroup ibsw_interface + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to the error log + * @see IBSW specification rev 6 chapter 7.1 + * + * + * + * ## Overview + * + * ## Mode of Operation + * + * ### RAM error log + * + * A call interface wrapper CrIbLogError() for the IASW to add entries to the + * error log is provided. The wrapper uses a counter to track the number of + * entries added since the boot of the IASW. Note that this is not the same as + * the number of entries in the error log. + * + * The initial configuration of the RAM error log is done during ibsw_init() + * + * + * ### RAM error log dump + * + * The contents of the RAM error log buffer can be dumped into a buffer + * by calling CrIbDumpRamErrorLog(). Entries are added in reverse order from + * last added to oldest. + * + * ### Flash error log dump + * + * This function reads a block page by page until it encounters the end of a + * block. Entries are expected to be in chronological order and are stored in + * one chunk from the start of a page. The end of a chunk is determined from the + * first 8 bytes having all bits set (i.e. empty NAND flash). If the end of a + * chunk is encountered, reading continues with the next page and so on, until + * the end of the block is reached. At the end of the block, the buffer contents + * are reversed, so that the entry order is from newest to oldest. + * + * @note + * This legal due to the size of an error log entry being 20 bytes and a + * flash page being 4096 bytes. If a page is read completely without + * encountering at least 16 empty bytes, the page is therefore invalid or + * does not contain an error log at all. + * In any case, the flash dump function cannot verify if the data read + * indeed consists of error log entries. + * + * + * ### Error log to FLASH + * + * If configured, new entries in the RAM error log are periodically flushed to + * FLASH at the end of an IASW cycle. Each entry is duplicated into two + * different FLASH blocks. After boot and configuration update from Ground, the + * selected FLASH blocks are erased and written with binary dumps of type struct + * error_log_entry extracted from the error log. The page and in-page offsets + * are incremented on each write until the write process encounters an error or + * is deliberately disabled. + * + * + * + * @startuml {error_log_flush.svg} "Error log write to FLASH" width=10 + * start + * + * if (log emtpy) then (yes) + * stop + * endif + * + * if (!ERR_LOG_ENB) then (yes) + * stop + * endif + * + * if (inside SAA) then (yes) + * stop + * endif + * + * if (flash block init) then (no) + * stop + * endif + * + * if (init write) then (error) + * :report error; + * :disable log write; + * stop + * endif + * + * while (log entry?) + * : read entry; + * :write log entry to flash; + * :update page offset; + * if (page exceeded next write) then (yes) + * :next page; + * if (block exceeded) then + * :rotate to next block; + * :break; + * endif + * endif + * endwhile + * + * if (stop write) then (error) + * :report error; + * :disable log write; + * stop + * endif + * + * stop + * @enduml + * + * + * ### Configuration changes + * If the address of one of the FLASH blocks changes during operation, the + * new block is erased and used for writing. + * + * + * ## Error Handling + * + * If an error is encountered during a write of any of the flash blocks, + * an event report is issued. + * + * Errors may occur due to the following causes: + * - the flash unit or block address is invalid + * - the flash block is full and cannot be written + * - the flash device encountered an error during a write and the block is now + * marked invalid + * + * ## Notes + * - at this time, every execution of this function that writes log entries will + * do so at the start of a new page + * + * - an entry in the error log is currently 20 bytes. In order not to + * divide entries between pages, they are never fully written, i.e. the last + * 4 bytes of any page (4096 words/16kiB) will never contain any error log + * data. + * + * - valid log sections in flash pages can be identified by checking for + * flash entries marked empty (0xffffffff) + * + */ + + +#include <stdint.h> +#include <string.h> + +#include <compiler.h> + +#include <iwf_flash.h> +#include <event_report.h> +#include <error_log.h> + + +#include <ibsw_interface.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <errors.h> + + +static uint32_t error_log_entries_made_since_IBSW_IASW_started; + + +compile_time_assert(sizeof(struct error_log_entry) % sizeof(uint32_t) == 0, + ERR_LOG_ENTRY_NOT_MULTIPLE_OF_4); + +/** + * @brief add an entry to the error log in RAM + * + * @param evtId an event id + * @param evtData pointer to a buffer containing ERROR_LOG_INFO_SIZE bytes; + * unused bytes should be zero + */ + +void CrIbLogError(unsigned short evtId, unsigned char *evtData) +{ + CrFwTimeStamp_t time; + + + time = CrIbGetCurrentTime(); + + error_log_add_entry(ibsw_cfg.error_log, (struct event_time *) &time, + (uint16_t) evtId, (uint8_t *) evtData); + + error_log_entries_made_since_IBSW_IASW_started++; +} + + +/** + * @brief get a dump of the error log in order from newest to oldest + */ + +void CrIbDumpRamErrorLog(unsigned char *buf) +{ + error_log_dump_reverse(ibsw_cfg.error_log, (uint8_t *) buf); +} + + +/** + * + * @brief reverse the items in a buffer + * + * @param buf the buffer containing the items + * @param tmp_elem a temporary storage location, minimum size of one item + * @param idx the index to start reversing from + * @param buf_len the number of elements in the buffer + * @param elem_size the storage size of one item + * + * @note + * uses a single buffer and an intermediate single-element swap + * buffer in order to use as little memory as possible + */ + +static void reverse_buffer_by_index(void *buf, void *tmp_elem, + uint32_t idx, uint32_t buf_len, + uint32_t elem_size) +{ + uint32_t i; + + + for (i = 0; i < buf_len; i++) { + + if (i >= idx) { + i += idx; + idx = (buf_len - 1); + continue; + } + + memcpy((uint8_t *) tmp_elem, (uint8_t *) buf + idx * elem_size, + elem_size); + + memcpy((uint8_t *) buf + idx * elem_size, + (uint8_t *) buf + i * elem_size, elem_size); + + memcpy((uint8_t *) buf + i * elem_size, (uint8_t *) tmp_elem, + elem_size); + + idx--; + } +} + + + +/** + * @brief locate and dump an error log in FLASH in order from newest to oldest + * + * @param unit the flash unit + * @param addr the logical flash address + * @param buf a buffer to store the dump into + * + * @return 0 on error, number of flash entries dumped to buffer otherwise + * + * @note this function will at most write a buffer the size of one FLASH block + * @note the supplied buffer also serves as scratch buffer + * + */ + +uint32_t CrIbDumpFlashErrorLog(unsigned int unit, unsigned int addr, char *buf) +{ + + uint32_t idx = 0; + + uint32_t i; + uint32_t block, page, offset; + + struct error_log_entry log_entry; + + struct error_log_entry *log; + + const uint32_t log_entry_len = sizeof(struct error_log_entry) / + sizeof(uint32_t); + + + + flash_reverse_logical_addr(addr, &block, &page, &offset); + + if (flash_init_read(unit, block, page, offset)) + goto exit; + + + log = (struct error_log_entry *) buf; + + + while (1) { + + if ((offset + log_entry_len) >= FLASH_PAGE_SIZE) { + + offset = 0; + page++; + + /* end of block, we're done */ + if (page >= FLASH_PAGES_PER_BLOCK) + break; + + /* might be empty; just break here, since we should have + * alreay collected at least one entry + * if the address does not work at all, we exit above + * anyways + */ + if (flash_init_read(unit, block, page, offset)) + break; + } + + /* retval can be ignored, size checked above */ + flash_read_bypass_edac(unit, 0, (uint32_t *) &log_entry, + log_entry_len); + + offset += log_entry_len; + + /* if first 8 bytes are empty, we can assume that the rest is + * empty as well, since the former hold the time stamps and + * event id + */ + + i = __builtin_popcount(((uint32_t *) &log_entry)[0]) + + __builtin_popcount(((uint32_t *) &log_entry)[1]); + + if (i == (2 * __CHAR_BIT__ * sizeof(uint32_t))) { + offset = FLASH_PAGE_SIZE; + continue; /* go to next page */ + } + + /* add to "log" */ + memcpy((void *) &log[idx], (void *) &log_entry, + sizeof(struct error_log_entry)); + + idx++; + } + + /* the reversing index marker is always the last element */ + reverse_buffer_by_index(log, &log_entry, idx - 1, idx, + sizeof(struct error_log_entry)); + +exit: + return idx; +} + + +/** + * + * @brief get the number of error log entries made since the IBSW/IASW was last + * started + */ + +uint32_t get_error_log_entires_made_since_IBSW_IASW_started(void) +{ + return error_log_entries_made_since_IBSW_IASW_started; +} + + +/** + * @brief update and initialise a flash error log location + * + * @param addr the address from the datapool + * @param unit the unit from the datapool + * + * @param[inout] flash_addr the current logical flash address + * @param[inout] flash_unit the current flash unit + * + * @return 0 if no action, 1 if updated, -1 on error + */ + +static int32_t error_log_flash_init(uint32_t addr, uint16_t unit, + uint32_t *flash_addr, uint32_t *flash_unit) +{ + uint32_t block, page, offset; + uint16_t event_data[2]; + + if ((*flash_addr) == addr) + if ((*flash_unit) == (uint32_t) unit) + return 0; + + (*flash_addr) = addr; + (*flash_unit) = (uint32_t) unit; + + flash_reverse_logical_addr(addr, &block, &page, &offset); + + if (flash_erase_block(unit, block)) + { + if (errno == ERR_FLASH_BLOCK_INVALID) + { + event_data[0] = unit; + event_data[1] = (uint16_t) block; + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_MED_SEV, + CRIA_SERV5_EVT_FL_FBF_BB, event_data, 4); + return -1; + } + else + { + event_report(ERRLOG, HIGH, addr); + return -1; /* errno set in call */ + } + } + + return 1; +} + + +/** + * + * @brief transfer new error log entries to flash + * + * @return number of error log entries moved to flash or -1 on error + * + */ +int32_t error_log_move_to_flash(void) +{ + +#define EL_FLASH_BLOCKS 2 + + int32_t ret; + + uint8_t tmp8; + + uint32_t i, n; + + struct error_log_entry log_entry; + + + static uint32_t el_addr = 0xffffffff; /* NOTE: must be static */ + static uint32_t el_unit = 0xff; /* NOTE: must be static */ + static uint32_t store, el_block, el_page, el_offset; + + static uint8_t err_log_enb; + + + uint16_t get_el_unit[EL_FLASH_BLOCKS]; + uint32_t get_el_addr[EL_FLASH_BLOCKS]; + + const uint32_t log_entry_len = sizeof(struct error_log_entry) / + sizeof(uint32_t); + + const uint32_t log_page_max = log_entry_len * ERROR_LOG_MAX_ENTRIES; + + + /* if the error log was disabled in the previous cycle and that status + * changed, update the status and set isErrLogValid), + */ + CrIaCopy(ERR_LOG_ENB_ID, &tmp8); + + if (!err_log_enb && tmp8) + ibsw_cfg.isErrLogValid = 1; + + err_log_enb = tmp8; /* update status */ + + if (!err_log_enb) /* disabled, abort */ + return -1; + + if (!ibsw_cfg.isErrLogValid) /* invalid, abort */ + return -1; + + CrIaCopy(ISSAAACTIVE_ID, &tmp8); + if (tmp8) + return -1; /* inside SAA, ignore */ + + /* no new log entries */ + if (!error_log_num_entries(ibsw_cfg.error_log)) + return 0; + + + /* if ground changes the current error log location, log writing will + * automatically switch to the new block + */ + + CrIaCopy(EL1_CHIP_ID, &get_el_unit[0]); + CrIaCopy(EL2_CHIP_ID, &get_el_unit[1]); + + CrIaCopy(EL1_ADDR_ID, &get_el_addr[0]); + CrIaCopy(EL2_ADDR_ID, &get_el_addr[1]); + + ret = error_log_flash_init(get_el_addr[store], get_el_unit[store], + &el_addr, &el_unit); + + if (ret == -1) + goto flash_error; + + + /* new block to write */ + if (ret == 1) + flash_reverse_logical_addr(el_addr, &el_block, + &el_page, &el_offset); + + if (flash_init_write(el_unit, el_block, el_page, el_offset)) { + event_report(ERRLOG, HIGH, el_addr); + goto flash_error; + } + + + n = error_log_num_entries(ibsw_cfg.error_log); + + for (i = 0; i < n; i++) { + + if (!error_log_read_entry_raw(ibsw_cfg.error_log, &log_entry)) + break; + + flash_write(el_unit, (uint32_t *) &log_entry, log_entry_len); + + el_offset += log_entry_len; + + if ((el_offset + log_entry_len) > log_page_max) { + + el_page++; + + el_offset = 0; + + if (el_page >= FLASH_PAGES_PER_BLOCK) { + + store++; + + if (store >= EL_FLASH_BLOCKS) + store = 0; + } + + break; /* Break here, or the logic becomes + * nasty. In the few instances where this + * will be the case, we'll catch the + * remaining entries the next IASW cycle + */ + } + } + + if (flash_stop_write(el_unit)) { + event_report(ERRLOG, HIGH, el_addr); + goto flash_error; + } + + + return 0; + + +flash_error: + el_addr = 0xffffffff; + el_unit = 0xff; + ibsw_cfg.isErrLogValid = 0; /* BELG-7/A/T */ + + return -1; +} diff --git a/IBSW/lib/ibsw_interface/ibsw_execute_op.c b/IBSW/lib/ibsw_interface/ibsw_execute_op.c new file mode 100644 index 0000000000000000000000000000000000000000..7d549f73d010dbc841ffb1fbb0fbe332f38faecc --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_execute_op.c @@ -0,0 +1,287 @@ +/** + * @file ibsw_execute_op.c + * @ingroup ibsw_interface + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements a IBSW functions that execute IASW tasks + * + */ +#include <stdint.h> + +#include <leon3_grtimer_longcount.h> +#include <error_log.h> + +#include <ibsw_interface.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <Services/General/CrIaConstants.h> /* for event names */ + + +static unsigned int nOfNotif_ID[N_RT_CONT] = { + NOFNOTIF_1_ID, NOFNOTIF_2_ID, NOFNOTIF_3_ID, NOFNOTIF_4_ID, + NOFNOTIF_5_ID}; + +static unsigned int nOfFuncExec_ID[N_RT_CONT] = { + NOFFUNCEXEC_1_ID, NOFFUNCEXEC_2_ID, NOFFUNCEXEC_3_ID, NOFFUNCEXEC_4_ID, + NOFFUNCEXEC_5_ID}; + +static unsigned int wcetTimeStampFine_ID[N_RT_CONT] = { + WCETTIMESTAMPFINE_1_ID, WCETTIMESTAMPFINE_2_ID, WCETTIMESTAMPFINE_3_ID, + WCETTIMESTAMPFINE_4_ID, WCETTIMESTAMPFINE_5_ID}; + +static unsigned int wcetTimeStampCoarse_ID[N_RT_CONT] = { + WCETTIMESTAMPCOARSE_1_ID, WCETTIMESTAMPCOARSE_2_ID, + WCETTIMESTAMPCOARSE_3_ID, WCETTIMESTAMPCOARSE_4_ID, + WCETTIMESTAMPCOARSE_5_ID}; + +static unsigned int et_ID[N_RT_CONT] = { + WCET_1_ID, WCET_2_ID, WCET_3_ID, WCET_4_ID, WCET_5_ID}; + +static unsigned int etAver_ID[N_RT_CONT] = { + WCETAVER_1_ID, WCETAVER_2_ID, WCETAVER_3_ID, WCETAVER_4_ID, + WCETAVER_5_ID}; + +static unsigned int wcetMax_ID[N_RT_CONT] = { + WCETMAX_1_ID, WCETMAX_2_ID, WCETMAX_3_ID, WCETMAX_4_ID, WCETMAX_5_ID}; + +static unsigned int alpha_ID[N_RT_CONT] = { + THR_MA_A_1_ID, THR_MA_A_2_ID, THR_MA_A_3_ID, THR_MA_A_4_ID, + THR_MA_A_5_ID}; + + +static struct grtimer_uptime cycle_t0; + + +/** + * @brief notify a RT container + * param rt_id RT container ID (1..N_RT_CONT) + */ + +void notify_rt(uint32_t rt_id) +{ + unsigned int rt_idx = rt_id - 1; + unsigned int nOfNotif; + + if (rt_idx >= N_RT_CONT) + return; + + /* increment nOfNotif */ + CrIaCopy(nOfNotif_ID[rt_idx], &nOfNotif); + nOfNotif++; + CrIaPaste(nOfNotif_ID[rt_idx], &nOfNotif); +} + + +void run_rt(uint32_t rt_id, float deadline, void (*behaviour) (void)) +{ + unsigned int rt_idx = rt_id - 1; + + struct grtimer_uptime in; + struct grtimer_uptime out; + float et, wcet, alpha, et_aver; + uint16_t tmp16; + unsigned int tmp32; + unsigned short event_data[2]; + CrFwTimeStamp_t time; + + /* increment nOfFuncExec */ + CrIaCopy(nOfFuncExec_ID[rt_idx], &tmp32); + tmp32++; + CrIaPaste(nOfFuncExec_ID[rt_idx], &tmp32); + + /* make timestamp */ + grtimer_longcount_get_uptime(ibsw_cfg.timer.rtu, &in); + + /* execute container-specific behaviour */ + behaviour(); + + /* retrieve execution time */ + grtimer_longcount_get_uptime(ibsw_cfg.timer.rtu, &out); + et = grtimer_longcount_difftime(ibsw_cfg.timer.rtu, out, in); + + /* check if it is beyond deadline and emit an event if so */ + if (deadline != 0.0f) { + if (et >= deadline) { + event_data[0] = rt_id; + /* extent of overrun is reported in ms */ + tmp32 = (unsigned int)(1000 * (et-deadline)); + + /* saturate at 16 bit */ + if (tmp32 > 0xffff) + event_data[1] = 0xffff; + else + event_data[1] = (unsigned short) tmp32; + + + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_HIGH_SEV, + CRIA_SERV5_EVT_THRD_OR, event_data, 4); + } + } + + /* enter (WC)ET in Thread Log */ + CrIaPaste(et_ID[rt_idx], &et); + + /* compute average ET */ + CrIaCopy(alpha_ID[rt_idx], &alpha); + CrIaCopy(etAver_ID[rt_idx], &et_aver); + + et_aver = alpha * et_aver + (1.0 - alpha) * et; + CrIaPaste(etAver_ID[rt_idx], &et_aver); + + /* compare ET with WCET (MAX) */ + CrIaCopy(wcetMax_ID[rt_idx], &wcet); + + if (et >= wcet) { + CrIaPaste(wcetMax_ID[rt_idx], &et); + + /* enter current timestamp of the WCET in the Thread Log */ + time = CrIbGetCurrentTime(); + tmp32 = ((uint32_t) time.t[0] << 24) | + ((uint32_t) time.t[1] << 16) | + ((uint32_t) time.t[2] << 8) | + (uint32_t) time.t[3]; + + tmp16 = ((uint16_t)time.t[4] << 8) | ((uint16_t)time.t[5]); + CrIaPaste(wcetTimeStampFine_ID[rt_idx], &tmp16); + CrIaPaste(wcetTimeStampCoarse_ID[rt_idx], &tmp32); + } +} + + +void execute_cyclical(void) +{ + notify_rt(RTCONT_CYC); + + run_rt(RTCONT_CYC, DEADLINE_CYC, CrIaExecCycActivities); +} + + +void wrap_error_log_move_to_flash(void) +{ + /* to ignore the return value */ + error_log_move_to_flash(); +} + + +void execute_log_move_to_flash(void) +{ + notify_rt(RTCONT_ERRLOG); + + run_rt(RTCONT_ERRLOG, DEADLINE_ERRLOG, wrap_error_log_move_to_flash); +} + + +void flash_functional_behaviour(void) +{ + uint32_t ready = 0; + struct grtimer_uptime now; + double trem; + uint8_t incStepCnt = 1; + uint32_t flashContStepCnt; + + if (flash_operation.isReady) + return; /* nothing to do */ + + grtimer_longcount_get_uptime(ibsw_cfg.timer.rtu, &now); + trem = grtimer_longcount_difftime(ibsw_cfg.timer.rtu, now, cycle_t0); + + while (!ready && (trem < RUNBEFORE_FLASH)) { + switch (flash_operation.op) { + case WRITE: + + ready = CrIbFbfWriteBlock(flash_operation.fbf, + flash_operation.mem); + break; + + case READ: + + ready = CrIbFbfReadBlock(flash_operation.fbf, + (uint32_t) flash_operation.block, + flash_operation.mem); + break; + + default: + break; + } + + grtimer_longcount_get_uptime(ibsw_cfg.timer.rtu, &now); + trem = grtimer_longcount_difftime(ibsw_cfg.timer.rtu, now, cycle_t0); + + /* increment step counter if entered while-loop the first time */ + if(incStepCnt) { + CrIaCopy(FLASHCONTSTEPCNT_ID, &flashContStepCnt); + flashContStepCnt++; + CrIaPaste(FLASHCONTSTEPCNT_ID, &flashContStepCnt); + incStepCnt = 0; + } + } + + flash_operation.isReady = ready; + + if (flash_operation.isReady) { + /* reset the step counter to zero */ + flashContStepCnt = 0; + CrIaPaste(FLASHCONTSTEPCNT_ID, &flashContStepCnt); + } +} + + +/** + * @brief execute the FLASH reader/writer + * + * @param t0 a timestamp of type struct grtimer_uptime + */ + +void execute_flash_op(struct grtimer_uptime t0) +{ + /* make the timestamp of the start of the cycle available to the + * functional behaviour + */ + cycle_t0 = t0; + + notify_rt(RTCONT_FLASH); + + run_rt(RTCONT_FLASH, DEADLINE_FLASH, flash_functional_behaviour); +} + + +/** + * @brief execute the Compression on the second core through RT cont 5 + * + */ + +void execute_acquisition(void) +{ + notify_rt(RTCONT_ACQ); + + /* run_rt(RTCONT_ACQ, DEADLINE_ACQ, wake_core2_for_acquisition); */ + cpu1_notification(SDP_STATUS_ACQUISITION); +} + + +/** + * @brief execute the Compression on the second core through RT cont 5 + * + */ + +void execute_compression(void) +{ + notify_rt(RTCONT_CMPR); + + /* run_rt(RTCONT_CMPR, DEADLINE_CMPR, wake_core2_for_compression); */ + cpu1_notification(SDP_STATUS_SCIENCE); +} diff --git a/IBSW/lib/ibsw_interface/ibsw_fbf.c b/IBSW/lib/ibsw_interface/ibsw_fbf.c new file mode 100644 index 0000000000000000000000000000000000000000..c8eb1f3a90faed1abb9ce7cae54ff366fdb9c53d --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_fbf.c @@ -0,0 +1,537 @@ +/** + * @file ibsw_fbf.c + * @ingroup ibsw_interface + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to the FLASH + * + * ## Overview + * + * These are functions to read and write flash based files. The functions + * CrIbFbfOpen() and CrIbFbfClose() set entries in the data pool for the IASW. + * CrIbFbfReadBlock() and CrIbFbfWriteBlock() contain the logic for reading and + * writing a block with a granularity of one page per call. These functions are + * executed in execute_flash_op(). + * + * The functions CrIbFlashTriggerRead() and CrIbFlashTriggerWrite() are used + * by the IASW to start a read or write operation. The state of the flash + * operation may be queried by calling CrIbFlashIsReady(). + * + * ## Mode of Operation + * + * ### CrIbFbfReadBlock() + * + * @startuml + * + * start + * + * if (!page) then (yes) + * :load FBF address; + * :load chip id; + * :translate address; + * :add block offset; + * endif + * + * if (init read ok) then (yes) + * :get edac statistic; + * :read page; + * :get edac statistic; + * if (FLASH EDAC occured) then (yes) + * if (init read ok) then (yes) + * :get edac statistic; + * :read page; + * :get edac statistic; + * if (FLASH EDAC occured) then (yes) + * :issue event report; + * :set FBF invalid; + * :set page = 0; + * :return 1; + * stop + * endif + * + * else + * :issue event report; + * :set FBF invalid; + * :set page = 0; + * :return 1; + * stop + * endif + * + * endif + * + * :increment page; + * if (page < FLASH_PAGES_PER_BLOCK) then (yes) + * :return 0; + * stop + * endif + * else + * :issue event report; + * :set FBF invalid; + * endif + * + * :set page = 0; + * :return 1; + * stop + * + * @enduml + * + * + * This function returns 0 if more read operations are pending, or 1 on success + * or error. If an error occured, an event report is generated. + * + * As the IWF FLASH sometimes generates false-positive EDAC events, the FLASH + * EDAC statistic is compared to the value before a page read. If an event + * occured, the page is immedialtely re-read once. If an EDAC error occures + * again, the FBF is considered invalid. + * + * + * + * ### CrIbFbfWriteBlock() + * + * + * @startuml + * + * start + * + * if (!page) then (yes) + * if (!FBF open) then (no) + * :return 1; + * stop + * endif + * if (FBF next block > FBF size) then (yes) + * :return 1; + * stop + * endif + * if (!FBF enabled) then (yes) + * :return 1; + * stop + * endif + * if (!FBF valid) then (yes) + * :return 1; + * stop + * endif + * if (SAA active) then (yes) + * :return 1; + * stop + * endif + * :load FBF address; + * :load chip id; + * :translate address; + * :erase block; + * endif + * + * if (init write ok) then (yes) + * :write page; + * :increment page; + * if (page < FLASH_PAGES_PER_BLOCK) then (yes) + * :return 0; + * stop + * endif + * else + * :issue event report; + * :set FBF invalid; + * endif + * + * :set page = 0; + * if (write ok) then (yes) + * :increment FBF next block; + * else + * :issue event report; + * :set FBF invalid; + * endif + * :return 1; + * stop + * + * @enduml + * + * + * This function returns 0 if more write operations are pending, or 1 on success + * or error. If an error occured during a flash operation, an event report is + * generated. When performing a write cycle and 1 is returned on the initial + * call of this function, either the configuration in the IASW datapool for + * the FBF is invalid or the SAA flag is active. Note that this function does + * not abort already ongoing FLASH writes when the SAA is entered. + * + * + * ## Error Handling + * + * If either CrIbFbfReadBlock() or CrIbFbfWriteBlock() encounter an error, it is + * reported through the event report interface. + * + * ## Notes + * + * None + * + */ +#include <stdint.h> +#include <stdlib.h> + +#include <iwf_flash.h> +#include <event_report.h> + +#include <ibsw_interface.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <errors.h> + + +uint32_t edac_err_cnt = 0; /* Mantis 2209 */ + + +/** + * @brief open a flash-based file + * + * @param fbf the number of the flash-based file + */ + +void CrIbFbfOpen(uint32_t fbf) +{ + uint8_t tmp8; + + uint16_t tmp16; + + + CrIaCopyArrayItem(ISFBFOPEN_ID, &tmp8, fbf); + + if (tmp8) + return; + + + tmp16 = 0; + CrIaPasteArrayItem(FBFNBLOCKS_ID, &tmp16, fbf); + + tmp8 = 1; + CrIaPasteArrayItem(ISFBFOPEN_ID, &tmp8, fbf); +} + + +/** + * @brief close a flash-based file + * + * @param fbf the number of the flash-based file + * + */ + +void CrIbFbfClose(uint32_t fbf) +{ + uint8_t tmp8 = 0; + + CrIaPasteArrayItem(ISFBFOPEN_ID, &tmp8, fbf); +} + + +/** + * @brief read a block from a flash-based file + * + * @param fbf the number of the flash-based file + * @param fbf_block the number of the block (withing the fbf) to read + * @param buf a pointer to a memory buffer to copy the block data to + * + * @return 0 if reads are pending, 1 otherwise + * + * @note This function remembers its last read position and will continue until + * the flash block is fully read. Only the buffer reference can be updated + * until the block read is complete, all other inputs are ignored. + */ + +uint32_t CrIbFbfReadBlock(uint32_t fbf, uint32_t fbf_block, uint32_t *buf) +{ + uint8_t tmp8; + + uint16_t tmp16; + + static uint32_t addr, unit, block, page, offset; + uint32_t retry_page = 0; + + char cb[16]; + + + if (page) + goto read_continue; + + + CrIaCopyArrayItem(FBF_ADDR_ID, &addr, fbf); + + CrIaCopyArrayItem(FBF_CHIP_ID, &tmp16, fbf); + unit = (uint32_t) tmp16; + + flash_reverse_logical_addr(addr, &block, &page, &offset); + + block += fbf_block; + + +read_continue: + + if (flash_init_read(unit, block, page, 0)) + goto read_error; + + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/edac"), + "flash_errors", cb); + edac_err_cnt = strtoul(cb, NULL, 10); + + if (flash_read(unit, 0, buf + page * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE)) + goto read_error; + + /* if the FLASH EDAC error counter incremented, retry once */ + sysobj_show_attr(sysset_find_obj(sys_set, "/sys/edac"), + "flash_errors", cb); + + if (edac_err_cnt < strtoul(cb, NULL, 10)) { + if (!retry_page) { + retry_page = 1; + goto read_continue; + } else { + goto read_error; + } + } + + + page++; + + + if (page < FLASH_PAGES_PER_BLOCK) + return 0; + + goto read_complete; + + + /* this is only relevant if bad block reads are not allowed */ +read_error: + + /* we do not want to report a read of an empty page */ + if (errno != ERR_FLASH_ADDR_EMPTY) + event_report(FBF, HIGH, fbf+1); + + tmp8 = 0; + CrIaCopyArrayItem(ISFBFVALID_ID, &tmp8, fbf); + + +read_complete: + + page = 0; + + return 1; +} + + +/** + * @brief write a block to a flash-based file + * + * @param fbf the number of the flash-based file + * @param buf a pointer to a memory buffer to copy the block data from + * @note the memory buffer is expected to be the size of a flash block + * + * @return 0 if writes are pending, 1 otherwise + * + * + * @note this function remembers its last write position and will continue until + * the flash block is fully written + */ + +uint32_t CrIbFbfWriteBlock(uint32_t fbf, uint32_t *buf) +{ + uint8_t tmp8; + + uint16_t tmp16, event_data[2]; + + static uint16_t n_blocks; + + static uint32_t addr, unit, block, page, offset; + + + if (page) + goto write_continue; /* this block is already initialised */ + + + + CrIaCopyArrayItem(ISFBFOPEN_ID, &tmp8, fbf); + + if (!tmp8) + return 1; /* file not open */ + + + CrIaCopyArrayItem(FBFNBLOCKS_ID, &n_blocks, fbf); + + if (!(n_blocks < FBF_SIZE)) + return 1; /* full */ + + + CrIaCopyArrayItem(FBF_ENB_ID, &tmp8, fbf); + + if (!tmp8) + return 1; /* file not enabled */ + + + CrIaCopyArrayItem(ISFBFVALID_ID, &tmp8, fbf); + + if (!tmp8) + return 1; /* file not valid */ + + + CrIaCopy(ISSAAACTIVE_ID, &tmp8); + + if (tmp8) + return 1; /* inside SAA */ + + + + CrIaCopyArrayItem(FBF_ADDR_ID, &addr, fbf); + + CrIaCopyArrayItem(FBF_CHIP_ID, &tmp16, fbf); + unit = (uint32_t) tmp16; + + flash_reverse_logical_addr(addr, &block, &page, &offset); + + + if (flash_erase_block(unit, block + n_blocks)) + { + if (errno == ERR_FLASH_BLOCK_INVALID) + { + /* corresponds to N1 */ + event_data[0] = unit; + event_data[1] = (uint16_t) block; + CrIaEvtRaise(CRIA_SERV5_EVT_ERR_MED_SEV, + CRIA_SERV5_EVT_FL_FBF_BB, event_data, 4); + goto write_error; + } + else + { + /* corresponds to N3 */ + event_report(FBF, HIGH, fbf+1); + goto write_error; + } + } + +write_continue: + + if (flash_init_write(unit, block + n_blocks, page, 0)) + { + /* corresponds to N3 */ + event_report(FBF, HIGH, fbf+1); + goto write_error; + } + + + flash_write(unit, buf + page * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE); + page++; + + + if (flash_stop_write(unit)) + { + /* corresponds to N3 */ + event_report(FBF, HIGH, fbf+1); + goto write_error; + } + + + if (page < FLASH_PAGES_PER_BLOCK) + return 0; + + + n_blocks++; + CrIaPasteArrayItem(FBFNBLOCKS_ID, &n_blocks, fbf); + + goto write_complete; + + +write_error: + + tmp8 = 0; + CrIaPasteArrayItem(ISFBFVALID_ID, &tmp8, fbf); + +write_complete: + + page = 0; + + return 1; +} + + +/** + * @brief trigger a read operation on the flash via the FLASH operation thread + * @param fbf the flash based file id + * @param block the flash block + * @param mem the memory to read to + * + * return -1 on failure, 0 otherwise + */ + +int32_t CrIbFlashTriggerRead(uint8_t fbf, uint16_t block, uint32_t *mem) +{ + uint32_t tmp; + + + if (!flash_operation.isReady) + return -1; + + flash_operation.fbf = fbf; + flash_operation.block = block; + flash_operation.mem = mem; + flash_operation.isReady = 0; + flash_operation.op = READ; + flash_operation.error = 0; + + CrIaCopy(NOFFUNCEXEC_2_ID, &tmp); + tmp++; + CrIaPaste(NOFFUNCEXEC_2_ID, &tmp); + + return 0; +} + + +/** + * @brief trigger a write operation on the flash via the FLASH operation + * thread + * @param fbf the flash based file id + * @param mem the memory to write from + * + * return -1 on failure, 0 otherwise + */ + +int32_t CrIbFlashTriggerWrite(uint8_t fbf, uint32_t *mem) +{ + uint32_t tmp; + + + if (!flash_operation.isReady) + return -1; + + flash_operation.fbf = fbf; + flash_operation.mem = mem; + flash_operation.isReady = 0; + flash_operation.op = WRITE; + flash_operation.error = 0; + + CrIaCopy(NOFFUNCEXEC_2_ID, &tmp); + tmp++; + CrIaPaste(NOFFUNCEXEC_2_ID, &tmp); + + + return 0; +} + + +/** + * @brief query the status of the flash operation + * + * @return 0 if busy (read/write ongoing) + */ + +uint8_t CrIbFlashIsReady(void) +{ + return flash_operation.isReady; +} diff --git a/IBSW/lib/ibsw_interface/ibsw_interface.c b/IBSW/lib/ibsw_interface/ibsw_interface.c new file mode 100644 index 0000000000000000000000000000000000000000..46c90fcf2821ce87e006561077b44aa2f67f8f02 --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_interface.c @@ -0,0 +1,47 @@ +/** + * @file ibsw_interface.c + * @ingroup ibsw_interface + * @author Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup ibsw_interface IBSW <> IASW interface + * @brief implements the specified IBSW <> IASW interface + * + * + * ## Overview + * + * This group of functions implement interfaces for the IASW. + * + * ## Mode of Operation + * + * Please check out the detailed description sections of the various member + * files. + * + * ## Error Handling + * + * Error handling is specific to a components. + * + * ## Notes + * + * None. + * + */ + +#include <ibsw_interface.h> + +/* no way around a global due to the interface design */ +struct ibsw_config ibsw_cfg; +struct flash_operation flash_operation; + + diff --git a/IBSW/lib/ibsw_interface/ibsw_memscrub.c b/IBSW/lib/ibsw_interface/ibsw_memscrub.c new file mode 100644 index 0000000000000000000000000000000000000000..f52551c470f44b171589ec11f0b170bb0a7ef247 --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_memscrub.c @@ -0,0 +1,157 @@ +/** + * @file ibsw_memscrub.c + * @ingroup ibsw_interface + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to memory scrubbing + * + * + * ## Overview + * + * These are functions to execute a memory scrubbing and repair cycle. + * + * ## Mode of Operation + * + * ### CrIbScrubMemory() + * + * This function executes a scrub cycle on the selected RAM area from the last + * scrubbed position. The scrub position will wrap to the start of the memory + * if the upper boundary is exceeded. + * + * @note Since memscrub() executes a scrub as an array addr[0] ... addr[n], + * every call to this function will scrub at least one memory address even if + * the length argument is 0. If you do not want to scrub, do not call this + * function. + * + * ### CrIbMemRepair() + * + * This is a name-comliant wrapper call to memscrub_repair() + * + * ### CrIbInjectFault() + * + * This function can be used to inject invalid data word/EDAC checkbit + * combinations into memory for EDAC testing purposes. + * + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * @brief memory scrubbing of a range addr[0] ... addr[n] at a time + */ + +#include <stdint.h> + +#include <edac.h> +#include <memcfg.h> +#include <memscrub.h> +#include <wrap_malloc.h> + +#include <ibsw_interface.h> + + +/** + * @brief execute the scrubbing operation + * @param pos the starting position in memory + * @param mem_start the lower bound of the memory region + * @param mem_end the upper bound of the memory region + * @param scrubLen the number of 32bit words to scrub + */ + +static uint32_t execute_scrub(uint32_t pos, uint32_t mem_start, + uint32_t mem_end, uint32_t scrubLen) +{ + if (pos >= mem_end) + pos = mem_start; + + if (pos < mem_start) + pos = mem_start; + + if ((mem_end - pos) < (scrubLen * sizeof(uint32_t))) + scrubLen = (mem_end - pos) / sizeof(uint32_t); + + return (uint32_t) memscrub((uint32_t *) pos, scrubLen); +} + + +/** + * @brief High level memory scrubber. This finds errors and enters them in the + * scrublist for later repair. + * @param memId the id of the memory to scrub + * @param scubLen the number of 32 bit words to scrub + * + * @return last scrubbed address or 0 on error + */ + +uint32_t CrIbScrubMemory(enum scrubmem memId, uint32_t scrubLen) +{ + uint32_t addr = 0; + + uint32_t sram1_scrub_pos; + uint32_t sram2_scrub_pos; + + CrIaCopy(SRAM1SCRCURRADDR_ID, &sram1_scrub_pos); + CrIaCopy(SRAM2SCRCURRADDR_ID, &sram2_scrub_pos); + + switch (memId) { + + case SRAM1_ID: + addr = execute_scrub(sram1_scrub_pos, SRAM1_ADDR, + SRAM1_END, scrubLen); + sram1_scrub_pos = addr; + break; + + case SRAM2_ID: + addr = execute_scrub(sram2_scrub_pos, SRAM2_ADDR, + SRAM2_END, scrubLen); + sram2_scrub_pos = addr; + } + + CrIaPaste(SRAM1SCRCURRADDR_ID, &sram1_scrub_pos); + CrIaPaste(SRAM2SCRCURRADDR_ID, &sram2_scrub_pos); + + return addr; +} + + +/** + * @brief Repairs addresses that were entered in the scrublist. + */ + +uint32_t CrIbMemRepair(void) +{ + return memscrub_repair(); +} + + +/** + * @brief write a faulty value/edac check bit combination to a memory location + * + * @param mem_value a 32-bit value to write to memory + * @param edac_value a 32-bit value to use as input for the calculation of + * the edac checkbits + * @param addr a pointer to a memory location + * + * @note mem_value and edac_value should be off by one or two bits to inject a + * single or double fault respectively, otherwise the outcome may be + * either + */ + +void CrIbInjectFault(uint32_t mem_value, uint32_t edac_value, void *addr) +{ + memcfg_bypass_write(addr, mem_value, edac_checkbits(edac_value)); +} diff --git a/IBSW/lib/ibsw_interface/ibsw_spw.c b/IBSW/lib/ibsw_interface/ibsw_spw.c new file mode 100644 index 0000000000000000000000000000000000000000..3222c5f54ee01df3ded45d1871a3025612550cd0 --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_spw.c @@ -0,0 +1,393 @@ +/** + * @file ibsw_spw.c + * @ingroup ibsw_interface + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to the SpaceWire device + * + * + * ## Overview + * + * These are function to "collect" and "hand over" packets from and to the SpW + * interface to the SEM. These function calls are part of the + * IASW/CrFramework/FwProfile input/output scheme. + * + * ## Mode of Operation + * + * ### CrIbIsSemPcktAvail() + * + * @startuml + * + * start + * + * if (packets delivered < MAX_SEM_PCKT_CYC) then (yes) + * if (SpW packets available) then (yes) + * if (packet size ok) then (yes) + * :return 1; + * stop + * else + * :drop packet; + * endif + * endif + * endif + * :return 0; + * stop + * + * @enduml + * + * This function checks if at least one packet has been received on the SpW + * interface. If the packet size is within bounds, 1 is returned otherwise the + * packet is dropped. In this and any other case, 0 is returned. + * + * This function will always return 0 if a certain number of packets has been + * reported to the IASW to be available. This is done since the IASW would keep + * "collecting" packets as long as the SpW interface has packets available, + * regardless of the available slots in its own memory pool and consequently + * crash. + * + * Note that this function does explicitly not attempt to allocate an IASW + * packet slot before it reports a packet available. + * + * ### CrIbSemPcktCollect() + * + * @startuml + * + * start + * if (get next packet size) then (yes) + * if (request packet slot from pool) then (yes) + * if (retrieve packet) then (yes) + * :return packet; + * stop + * else + * :release packet slot; + * endif + * endif + * endif + * + * + * :return NULL; + * stop + * + * @enduml + * + * + * This function attempts to retrieve a packet from the SpW interface. If the + * packet cannot be retrieved, it will return NULL. The memory pool from which + * the packet store is allocated is maintained by the IASW, which also + * deallocates the packet slot. If the IASW cannot supply the required memory to + * store a packet, the function also returns NULL. If an error occurs during + * retrieval of the SpW packet, the function released the packet slot back into + * the memory pool and returns NULL. In case of success, the pointer to the + * packet slot is returned. + * + * + * ### CrIbSemPcktHandover() + * + * @startuml + * + * start + * if (packet size ok) then (yes) + * if (add outgoing packet) then (yes) + * : return 1; + * stop + * endif + * endif + * + * :return 0; + * stop + * + * @enduml + * + * This function accepts a buffer containing a single packet for transmission. + * The packet size field is inspected. If the packet size exceeds the maximum + * size of a transport unit configured in the SpW device, 0 is returned to + * indicate that the packet was not accepted, otherwise the packet is added + * to the SpaceWire transmit buffer and 1 is return to indicate success. + * If an error occurs while handing the packet over to the driver, 0 is + * returned. + * + * ## SpaceWire Routing + * + * For development, testing and on-ground calibration purposes, fast packet + * routing may be enabled between SpaceWire ports 0 and 1, thereby bypassing + * the IASW. These are not part of the nominal flight software. + * + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + * + */ +#include <stdint.h> + +#include <packet_tracker.h> +#include <grspw2.h> + +#include <ibsw_interface.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +#include <ibsw.h> +#include <clkgate.h> +#include <leon/irq.h> + +#define SPW_MIN_MTU 18 +#define SES_ADDR 68 +#define SES_PROTOCOL_ID 2 +#define SES_HEADER_BYTES 4 + + +/** + * @brief check if the SpW link to SEM is in RUN state + * @return 0 if running, 1 otherwise + */ + +CrFwBool_t CrIbIsSEMLinkRunning(void) +{ + return (grspw2_get_link_status(&ibsw_cfg.spw1) == GRSPW2_STATUS_LS_RUN); +} + +/** + * @brief check if the SpW link to the EGSE is in RUN state + * @return 0 if running, 1 otherwise + */ + +CrFwBool_t CrIbIsEGSELinkRunning(void) +{ + return (grspw2_get_link_status(&ibsw_cfg.spw0) == GRSPW2_STATUS_LS_RUN); +} + +/** + * @brief check if there is a packet available from the SpW + * @return 0 if no packet is available, 1 otherwise + */ + +CrFwBool_t CrIbIsSemPcktAvail(__attribute__((unused)) CrFwDestSrc_t src) +{ + static uint32_t cycle = 1234; + static uint32_t pckts_delivered; + int32_t elem; + uint32_t max_sem_pckt_cyc; + + pckts_delivered++; + + if (cycle != CrIbGetNotifyCnt()) { + cycle = CrIbGetNotifyCnt(); + pckts_delivered = 0; + } + + CrIaCopy(MAX_SEM_PCKT_CYC_ID, &max_sem_pckt_cyc); + + if (pckts_delivered >= max_sem_pckt_cyc) + return 0; + + if (grspw2_get_num_pkts_avail(&ibsw_cfg.spw1)) { + + elem = grspw2_get_next_pkt_size(&ibsw_cfg.spw1); + + if (elem >= SPW_MIN_MTU) + if (elem <= GRSPW2_DEFAULT_MTU) + return 1; + + /* discard packet from descriptor table if size is too small + * or too large + */ + grspw2_drop_pkt(&ibsw_cfg.spw1); + } + + return 0; +} + + +CrFwPckt_t CrIbSemPcktCollect(__attribute__((unused)) CrFwDestSrc_t src) +{ + uint8_t *buf; + int32_t elem; + + /* what a waste of cycles, clueless interface design + * at least the caches are already primed afterwards... + */ + elem = grspw2_get_next_pkt_size(&ibsw_cfg.spw1); + + if (!elem) + return NULL; + + buf = (uint8_t *) CrFwPcktMake((CrFwPcktLength_t) elem); + + if (!buf) + return NULL; + + elem = grspw2_get_pkt(&ibsw_cfg.spw1, buf); + + if (!elem) { + CrFwPcktRelease((CrFwPckt_t) buf); + return NULL; + } + + return (char *) buf; +} + + +/** + * @brief hand over a packet to be sent via SpaceWire + * @return 1 if the packet was accepted, 0 otherwise + */ + + +CrFwBool_t CrIbSemPcktHandover(CrFwPckt_t pckt) +{ + uint16_t size; + int32_t ret; + + static const uint8_t hdr[4] = {SES_ADDR, + SES_PROTOCOL_ID, 0, 0}; + + + size = ptrack_get_pkt_size((uint8_t *) pckt); + + if (size > GRSPW2_DEFAULT_MTU) + return 0; + + ret = grspw2_add_pkt(&ibsw_cfg.spw1, hdr, SES_HEADER_BYTES, + (uint8_t *) pckt, size); + + if (ret) + return 0; + + return 1; +} + + +/** + * @brief disable SEM SpW link error interrupts + */ + +void CrIbDisableSemSpWLinkErrorIRQ(void) +{ + grspw2_unset_link_error_irq(&ibsw_cfg.spw1); +} + + +/** + * @brief enable SEM SpW link error interrupts + */ + +void CrIbEnableSemSpWLinkErrorIRQ(void) +{ + grspw2_set_link_error_irq(&ibsw_cfg.spw1); +} + +#if (__SPW_ROUTING__) + +/** + * @brief disable MON SpW link error interrupts + */ + +void CrIbDisableMonSpWLinkErrorIRQ(void) +{ + grspw2_unset_link_error_irq(&ibsw_cfg.spw0); +} + + +/** + * @brief enable MON SpW link error interrupts + */ + +void CrIbEnableMonSpWLinkErrorIRQ(void) +{ + grspw2_set_link_error_irq(&ibsw_cfg.spw0); +} + +/** + * @brief enable direct routing between SpW0 and SpW1 + */ + +void CrIbEnableSpWRoutingNOIRQ(void) +{ + grspw2_enable_routing_noirq(&ibsw_cfg.spw1, &ibsw_cfg.spw0); +} + + +/** + * @brief perfom one routing cycle from SpW0 to SpW1 + */ + +void CrIbSpWRoute(void) +{ + grspw2_route(&ibsw_cfg.spw1); +} + +/** + * @brief enable direct routing between SpW0 and SpW1 + */ + +void CrIbEnableSpWRouting(void) +{ + grspw2_enable_routing(&ibsw_cfg.spw1, &ibsw_cfg.spw0); +} + + +/** + * @brief enable direct routing between SpW0 and SpW1 + */ + +void CrIbDisableSpWRouting(void) +{ + grspw2_disable_routing(&ibsw_cfg.spw1); + grspw2_disable_routing(&ibsw_cfg.spw0); +} + +#endif /* __SPW_ROUTING__ */ + + + +#define SES_HEADER_BYTES 4 +#define SPW_1_ADDR 36 +#define SPW_1_STRIP_HDR_BYTES 4 + +/** + * @brief reset and reconfigure the SpW 1 core + */ + +void CrIbResetSEMSpW(void) +{ + struct grspw2_core_cfg *spw = &ibsw_cfg.spw1; + + + grspw2_spw_hardreset(spw->regs); + + /* dpu SpW are already clocked at 10 MHz */ + grspw2_core_init(spw, GRSPW2_BASE_CORE_1, SPW_1_ADDR, 1, 1, + GRSPW2_DEFAULT_MTU, GR712_IRL2_GRSPW2_1, + GR712_IRL1_AHBSTAT, SPW_1_STRIP_HDR_BYTES); + + grspw2_rx_desc_table_init(spw, + spw->alloc.rx_desc_tbl, + GRSPW2_DESCRIPTOR_TABLE_SIZE, + spw->alloc.rx_descs, GRSPW2_DEFAULT_MTU); + + grspw2_tx_desc_table_init(spw, + spw->alloc.tx_desc_tbl, + GRSPW2_DESCRIPTOR_TABLE_SIZE, + spw->alloc.tx_hdr, spw->alloc.tx_hdr_size, + spw->alloc.tx_descs, GRSPW2_DEFAULT_MTU); + grspw2_core_start(spw); +} + diff --git a/IBSW/lib/ibsw_interface/ibsw_time.c b/IBSW/lib/ibsw_interface/ibsw_time.c new file mode 100644 index 0000000000000000000000000000000000000000..3c6d2c031156cedc3bc3ffd6f3244b804ad7582c --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_time.c @@ -0,0 +1,132 @@ +/** + * @file ibsw_time.c + * @ingroup ibsw_interface + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to time functions + * + * ## Overview + * + * These are function to get the current system time and the time of the next + * expected sync pulse in CUC format. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + */ +#include <stdint.h> + +#include <timing.h> +#include <syncpulse.h> + +#include <ibsw_interface.h> + + + +/** + * @brief provides the current time + * + * @return a timestamp + */ + +CrFwTimeStamp_t CrIbGetCurrentTime(void) +{ + uint32_t coarse_time; + uint32_t fine_time; + + uint16_t cuc_frac; + + float t_frac; + + CrFwTimeStamp_t time; + + + timekeeper_get_current_time(&ibsw_cfg.timer, &coarse_time, &fine_time); + + t_frac = (float) fine_time; + t_frac = t_frac / ((float) CPU_CPS); + t_frac = t_frac * ((float) 0xfffe); + + cuc_frac = (uint16_t) t_frac; + + cuc_frac &= ~0x1; + cuc_frac |= (ibsw_cfg.timer.synced & 0x1); + + time.t[0] = (coarse_time >> 24) & 0xff; + time.t[1] = (coarse_time >> 16) & 0xff; + time.t[2] = (coarse_time >> 8) & 0xff; + time.t[3] = coarse_time & 0xff; + time.t[4] = (cuc_frac >> 8) & 0xff; + time.t[5] = cuc_frac & 0xff; + + return time; +} + + +/** + * @brief provides the time of the next sync pulse and configures SpW tick in + * + * @return a timestamp + */ + +CrFwTimeStamp_t CrIbGetNextTime(void) +{ + uint32_t coarse_time; + uint32_t fine_time; + + uint16_t cuc_frac; + + float t_frac; + + CrFwTimeStamp_t time; + + + syncpulse_spw_get_next_time(&ibsw_cfg.timer, &coarse_time, &fine_time); + + t_frac = (float) fine_time; + t_frac = t_frac / ((float) CPU_CPS); + t_frac = t_frac * ((float) 0xfffe); + + cuc_frac = (uint16_t) t_frac; + + cuc_frac &= ~0x1; + cuc_frac |= (ibsw_cfg.timer.synced & 0x1); + + time.t[0] = (coarse_time >> 24) & 0xff; + time.t[1] = (coarse_time >> 16) & 0xff; + time.t[2] = (coarse_time >> 8) & 0xff; + time.t[3] = coarse_time & 0xff; + time.t[4] = (cuc_frac >> 8) & 0xff; + time.t[5] = cuc_frac & 0xff; + + return time; +} + +/** + * @brief manually disable the SpW tick-out + */ + +void CrIbDisableSpWTick(void) +{ + syncpulse_disable_spw_tick(&ibsw_cfg.timer); +} diff --git a/IBSW/lib/ibsw_interface/ibsw_utility.c b/IBSW/lib/ibsw_interface/ibsw_utility.c new file mode 100644 index 0000000000000000000000000000000000000000..e8ba03e2cb7a7599de780d2af8ec2cc7d369fa07 --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_utility.c @@ -0,0 +1,352 @@ +/** + * @file ibsw_utility.c + * @ingroup ibsw_interface + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to utility functions + * + * ## Overview + * + * These are function in the utility group. Please refer to the individual + * function description for information on their purpose. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + * + */ +#include <stdint.h> +#include <string.h> + +#include <error_log.h> +#include <iwf_fpga.h> +#include <syncpulse.h> +#include <exchange_area.h> +#include <compiler.h> +#include <leon3_dsu.h> +#include <stacktrace.h> +#include <ibsw_interface.h> +#include <ahb.h> + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + + + + +/** + * @brief the dpu reset function + * @param reset_type a reset type + * + * @note this writes the exchange area specified in CHEOPS-IWF-INST-ICD-009 + * DPU-SICD-IF-3520 + */ + +void CrIbResetDPU(unsigned char reset_type) +{ + uint8_t dpuMode; + uint8_t dpuSwActive; + uint8_t dpuWatchdogStatus; + uint8_t dpuUnit; + + uint8_t dpuResetType; + uint8_t timeSyncStatus; + uint8_t bootReportSent; + uint8_t spare1; + uint8_t semError; + uint8_t semOn; + + uint8_t dpuScLinkStatus; + uint8_t dpuMilbusCoreEx; + uint8_t dpuMilbusSyncDw; + uint8_t dpuMilbusSyncTo; + uint8_t dpuSemLinkStatus; + uint8_t dpuSemLinkState; + + uint32_t temp_finetime; + + uint32_t trace_entries[STACKTRACE_MAX_ENTRIES]; + + uint32_t i; + + uint32_t sp; + uint32_t pc; + + register int sp_local asm("%sp"); + + struct stack_trace trace; + + struct exchange_area *exchange = + (struct exchange_area *) EXCHANGE_AREA_BASE_ADDR; + + /** RESET_TYPE **/ + exchange->reset_type = reset_type; + + + /** DBS_STATUS_BYTE1 **/ + + /* DpuMode(4) ... DPU_SAFE = 0 */ + dpuMode = 0; + + /* DpuSwActive(2) ... UNKNOWN = 0, DBS = 1, IASW = 2 */ + dpuSwActive = 2; + + /* DpuWatchdogStatus(1) */ + CrIaCopy(ISWATCHDOGENABLED_ID, &dpuWatchdogStatus); + + /* DpuUnit(1) ... RT9 = NOMINAL => 1; RT10 = REDUNDANT => 0 */ + dpuUnit = 1; + if (fpga_dpu_get_rt_addr() != 0x9) + dpuUnit = 0; + + exchange->hk_dbs_status_byte1 = + (dpuMode << 4) | (dpuSwActive << 2) | (dpuWatchdogStatus << 1) | dpuUnit; + + + /** DBS_STATUS_BYTE2 **/ + + /* DpuResetType(3) */ + dpuResetType = reset_type; /* this will be overwritten by the DBS */ + + /* TimeSyncStatus(1) */ + CrIaCopy(ISSYNCHRONIZED_ID, &timeSyncStatus); + + /* Mantis 2086 and 1994: invert the meaning of the sync flag for the boot report */ + if (timeSyncStatus == 0x01) + timeSyncStatus = 0; + else + timeSyncStatus = 1; + + /* BootReportSent(1) */ + bootReportSent = 0; /* NOTE: IASW shall send REPORT_NOT_SENT = 0 */ + + /* Spare1(1) */ + spare1 = 0; + + /* SemError(1) */ + semError = 0; + if (fpga_sem_get_status_failure()) + semError = 1; + + /* SemOn(1) */ + semOn = 0; + if (fpga_sem_get_status_on()) + semOn = 1; + + exchange->hk_dbs_status_byte2 = + (dpuResetType << 5) | (timeSyncStatus << 4) | (bootReportSent << 3) | + (spare1 << 2) | (semError << 1) | semOn; + + + /** DBS_STATUS_BYTE3 **/ + + /* if you are able to read this, the next 4 items are ones */ + + /* dpuScLinkStatus(1) */ + dpuScLinkStatus = 1; + + /* dpuMilbusCoreEx(1) */ + dpuMilbusCoreEx = 1; + + /* dpuMilbusSyncDw(1) */ + dpuMilbusSyncDw = 1; + + /* dpuMilbusSyncTo(1) */ + dpuMilbusSyncTo = 1; + + /* dpuSemLinkStatus(1) */ + dpuSemLinkStatus = 1; /* NOTE: in IASW, the link is always enabled */ + + /* dpuSemLinkState(3) */ + dpuSemLinkState = (uint8_t) CrIbIsSEMLinkRunning(); + + exchange->hk_dbs_status_byte3 = + (dpuScLinkStatus << 7) | (dpuMilbusCoreEx << 6) | (dpuMilbusSyncDw << 5) | + (dpuMilbusSyncTo << 4) | (dpuSemLinkStatus << 3) | dpuSemLinkState; + + + /** RESET_TIME **/ + timekeeper_get_current_time(&ibsw_cfg.timer, + &exchange->reset_time.coarse_time, + &temp_finetime); + + exchange->reset_time.fine_time = (uint16_t) temp_finetime; + + /** TRAP_CORE1 and TRAP_CORE2 **/ + exchange->trapnum_core0 = (dsu_get_reg_tbr(0) >> 4) & 0xff; + exchange->trapnum_core1 = (dsu_get_reg_tbr(1) >> 4) & 0xff; + + /** REGISTERS CORE1 **/ + exchange->regs_cpu0.psr = dsu_get_reg_psr(0); + exchange->regs_cpu0.wim = dsu_get_reg_wim(0); + exchange->regs_cpu0.pc = dsu_get_reg_pc(0); + exchange->regs_cpu0.npc = dsu_get_reg_npc(0); + exchange->regs_cpu0.fsr = dsu_get_reg_fsr(0); + + /** REGISTERS CORE2 **/ + exchange->regs_cpu1.psr = dsu_get_reg_psr(1); + exchange->regs_cpu1.wim = dsu_get_reg_wim(1); + exchange->regs_cpu1.pc = dsu_get_reg_pc(1); + exchange->regs_cpu1.npc = dsu_get_reg_npc(1); + exchange->regs_cpu1.fsr = dsu_get_reg_fsr(1); + + /** AHB STATUS REGISTER and AHB FAILING ADDRESS REG **/ + exchange->ahb_status_reg = ahbstat_get_status(); + exchange->ahb_failing_addr_reg = ahbstat_get_failing_addr(); + + /** CALL STACK CORE 1 **/ + trace.max_entries = STACKTRACE_MAX_ENTRIES; + trace.nr_entries = 0; + trace.entries = trace_entries; + + /* trace_entries has not yet decayed into a pointer, so sizeof() is fine */ + bzero(trace_entries, sizeof(trace_entries)); + + /* The DSU of the GR712 appears to return the contents of a different register + * than requested. Usually it is the following entry, i.e. when requesting + * the register %o6 (== %sp) of a particular register file (CPU window) we + * get the contents %o7 (address of caller). This can also be seen in the AHB + * trace buffer. Hence, we use the local value of %sp (i.e. of the CPU calling + * this function). For the other CPU, we can't do much if the returned value + * is incorrect, so a stack trace may not be valid or contain meaningful + * information. Interestingly enough, this behaviour appears to depend on + * the length and operations of the current function, so this may really be + * a problem with the types and amounts of transfers crossing the bus. + */ + + sp = sp_local; + pc = dsu_get_reg_pc(0); /* not critical if incorrect */ + save_stack_trace(&trace, sp, pc); + + for (i = 0; i < STACKTRACE_MAX_ENTRIES; i++) + exchange->stacktrace_cpu0[i] = trace_entries[i]; + + + trace.max_entries = STACKTRACE_MAX_ENTRIES; + trace.nr_entries = 0; + trace.entries = trace_entries; + /** CALL STACK CORE 2 **/ + bzero(trace_entries, sizeof(trace_entries)); + + sp = dsu_get_reg_sp(1, dsu_get_reg_psr(1) & 0x1f); + pc = dsu_get_reg_pc(1); + save_stack_trace(&trace, sp, pc); + + for (i = 0; i < STACKTRACE_MAX_ENTRIES; i++) + exchange->stacktrace_cpu1[i] = trace_entries[i]; + + + /* SpW and 1553 don't need to be stopped explicitly */ + + /* hit the reset button */ + if (reset_type == DBS_EXCHANGE_RESET_TYPE_CO) + fpga_reset_ctrl_set(RESET_CTRL_CO); + + else if (reset_type == DBS_EXCHANGE_RESET_TYPE_MB) + fpga_reset_ctrl_set(RESET_CTRL_MB); + + else + fpga_reset_ctrl_set(RESET_CTRL_UN); + + /* do nothing until reset */ + while (1) + cpu_relax(); +} + + +/** + * @brief get value of the notification cycle counter + */ + +uint32_t CrIbGetNotifyCnt(void) +{ + return ibsw_cfg.timer.notify_cnt; +} + + +uint32_t CrIbGetDpuBoardId(void) +{ + return fpga_dpu_get_board_serial(); +} + + + +/** + * @brief turn the SEM on/off and get its status + * + * @param op see enum sem_op + * + * @return 1 on success or positive status, 0 otherwise + * + * @note always returns 1 when not compiled for the DPU board + */ + +uint32_t CrIbSemLowLevelOp(enum sem_op __attribute__((unused)) op) +{ + uint32_t ret = 1; + uint8_t keyword = 0; + + switch (op) { + case SWITCH_ON: + /* switch on using the keyword from the data pool */ + CrIaCopy(SEM_ON_CODE_ID, &keyword); + fpga_sem_switch_on(keyword); + break; + case SWITCH_OFF: + /* switch on using the keyword from the data pool */ + CrIaCopy(SEM_OFF_CODE_ID, &keyword); + fpga_sem_switch_off(keyword); + syncpulse_disable_spw_tick(&ibsw_cfg.timer); + break; + case HEATER_ON: + fpga_sem_heater_on(); + break; + case HEATER_OFF: + fpga_sem_heater_off(); + break; + case GET_STATUS_ON: + ret = fpga_sem_get_status_on(); + break; + case GET_FAILURE: + ret = fpga_sem_get_status_failure(); + break; + case GET_STATUS_HEATER_ON: + ret = fpga_sem_get_status_heater_on(); + break; + } + + return ret; +} + + +/** + * @brief update synchronisation flag in data pool + */ + +void CrIbSetSyncFlag(uint32_t sync) +{ + uint8_t sync_flag; + + sync_flag = (uint8_t) sync; + CrIaPaste(ISSYNCHRONIZED_ID, &sync_flag); +} diff --git a/IBSW/lib/ibsw_interface/ibsw_watchdog.c b/IBSW/lib/ibsw_interface/ibsw_watchdog.c new file mode 100644 index 0000000000000000000000000000000000000000..25fb4c42c58c51c9adc1d8de462533ecff5db7da --- /dev/null +++ b/IBSW/lib/ibsw_interface/ibsw_watchdog.c @@ -0,0 +1,102 @@ +/** + * @file ibsw_watchdog.c + * @ingroup ibsw_interface + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements an IBSW <> IASW interface to the watchdog + * + * ## Overview + * + * These are wrapper functions that comply with the IBSW/IASW naming scheme. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * None + * + */ +#include <stdint.h> + +#include <watchdog.h> +#include <iwf_fpga.h> + +#include <ibsw_interface.h> + + + +/** + * @brief reset procedure executed by watchdog() + * @note the watchdog reset procedure is special in that it cannot + * flush the flash buffer because of the FPGA's reset timeout + */ + +static void wd_reset(void) +{ + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_WD); +} + + +/** + * @brief remote terminal (=BEE) reset callback + */ + +void rt_reset(__attribute__((unused)) void *userdata) +{ + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_MB); +} + +/** + * @brief remote terminal (=BEE) reset callback + */ + +void fdir_reset(__attribute__((unused)) void *userdata) +{ + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_UN); +} + +/** + * @brief enable the watchdog + */ + +void CrIbEnableWd(void) +{ + watchdog_enable(&ibsw_cfg.timer, &wd_reset); +} + + +/** + * @brief disable the watchdog + */ + +void CrIbDisableWd(void) +{ + watchdog_disable(&ibsw_cfg.timer); +} + + +/** + * @brief enable the watchdog + */ + +void CrIbResetWd(void) +{ + watchdog_feed(&ibsw_cfg.timer); +} diff --git a/IBSW/lib/irq_dispatch.c b/IBSW/lib/irq_dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..6d2cef2387e31813cab06744c930140ee2fe0c29 --- /dev/null +++ b/IBSW/lib/irq_dispatch.c @@ -0,0 +1,737 @@ +/** + * @file irq_dispatch.c + * @ingroup irq_dispatch + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date December, 2013 + * @brief Central IRQ dispatcher + * + * @copyright + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @note eventually replace catch_interrupt() libgloss/newlib functionality + * with local/custom code and rework the globals + * @note irq configuration should only be done through a syscall, + * so traps are disabled + * + * @defgroup irq_dispatch IRQ dispatcher + * @brief a central IRQ handler that dispatches interrupts to registered + * callback functions + * + * Implements a central interrupt handler that supports registration of a + * predefined arbitrary number of callback function per interrupt with immediate + * or deferred execution priorities. Callbacks are tracked in linked lists that + * should always be allocated in a contiguous block of memory for proper cache + * hit rate. + * + * @image html irq_dispatch/irq_dispatch.png "IRQ dispatcher" + * + * On LEONs with round-robin extended interrupt + * lines, such as in the MPPB, the handler can be modified to execute all active + * secondary interrupts without exiting IRQ mode for significantly reduced + * call overhead. + * + * @example demo_irq_dispatch.c + */ + + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <irq_dispatch.h> +#include <list.h> +#include <irq.h> +#include <spinlock.h> +#include <leon_reg.h> +#include <compiler.h> +#include <errors.h> +#include <asm/leon.h> +#include <io.h> +#include <sysctl.h> + +#if !(__sparc__) +/* unit testing dummy */ +int catch_interrupt(__attribute__((unused)) int func, + __attribute__((unused)) int irq) +{ + return 0; +} +#else +#include <asm-leon/irq.h> +#endif + + + +struct irl_vector_elem { + int32_t (*callback)(void *userdata); + enum prty priority; + void *userdata; + struct list_head callback_node; +}; + +#define IRL_POOL_SIZE 128 +#define IRL_QUEUE_SIZE 128 +#define IRL_SIZE 128 + +struct list_head irl_pool_head; +struct list_head irl_queue_head; +struct list_head irq_queue_pool_head; + +struct list_head irq1_vector[IRL_SIZE]; +struct list_head irq2_vector[IRL_SIZE]; + +struct irl_vector_elem irl_pool[IRL_POOL_SIZE]; +struct irl_vector_elem irl_queue_pool[IRL_QUEUE_SIZE]; + + + +/* temporarily from c-irq.c */ +struct leon3_irqctrl_registermap *leon3_irqctrl_regs; + +#define ICLEAR 0x20c +#define IMASK 0x240 +#define IFORCE 0x208 + +#if (__sparc__) +int32_t *lreg = (int32_t *) 0x80000000; + +void enable_irq(int32_t irq) +{ + lreg[ICLEAR/4] = (1 << irq); /* clear any pending irq*/ + lreg[IMASK/4] |= (1 << irq); /* unmaks irq */ + leon3_irqctrl_regs->irq_mpmask[leon3_cpuid()] |= 1 << irq; +} + +void enable_irq2(int32_t irq) +{ + lreg[ICLEAR/4] = (1 << irq); /* clear any pending irq*/ + lreg[IMASK/4] |= (1 << irq); /* unmaks irq */ + leon3_irqctrl_regs->irq_mpmask[leon3_cpuid()] |= (1 << irq) << 16; +} + +void disable_irq(int32_t irq) +{ + lreg[IMASK/4] &= ~(1 << irq); +} + +void disable_irq2(int32_t irq) +{ + lreg[IMASK/4] &= ~((1 << irq) << 16); +} + +void force_irq(int32_t irq) +{ + lreg[IFORCE/4] = (1 << irq); +} +#else +void enable_irq(int32_t __attribute__((unused)) irq) +{ +} + +void enable_irq2(int32_t __attribute__((unused)) irq) +{ +} + +void disable_irq(int32_t __attribute__((unused)) irq) +{ +} + +void disable_irq2(int32_t __attribute__((unused)) irq) +{ +} +#endif +/* end temp */ + + +static struct { + uint32_t irl1; + uint32_t irl2; + uint32_t irl1_irq[15]; + uint32_t irl2_irq[15]; +} irqstat; + +#if (__sparc__) +#define UINT32_T_FORMAT "%lu" +#else +#define UINT32_T_FORMAT "%u" +#endif + +static ssize_t irl1_show(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + char *buf) +{ + uint32_t irq; + + + if (!strcmp("irl1", sattr->name)) + return sprintf(buf, UINT32_T_FORMAT, irqstat.irl1); + + irq = atoi(sattr->name); + + if (irq > 15) + return 0; + + return sprintf(buf, UINT32_T_FORMAT, irqstat.irl1_irq[irq - 1]); +} + +static ssize_t irl1_store(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + __attribute__((unused)) const char *buf, + __attribute__((unused)) size_t len) +{ + uint32_t irq; + + + if (!strcmp("irl1", sattr->name)) { + irqstat.irl1 = 0; + return 0; + } + + irq = atoi(sattr->name); + + if (irq > 15) + return 0; + + irqstat.irl1_irq[irq - 1] = 0; + + return 0; +} + +static ssize_t irl2_show(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + char *buf) +{ + uint32_t irq; + + + if (!strcmp("irl2", sattr->name)) + return sprintf(buf, UINT32_T_FORMAT, irqstat.irl2); + + irq = atoi(sattr->name); + + if (irq > 15) + return 0; + + return sprintf(buf, UINT32_T_FORMAT, irqstat.irl2_irq[irq - 1]); +} + +static ssize_t irl2_store(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + __attribute__((unused)) const char *buf, + __attribute__((unused)) size_t len) +{ + uint32_t irq; + + + if (!strcmp("irl2", sattr->name)) { + irqstat.irl2 = 0; + return 0; + } + + irq = atoi(sattr->name); + + if (irq > 15) + return 0; + + irqstat.irl2_irq[irq - 1] = 0; + + return 0; +} + +__extension__ +static struct sobj_attribute irl1_attr[] = { + __ATTR(irl1, irl1_show, irl1_store), + __ATTR(1, irl1_show, irl1_store), __ATTR(2, irl1_show, irl1_store), + __ATTR(3, irl1_show, irl1_store), __ATTR(4, irl1_show, irl1_store), + __ATTR(5, irl1_show, irl1_store), __ATTR(6, irl1_show, irl1_store), + __ATTR(7, irl1_show, irl1_store), __ATTR(8, irl1_show, irl1_store), + __ATTR(9, irl1_show, irl1_store), __ATTR(10, irl1_show, irl1_store), + __ATTR(11, irl1_show, irl1_store), __ATTR(12, irl1_show, irl1_store), + __ATTR(13, irl1_show, irl1_store), __ATTR(14, irl1_show, irl1_store), + __ATTR(15, irl1_show, irl1_store)}; + +static struct sobj_attribute *irl1_attributes[] = { + &irl1_attr[0], &irl1_attr[1], &irl1_attr[2], &irl1_attr[3], + &irl1_attr[4], &irl1_attr[5], &irl1_attr[6], &irl1_attr[7], + &irl1_attr[8], &irl1_attr[9], &irl1_attr[10], &irl1_attr[11], + &irl1_attr[12], &irl1_attr[13], &irl1_attr[14], &irl1_attr[14], + NULL}; + +__extension__ +static struct sobj_attribute irl2_attr[] = { + __ATTR(irl2, irl2_show, irl2_store), + __ATTR(1, irl2_show, irl2_store), __ATTR(2, irl2_show, irl2_store), + __ATTR(3, irl2_show, irl2_store), __ATTR(4, irl2_show, irl2_store), + __ATTR(5, irl2_show, irl2_store), __ATTR(6, irl2_show, irl2_store), + __ATTR(7, irl2_show, irl2_store), __ATTR(8, irl2_show, irl2_store), + __ATTR(9, irl2_show, irl2_store), __ATTR(10, irl2_show, irl2_store), + __ATTR(11, irl2_show, irl2_store), __ATTR(12, irl2_show, irl2_store), + __ATTR(13, irl2_show, irl2_store), __ATTR(14, irl2_show, irl2_store), + __ATTR(15, irl2_show, irl2_store)}; + +__extension__ +static struct sobj_attribute *irl2_attributes[] = { + &irl2_attr[0], &irl2_attr[1], &irl2_attr[2], &irl2_attr[3], + &irl2_attr[4], &irl2_attr[5], &irl2_attr[6], &irl2_attr[7], + &irl2_attr[8], &irl2_attr[9], &irl2_attr[10], &irl2_attr[11], + &irl2_attr[12], &irl2_attr[13], &irl2_attr[14], &irl2_attr[15], + NULL}; + +/** + * @brief queue a callback for delayed exectuion + * + * @param[in] p_elem a pointer to a struct IRQVectorElem + * + * @retval -1 : error + * @retval 0 : success + */ + +static int32_t irq_queue(struct irl_vector_elem *p_elem) +{ + uint32_t psr_flags; + struct irl_vector_elem *p_queue; + + if (likely(list_filled(&irq_queue_pool_head))) { + + psr_flags = spin_lock_save_irq(); + + p_queue = list_entry((&irq_queue_pool_head)->next, + struct irl_vector_elem, callback_node); + + p_queue->callback = p_elem->callback; + p_queue->priority = p_elem->priority; + p_queue->userdata = p_elem->userdata; + + list_move_tail(&p_queue->callback_node, &irl_queue_head); + + spin_lock_restore_irq(psr_flags); + + return 0; + + } else { + errno = E_IRQ_QUEUE_BUSY; + return -1; + } +} + + +/** + * @brief the central interrupt handling routine + * + * @param[in] irq an interrupt number + * + * @retval 0 : always + * + * @note callback return codes ignored for now + */ + +static int32_t irq_dispatch(int32_t irq) +{ + uint32_t irq2; + + struct irl_vector_elem *p_elem; + struct irl_vector_elem *p_tmp; + + + irqstat.irl1++; + irqstat.irl1_irq[irq - 1]++; + + if (irq == IRL1_EXTENDED_INT) { + + irq2 = leon3_irqctrl_regs->extended_irq_id[leon3_cpuid()]; + + irqstat.irl2++; + irqstat.irl2_irq[irq2 - 1]++; + + list_for_each_entry_safe(p_elem, p_tmp, + &irq2_vector[irq2], callback_node) { + + if (likely(p_elem->priority == PRIORITY_NOW)) { + p_elem->callback(p_elem->userdata); + } else { + /* execute immediately if queueing fails */ + if (irq_queue(p_elem) < 0) + p_elem->callback(p_elem->userdata); + } + } + + } else { /* regular (primary) interrupts */ + + list_for_each_entry(p_elem, &irq1_vector[irq], callback_node) { + if (likely(p_elem->priority == PRIORITY_NOW)) { + p_elem->callback(p_elem->userdata); + } else { + /* execute immediately if queueing fails */ + if (irq_queue(p_elem) < 0) + p_elem->callback(p_elem->userdata); + } + } + } + + return 0; +} + + + +/** + * @brief register a callback function to the primary interrupt line + * + * + * @param[in] irq an interrupt number + * @param[in] priority a callback priority + * @param[in] callback a callback function + * @param[in] userdata a pointer to arbitrary user data; passed to + * callback function + * + * @retval -1 : error + * @retval 0 : success + * + * @bug catch_interrupt() is called without checking whether the IRL + * was already mapped + */ + +int32_t irl1_register_callback(int32_t irq, + enum prty priority, + int32_t (*callback)(void *userdata), + void *userdata) +{ + uint32_t psr_flags; + + struct irl_vector_elem *p_elem; + + + if (irq >= IRL_SIZE) { + errno = E_IRQ_EXCEEDS_IRL_SIZE; + return -1; + } + + if (list_empty(&irl_pool_head)) { + errno = E_IRQ_POOL_EMPTY; + return -1; + } + + if (callback == NULL) { + errno = EINVAL; + return -1; + } + + psr_flags = spin_lock_save_irq(); + + p_elem = list_entry((&irl_pool_head)->next, struct irl_vector_elem, + callback_node); + + p_elem->callback = callback; + p_elem->priority = priority; + p_elem->userdata = userdata; + + list_move_tail(&p_elem->callback_node, &irq1_vector[irq]); + + spin_lock_restore_irq(psr_flags); + + enable_irq(irq); + + return catch_interrupt(((int) irq_dispatch), irq); +} + + +/** + * @brief de-register a callback function on the primary interrupt line + * + * @param[in] IRQ an interrupt number + * @param[in] callback a callback function + * @param[in] userdata a pointer to arbitrary user data + * + * @retval -1 : error + * @retval 0 : success + * + * @note in case of duplicate callbacks, only the first encountered will + * be removed + */ + +int32_t irl1_deregister_callback(int32_t irq, + int32_t (*callback)(void *userdata), + void *userdata) +{ + uint32_t psr_flags; + struct irl_vector_elem *p_elem; + struct irl_vector_elem *p_tmp; + + if (irq >= IRL_SIZE) { + errno = E_IRQ_EXCEEDS_IRL_SIZE; + return -1; + } + + list_for_each_entry_safe(p_elem, p_tmp, + &irq1_vector[irq], callback_node) { + + if (p_elem->callback == callback + && p_elem->userdata == userdata) { + + p_elem->callback = NULL; + p_elem->userdata = NULL; + p_elem->priority = -1; + + psr_flags = spin_lock_save_irq(); + list_move_tail(&p_elem->callback_node, &irl_pool_head); + spin_lock_restore_irq(psr_flags); + + if (irq1_vector[irq].next == &irq1_vector[irq]) + disable_irq(irq); + + return 0; + } + } + errno = E_IRQ_DEREGISTER; + return -1; +} + + +/** + * @brief register a callback function to the secondary interrupt line + * + * @param[in] IRQ an interrupt number + * @param[in] priority a callback priority + * @param[in] callback a callback function + * @param[in] userdata a pointer to arbitrary user data + * + * @retval -1 : error + * @retval 0 : success + * + */ + +int32_t irl2_register_callback(int32_t irq, + enum prty priority, + int32_t (*callback)(void *userdata), + void *userdata) +{ + uint32_t psr_flags; + struct irl_vector_elem *p_elem; + + if (irq >= IRL_SIZE) { + errno = E_IRQ_EXCEEDS_IRL_SIZE; + return -1; + } + + if (list_empty(&irl_pool_head)) { + errno = E_IRQ_POOL_EMPTY; + return -1; + } + + if (callback == NULL) { + errno = EINVAL; + return -1; + } + + psr_flags = spin_lock_save_irq(); + p_elem = list_entry((&irl_pool_head)->next, struct irl_vector_elem, + callback_node); + + p_elem->callback = callback; + p_elem->priority = priority; + p_elem->userdata = userdata; + + list_move_tail(&p_elem->callback_node, &irq2_vector[irq]); + + spin_lock_restore_irq(psr_flags); + + enable_irq2(irq); + + return 0; +} + +/** + * @brief de-register a callback function on the secondary interrupt line + * + * @param[in] IRQ an interrupt number + * @param[in] callback a callback function + * @param[in] userdata a pointer to arbitrary user data + * + * @retval -1 : error + * @retval 0 : success + */ + +int32_t irl2_deregister_callback(int32_t irq, + int32_t (*callback)(void *userdata), + void *userdata) +{ + uint32_t psr_flags; + struct irl_vector_elem *p_elem; + struct irl_vector_elem *p_tmp; + + if (irq >= IRL_SIZE) { + errno = E_IRQ_EXCEEDS_IRL_SIZE; + return -1; + } + + list_for_each_entry_safe(p_elem, p_tmp, + &irq2_vector[irq], callback_node) { + + if (p_elem->callback == callback + && p_elem->userdata == userdata) { + + p_elem->callback = NULL; + p_elem->userdata = NULL; + p_elem->priority = -1; + + psr_flags = spin_lock_save_irq(); + list_move_tail(&p_elem->callback_node, &irl_pool_head); + spin_lock_restore_irq(psr_flags); + + if (irq2_vector[irq].next == &irq2_vector[irq]) + disable_irq2(irq); + + return 0; + } + } + + errno = E_IRQ_DEREGISTER; + return -1; +} + +/** + * + * @brief call this function in normal mode to handle non-priority + * interrupt requests + * + */ + +void irq_queue_execute(void) +{ + struct irl_vector_elem *p_elem = NULL; + struct irl_vector_elem *p_tmp; + + + if (list_empty(&irl_queue_head)) + return; + + list_for_each_entry_safe(p_elem, p_tmp, + &irl_queue_head, callback_node) { + + list_del(&p_elem->callback_node); + + if (likely(p_elem->callback != NULL)) { + + if (p_elem->callback(p_elem->userdata)) + irq_queue(p_elem); + else + list_add_tail(&p_elem->callback_node, + &irq_queue_pool_head); + + } else { + list_add_tail(&p_elem->callback_node, + &irq_queue_pool_head); + } + } +} + + +void irq_set_level(uint32_t irq_mask, uint32_t level) +{ + uint32_t flags; + + flags = ioread32be(&leon3_irqctrl_regs->irq_level); + + if (!level) + flags &= ~irq_mask; + else + flags |= irq_mask; + + + iowrite32be(flags, &leon3_irqctrl_regs->irq_level); +} + + + +/** + * @brief enable the interrupt handling service + * + * @retval -1 : error + * @retval 0 : success + */ + +int32_t irq_dispatch_enable(void) +{ + size_t i; + + struct sysset *sset; + struct sysobj *sobj; + +#if (__sparc__) + /** + * Basic Moron Protector (BMP)â„¢ + */ + static enum {DISABLED, ENABLED} dispatcher; + + if (dispatcher) + return -1; + + dispatcher = ENABLED; +#endif + + INIT_LIST_HEAD(&irl_pool_head); + INIT_LIST_HEAD(&irl_queue_head); + INIT_LIST_HEAD(&irq_queue_pool_head); + + for (i = 0; i < IRL_SIZE; i++) { + INIT_LIST_HEAD(&irq1_vector[i]); + INIT_LIST_HEAD(&irq2_vector[i]); + } + + for (i = 0; i < IRL_POOL_SIZE; i++) { + irl_pool[i].callback = NULL; + irl_pool[i].userdata = NULL; + list_add_tail(&irl_pool[i].callback_node, &irl_pool_head); + } + + for (i = 0; i < IRL_QUEUE_SIZE; i++) { + irl_queue_pool[i].callback = NULL; + irl_queue_pool[i].userdata = NULL; + list_add_tail(&irl_queue_pool[i].callback_node, + &irq_queue_pool_head); + } + + + sset = sysset_create_and_add("irq", NULL, sys_set); + + sobj = sysobj_create(); + + if (!sobj) + return -1; + + sobj->sattr = irl1_attributes; + sysobj_add(sobj, NULL, sset, "primary"); + + sobj = sysobj_create(); + + if (!sobj) + return -1; + + sobj->sattr = irl2_attributes; + sysobj_add(sobj, NULL, sset, "secondary"); + + + leon3_irqctrl_regs = (struct leon3_irqctrl_registermap *) + LEON3_BASE_ADDRESS_IRQMP; + + enable_irq(IRL1_EXTENDED_INT); + + + /* workaround for v0.8: + * enable timer 0 and 1 irqs so their interrupts are counted + * by irq_dispatch as well + */ + catch_interrupt(((int) irq_dispatch), GR712_IRL1_GPTIMER_0); + catch_interrupt(((int) irq_dispatch), GR712_IRL1_GPTIMER_1); + + /* retval check can be done outside */ + return catch_interrupt(((int) irq_dispatch), GR712_IRL1_IRQMP); +} diff --git a/IBSW/lib/iwf_flash.c b/IBSW/lib/iwf_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..8d0d487d3fb62aa63b6342db4539742f1351397e --- /dev/null +++ b/IBSW/lib/iwf_flash.c @@ -0,0 +1,1086 @@ +/** + * @file iwf_flash.c + * @ingroup iwf_flash + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date December, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup iwf_flash IWF FLASH memory + * @brief Implements access to the IWF FLASH memory device + * + * + * + * ## Overview + * + * This module implements access to the IWF FLASH memory device. + * + * + * ## Mode of Operation + * + * The function of the FPGA is to provide a software-accessible interface to + * the FLASH. Details on how the FLASH is operated can be found in the + * according datasheet. The operations described there are executed via the + * registers of the FPGA. + * + * As an example, the basic read procedure is reproduced below. + * + * + * @startuml{iwf_flash_read.svg} "FLASH read procedure" width=10 + * + * start + * + * :flash cmd 0x00000000; + * :write address bytes 1-5; + * :flash cmd 0x30303030; + * : wait for ready bit; + * + * repeat + * :read FLASH data register; + * note left + * ECC check by FPGA + * end note + * repeat while (read more?) + * + * stop + * + * @enduml + * + * + * @see + * - _K9F8G08UXM 1G x 8 Bit/ 2G x 8 Bit NAND Flash Memory rev 1.4_ + * datasheet for programming procedures and address generation + * + * - CHEOPS-IWF-INST-ICD-009 + * _CHEOPS DPU Boot S/W Interface Control Document_ for programming + * procedures of the parallel BEE FLASHes + * + * - CHEOPS-IWF-INST-IRD-020 _CHEOPS BEE DPU Hardware - Software Interface + * Requirements_ for FPGA register mappings + * + * ### Address Generation + * + * From the perspective of a user, the storage granularity within a FLASH + * unit is of 4 byte granularity. + * It is therefore addressed via a _logical_ + * address that must increments by 4, i.e. 32 bit word addressing. + * + * + * + * + * The _physical_ address used to program a read of a 4 byte wide entry + * is incrementing __one__ byte __per word__, as a FLASH word is stored in + * 4 (+1 EDAC) physical FLASH devices of 8 bits width each. + * + * This is because the FPGA does not perform address translation, but merely + * passes on what is written to its register to the actual FLASH devices. + * + * @startuml "Physical Layout of the FLASH mass storage" width=5 + * node "32bit FLASH" { + * node "EDAC" { + * } + * node "Byte 3" { + * } + * node "Byte 2" { + * } + * node "Byte 1" { + * } + * node "Byte 0" { + * } + * } + * @enduml + * + * In other words, each byte in the relevant flash registers map to a + * corresponding device, which still must be addressed as usual, as for example + * at a logical address of 0x10, 16 bytes (or 4 words) are stored before that + * address, but each of the bytes per word is stored in parallel, starting from + * the top of the flash device, as the device counters are independently + * referring to a byte offset, i.e. + * + @verbatim + Offset | FLASH 0 | FLASH 1 | FLASH 2 | FLASH 3 + -------------------------------------------------------- + 0x0 | [Byte 0] | [ Byte 1] | [Byte 2] | [Byte 3] + 0x1 | [Byte 4] | [ Byte 5] | [Byte 6] | [Byte 7] + 0x2 | [Byte 8] | [ Byte 9] | [Byte 10] | [Byte 11] + 0x3 | [Byte 12] | [ Byte 13] | [Byte 14] | [Byte 15] + @endverbatim + * + * + * The logical address thus requires conversion to the physical address where + * the FLASH page offset is modified. + * + * For added simplicity and to avoid confusion, a block/page/offset addressing + * scheme is used in the API of this component. + * + * + * ## Error Handling + * + * Error conditions that occur due to misconfiguration or during FLASH operation + * are propagated to the caller via return codes and, more detailed, by _errno_ + * flags. ECC errors generated during reads are handled via @ref edac. + * + * If errors occur during erase or write cycles, the operation is aborted and + * the flash block is marked invalid. + * + * Unless otherwise selected during compilation, the validity flag is ignored + * during reads. This allows the recovery of data written to blocks that were + * later marked invalid. Note that doing this will likely result in copious + * amounts of FLASH EDAC errors to be emitted by the FPGA. + * + * + * ## Notes + * + * - There is no timeout on flash ready checks. This means that if the + * FLASH/FPGA gets stuck, the watchdog timer will trigger. + * + * @example demo_flash.c + */ + +#include <errors.h> + +#include <iwf_fpga.h> +#include <iwf_flash.h> +#include <compiler.h> + +uint32_t flash_erase_retry = 0; + +/* the FPGA cannot tell us the current address read from the flash device + * so we'll keep track of it here + */ +static struct { + struct { + uint32_t block; + uint32_t page; + uint32_t offset; + } read; + + struct { + uint32_t block; + uint32_t page; + uint32_t offset; + } write; +} flash_unit_addr[FLASH_UNITS]; + + + +/** + * @brief set the internal flash write address + * + * @param unit the flash unit + * @param block the flash block + * @param page the flash page + * @param offset the byte offset within the page + * + * @return 0 on success, -1 on failure + */ + +static int32_t flash_internal_set_read_addr(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset) +{ + if (unit >= FLASH_UNITS) + return -1; + + flash_unit_addr[unit].read.block = block; + flash_unit_addr[unit].read.page = page; + flash_unit_addr[unit].read.offset = offset; + + return 0; +} + + +/** + * @brief set the internal flash write address + * + * @param unit the flash unit + * @param block the flash block + * @param page the flash page + * @param offset the byte offset within the page + * + * @return 0 on success, -1 on failure + */ + +static int32_t flash_internal_set_write_addr(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset) +{ + if (unit >= FLASH_UNITS) + return -1; + + flash_unit_addr[unit].write.block = block; + flash_unit_addr[unit].write.page = page; + flash_unit_addr[unit].write.offset = offset; + + return 0; +} + + +/** + * @brief set the internal flash read offset + * + * @param unit the flash unit + * @param offset the byte offset within the page + * + * @return 0 on success, -1 on failure + */ + +static int32_t flash_internal_set_read_offset(uint32_t unit, uint32_t offset) +{ + if (unit >= FLASH_UNITS) + return -1; + + flash_unit_addr[unit].read.offset = offset; + + return 0; +} + + +/** + * @brief get the internal flash read offset + * + * @param unit the flash unit + * + * @return offset + */ + +static uint32_t flash_internal_get_read_offset(uint32_t unit) +{ + return flash_unit_addr[unit].read.offset; +} + + +/** + * @brief set the internal flash write offset + * + * @param unit the flash unit + * @param offset the byte offset within the page + * + * @return 0 on success, -1 on failure + */ + +__attribute__((unused)) +static int32_t flash_internal_set_write_offset(uint32_t unit, uint32_t offset) +{ + if (unit >= FLASH_UNITS) + return -1; + + flash_unit_addr[unit].write.offset = offset; + + return 0; +} + + +/** + * @brief get the internal flash write offset + * + * @param unit the flash unit + * + * @return offset + */ + +static int32_t flash_internal_get_write_offset(uint32_t unit) +{ + return flash_unit_addr[unit].write.offset; +} + + +/** + * @brief increment the internal flash read offset + * + * @param unit the flash unit + */ + +static void flash_internal_inc_read_offset(uint32_t unit) +{ + if (unit >= FLASH_UNITS) + return; + + flash_unit_addr[unit].read.offset++; +} + + +/** + * @brief increment the internal flash write offset + * + * @param unit the flash unit + */ + +static void flash_internal_inc_write_offset(uint32_t unit) +{ + if (unit >= FLASH_UNITS) + return; + + flash_unit_addr[unit].write.offset++; +} + + +/** + * @brief get the internal flash write block + * + * @param unit the flash unit + * + * @return the write block + */ + +static uint32_t flash_get_write_block(uint32_t unit) +{ + return flash_unit_addr[unit].write.block; +} + + +/** + * @brief get the current flash read address + * + * @param[in] unit the flash unit + * @param[out] block the flash block + * @param[out] page the flash page + * + * @param[out] offset the byte offset within the page + */ + +void flash_get_read_addr(uint32_t unit, uint32_t *block, + uint32_t *page, uint32_t *offset) +{ + (*block) = flash_unit_addr[unit].read.block; + (*page) = flash_unit_addr[unit].read.page; + (*offset) = flash_unit_addr[unit].read.offset; +} + + +/** + * @brief get the current flash write address + * + * @param[in] unit the flash unit + * @param[out] block the flash block + * @param[out] page the flash page + * + * @param[out] offset the byte offset within the page + */ + +void flash_get_write_addr(uint32_t unit, uint32_t *block, + uint32_t *page, uint32_t *offset) +{ + (*block) = flash_unit_addr[unit].write.block; + (*page) = flash_unit_addr[unit].write.page; + (*offset) = flash_unit_addr[unit].write.offset; +} + + +/** + * @brief select a column in the flash memory + * + * @param unit the flash unit + * @param address a physical flash address + */ +/* this is a little stupid, maybe redo */ +static void flash_set_column(uint32_t unit, uint32_t address) +{ + uint32_t i; + + struct iwf_fpga_flash_addr flash_addr; + struct iwf_flash_address addr; + + + addr.phys_addr = address; + + /* order is important*/ + for (i = 0; i < FLASH_CHIPS_PER_DEVICE; i++) + flash_addr.addr_chip[i] = addr.byte1; + + fpga_flash_write_addr(unit, flash_addr.addr); + + + for (i = 0; i < FLASH_CHIPS_PER_DEVICE; i++) + flash_addr.addr_chip[i] = addr.byte2; + + fpga_flash_write_addr(unit, flash_addr.addr); +} + + +/** + * @brief select a row in the flash memory + * + * @param unit the flash unit + * @param address a physical flash address + */ + +static void flash_set_row(uint32_t unit, uint32_t address) +{ + uint32_t i; + + struct iwf_fpga_flash_addr flash_addr; + struct iwf_flash_address addr; + + + addr.phys_addr = address; + + /* order is important*/ + for (i = 0; i < FLASH_CHIPS_PER_DEVICE; i++) + flash_addr.addr_chip[i] = addr.byte3; + + fpga_flash_write_addr(unit, flash_addr.addr); + + + for (i = 0; i < FLASH_CHIPS_PER_DEVICE; i++) + flash_addr.addr_chip[i] = addr.byte4; + + fpga_flash_write_addr(unit, flash_addr.addr); + + + for (i = 0; i < FLASH_CHIPS_PER_DEVICE; i++) + flash_addr.addr_chip[i] = addr.byte5; + + fpga_flash_write_addr(unit, flash_addr.addr); +} + + +/** + * @brief set the address in the flash memory + * + * @param unit the flash unit + * @param address a physical flash address + */ + +static void flash_set_addr(uint32_t unit, uint32_t flash_addr) +{ + /* order is important*/ + flash_set_column(unit, flash_addr); + flash_set_row(unit, flash_addr); +} + + +/** + * @brief set the block in the flash memory + * + * @param unit the flash unit + * @param address a physical flash address + */ + +static void flash_set_block_addr(uint32_t unit, uint32_t flash_addr) +{ + flash_set_row(unit, flash_addr); +} + + +/** + * @brief generate a physical address in a flash memory + * + * @param block the flash block + * @param page the flash page + * @param offset the offset in the page + * + * @return the physical flash address + */ + +uint32_t flash_gen_phys_addr(uint32_t block, uint32_t page, uint32_t offset) +{ + uint32_t addr; + + + offset &= (1 << FLASH_PAGE_OFFSET_BITS) - 1; + + addr = page + block * FLASH_PAGES_PER_BLOCK; + addr = addr << FLASH_PAGE_ADDR_SHIFT; + addr = addr | offset; + + return addr; +} + + +/** + * @brief generate a logical address in a flash memory + * + * @param block the flash block + * @param page the flash page + * @param offset the offset in the page + * + * @return the logical flash address + */ + +uint32_t flash_gen_logical_addr(uint32_t block, uint32_t page, uint32_t offset) +{ + uint32_t addr; + + + offset &= (1 << FLASH_LOGICAL_PAGE_OFFSET_BITS) - 1; + + addr = page + block * FLASH_PAGES_PER_BLOCK; + addr = addr << FLASH_LOGICAL_PAGE_ADDR_SHIFT; + addr = addr | (offset << FLASH_LOGICAL_PAGE_OFFSET_SHIFT); + + return addr; +} + + +/** + * @brief reverse a logical address in a flash memory + * + * @param addr[in] the logical flash address + * @param block[out] the flash unit + * @param page[out] the flash page + * @param offset[out] the offset in the page + */ + +void flash_reverse_logical_addr(uint32_t addr, uint32_t *block, + uint32_t *page, uint32_t *offset) +{ + (*offset) = (addr >> FLASH_LOGICAL_PAGE_OFFSET_SHIFT) + & ((1 << FLASH_LOGICAL_PAGE_OFFSET_BITS) - 1); + + addr = addr >> FLASH_LOGICAL_PAGE_ADDR_SHIFT; + /* only works with powers of two */ + (*page) = addr & (FLASH_PAGES_PER_BLOCK - 1); + + (*block) = addr >> __builtin_popcount(FLASH_PAGES_PER_BLOCK - 1); +} + + +/** + * @brief check the configuration parameters for a flash operation + * + * @param block the flash block + * @param page the flash page + * @param offset the offset in the page + * + * @return 0 on success, -1 on failure + */ + +static int32_t flash_check_cfg(uint32_t block, uint32_t page, + uint32_t offset) +{ + if (block >= FLASH_BLOCKS_PER_CHIP) { + errno = ERR_FLASH_BLOCKS_EXCEEDED; + return -1; + } + + if (page >= FLASH_PAGES_PER_BLOCK) { + errno = ERR_FLASH_PAGES_EXCEEDED; + return -1; + } + + if (offset >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_PAGESIZE_EXCEEDED; + return -1; + } + + if (!fpga_mem_ctrl_sram_flash_enabled()) { + errno = ERR_FLASH_DISABLED; + return -1; + } + + return 0; +} + + +/** + * @brief program a flash read sequence + * + * @param unit the flash unit + * @param block the flash block + * @param page the flash page + * + * @param offset the byte offset within the page + */ + +static void flash_program_read_sequence(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset) +{ + uint32_t flash_addr; + + flash_internal_set_read_addr(unit, block, page, offset); + + flash_addr = flash_gen_phys_addr(block, page, offset); + + fpga_flash_set_cmd(unit, FLASH_CMD_READ_SEQ_1); + + flash_set_addr(unit, flash_addr); + + fpga_flash_set_cmd(unit, FLASH_CMD_READ_SEQ_2); +} + + +/** + * @brief check if the flash block is valid + * + * @param unit the flash unit + * @param block the flash block + * + * @return 1 if block is valid, 0 otherwise + */ + +uint32_t flash_block_valid(uint32_t unit, uint32_t block) +{ + uint32_t i; + uint32_t ret; + + uint32_t check_pages[] = FLASH_BAD_BLOCK_PAGES; + + + for (i = 0; i < ARRAY_SIZE(check_pages); i++) { + + flash_program_read_sequence(unit, block, check_pages[i], + FLASH_BAD_BLOCK_BYTE); + + /* bypass the EDAC by reading the data from the status + * register instead of the data register via flash_read_word() + */ + ret = fpga_flash_read_status(unit); + + if (ret != FLASH_BLOCK_VALID) { + errno = ERR_FLASH_BLOCK_INVALID; + return 0; + } + + /* if this is the case, the EDAC flash block is not 0xff + * and an uncorrectable EDAC error has been raised in + * the AHB register + */ + if (!fpga_flash_empty()) { + errno = ERR_FLASH_BLOCK_INVALID; + return 0; + } + } + + return 1; +} + + +/** + * @brief initialise a read to check if a flash block is empty + * + * @param unit the flash unit + * @param block the flash block + * @param page the flash page + * @param offset the byte offset within the page + * + * @return 1 if the block is empty, 0 otherwise + */ + +uint32_t flash_empty(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset) +{ + flash_program_read_sequence(unit, block, page, offset); + + fpga_flash_read_status(unit); + + if (fpga_flash_empty()) + return 1; + + return 0; +} + + +/** + * @brief initialise a flash read sequence + * + * @param unit the flash unit + * @param block the flash block + * @param page the flash page + * @param offset the byte offset within the page + * + * @return -1 in case of error, 0 otherwise + */ + +int32_t flash_init_read(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset) +{ + if (flash_check_cfg(block, page, offset)) + return -1; /* errno set by callee */ + + if (flash_empty(unit, block, page, offset)) { + errno = ERR_FLASH_ADDR_EMPTY; + return -1; + } + + flash_program_read_sequence(unit, block, page, offset); + + return 0; +} + + + +/** + * @brief read a word from flash + * + * @param unit the flash unit + * @param addr if 0, the data next flash address pointer will be read, + * otherwise a seek is performed + * + * @return the value read; if the returned value has all bits set, errno + * should be checked for ERR_FLASH_READ_PAGE_EXCEEDED which indicates + * an invalid address within a page + */ + +uint32_t flash_read_word(uint32_t unit, uint32_t offset) +{ + if (offset >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + + if (offset) { + flash_internal_set_read_offset(unit, offset); + + fpga_flash_set_cmd(unit, FLASH_CMD_READ_UPDATE_ADDR_1); + flash_set_column(unit, offset); + fpga_flash_set_cmd(unit, FLASH_CMD_READ_UPDATE_ADDR_2); + } + + if (!offset) { + if (flash_internal_get_read_offset(unit) >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + } + + flash_internal_inc_read_offset(unit); + + return fpga_flash_read_word(unit); +} + + +/** + * @brief read a series of words from flash + * + * @param unit the flash unit + * @param addr if 0, the data next flash address pointer will be read, + * otherwise a seek is performed + * + * @return 0 on success, -1 on error + */ + +int32_t flash_read(uint32_t unit, uint32_t offset, uint32_t *buf, uint32_t len) +{ + uint32_t i; + + + if (offset >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + + if ((offset + len - 1) >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + + + if (offset) { + flash_internal_set_read_offset(unit, offset); + + fpga_flash_set_cmd(unit, FLASH_CMD_READ_UPDATE_ADDR_1); + flash_set_column(unit, offset); + fpga_flash_set_cmd(unit, FLASH_CMD_READ_UPDATE_ADDR_2); + } else { + i = flash_internal_get_read_offset(unit); + if ((i + len - 1) >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + } + + for (i = 0; i < len; i++) { + buf[i] = fpga_flash_read_word(unit); + } + + flash_internal_set_read_offset(unit, + flash_internal_get_read_offset(unit) + + len); + + return 0; +} + + +/** + * @brief read a series of words from flash and bypass the EDAC + * + * @param unit the flash unit + * @param addr if 0, the data next flash address pointer will be read, + * otherwise a seek is performed + * + * @return 0 on success, -1 on error + */ + +int32_t flash_read_bypass_edac(uint32_t unit, uint32_t offset, + uint32_t *buf, uint32_t len) +{ + uint32_t i; + + + if (offset >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + + if ((offset + len - 1) >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + + + if (offset) { + flash_internal_set_read_offset(unit, offset); + + fpga_flash_set_cmd(unit, FLASH_CMD_READ_UPDATE_ADDR_1); + flash_set_column(unit, offset); + fpga_flash_set_cmd(unit, FLASH_CMD_READ_UPDATE_ADDR_2); + } else { + i = flash_internal_get_read_offset(unit); + if ((i + len - 1) >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_READ_PAGE_EXCEEDED; + return -1; + } + } + + for (i = 0; i < len; i++) { + buf[i] = fpga_flash_read_status(unit); + flash_internal_inc_read_offset(unit); + } + + return 0; +} + + + + +/** + * @brief mark a flash block as invalid + * + * @param unit the flash unit + * @param block the flash block + */ + +static void flash_mark_bad_block(uint32_t unit, uint32_t block) +{ + uint32_t i; + uint32_t flash_addr; + + uint32_t bad_block_pages[] = FLASH_BAD_BLOCK_PAGES; + + + for (i = 0; i < ARRAY_SIZE(bad_block_pages); i++) { + + flash_addr = flash_gen_phys_addr(block, bad_block_pages[i], + FLASH_BAD_BLOCK_BYTE); + + fpga_flash_disable_write_protect(); + + fpga_flash_set_cmd(unit, FLASH_CMD_PAGE_PROGRAM_SEQ_1); + flash_set_addr(unit, flash_addr); + + flash_write_word(unit, 0x0); + + fpga_flash_set_cmd(unit, FLASH_CMD_PAGE_PROGRAM_SEQ_2); + + fpga_flash_enable_write_protect(); + + /* status can be ignored, just pulling one bit down + * will make this successful + */ + } +} + + +/** + * @brief write a word to flash + * + * @param unit the flash unit + * @param word the word to write + * + * @return -1 on error, 0 otherwise + */ + +int32_t flash_write_word(uint32_t unit, uint32_t word) +{ + uint32_t tmp; + + + tmp = flash_internal_get_write_offset(unit); + + if (tmp >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_WRITE_PAGE_EXCEEDED; + return -1; + } + + fpga_flash_write_word(unit, word); + flash_internal_inc_write_offset(unit); + + return 0; +} + + +/** + * @brief write a buffer of 32 bit words to flash + * + * @param unit the flash unit + * @param buf the buffer to write + * @param len the number of words in the buffer + * + * @return -1 on error, 0 otherwise + */ + +int32_t flash_write(uint32_t unit, uint32_t *buf, uint32_t len) +{ + uint32_t i; + + + i = flash_internal_get_write_offset(unit); + + if ((i + len - 1) >= FLASH_PAGE_SIZE) { + errno = ERR_FLASH_WRITE_PAGE_EXCEEDED; + return -1; + } + + + for (i = 0; i < len; i++) + fpga_flash_write_word(unit, buf[i]); + + flash_internal_set_write_offset(unit, + flash_internal_get_write_offset(unit) + + len); + + return 0; +} + + +/** + * @brief initialise a flash write sequence + * + * @param unit the flash unit + * @param block the flash block + * @param page the flash page + * @param offset the byte offset within the page + * + * @return -1 in case of error, 0 otherwise + */ + +int32_t flash_init_write(uint32_t unit, uint32_t block, + uint32_t page, uint32_t offset) +{ + uint32_t flash_addr; + + + if (flash_check_cfg(block, page, offset)) + return -1; /* errno set by callee */ + + /* NOTE: Mantis 2238 (Note 4721) + flash_block_valid removed, because it is already + checked in flash_erase_block */ + + flash_internal_set_write_addr(unit, block, page, offset); + + flash_addr = flash_gen_phys_addr(block, page, offset); + + fpga_flash_disable_write_protect(); + + fpga_flash_set_cmd(unit, FLASH_CMD_PAGE_PROGRAM_SEQ_1); + flash_set_addr(unit, flash_addr); + + + return 0; +} + + +/** + * @brief finish a flash write sequence + * + * @param unit the flash unit + * + * @return -1 on error, 0 otherwise + */ + +int32_t flash_stop_write(uint32_t unit) +{ + uint32_t status; + + + fpga_flash_set_cmd(unit, FLASH_CMD_PAGE_PROGRAM_SEQ_2); + + fpga_flash_enable_write_protect(); + + fpga_flash_set_cmd(unit, FLASH_CMD_READ_STATUS); + + status = fpga_flash_read_status(unit); + + if (status & FLASH_STATUS_FAIL) { + flash_mark_bad_block(unit, flash_get_write_block(unit)); + errno = ERR_FLASH_DATA_WRITE_ERROR; + return -1; + } + + status = fpga_flash_read_edac_status(); + + if (status & FLASH_EDAC_STATUS_FAIL) { + flash_mark_bad_block(unit, flash_get_write_block(unit)); + errno = ERR_FLASH_EDAC_WRITE_ERROR; + return -1; + } + + return 0; +} + + +/** + * @brief erase a flash block + * + * @param unit the flash unit + * @param block the flash block + * + * @return -1 on error, 0 otherwise + */ + +int32_t flash_erase_block(uint32_t unit, uint32_t block) +{ + uint32_t status; + uint32_t flash_addr; + + /* Mantis 2270: retry once on invalid status */ + if (!flash_block_valid(unit, block)) + { + flash_erase_retry++; + + if (!flash_block_valid(unit, block)) + { + return -1; /* errno set by callee */ + } + } + + flash_addr = flash_gen_phys_addr(block, 0, 0); + + fpga_flash_disable_write_protect(); + + fpga_flash_set_cmd(unit, FLASH_CMD_BLOCK_ERASE_SEQ_1); + flash_set_block_addr(unit, flash_addr); + + + fpga_flash_set_cmd(unit, FLASH_CMD_BLOCK_ERASE_SEQ_2); + + fpga_flash_enable_write_protect(); + + fpga_flash_set_cmd(unit, FLASH_CMD_READ_STATUS); + + status = fpga_flash_read_status(unit); + + if (status & FLASH_STATUS_FAIL) { + flash_mark_bad_block(unit, flash_get_write_block(unit)); + errno = ERR_FLASH_DATA_ERASE_ERROR; + return -1; + } + + status = fpga_flash_read_edac_status(); + + if (status & FLASH_EDAC_STATUS_FAIL) { + flash_mark_bad_block(unit, flash_get_write_block(unit)); + errno = ERR_FLASH_EDAC_ERASE_ERROR; + return -1; + } + + return 0; +} diff --git a/IBSW/lib/iwf_fpga.c b/IBSW/lib/iwf_fpga.c new file mode 100644 index 0000000000000000000000000000000000000000..ff0dc8328e7b09559560652f56c8e9650994b88e --- /dev/null +++ b/IBSW/lib/iwf_fpga.c @@ -0,0 +1,871 @@ +/** + * @file iwf_fpga.c + * @ingroup iwf_fpga + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * Roland Ottensamer (roland.ottensamer@univie.ac.at), + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup iwf_fpga IWF FPGA + * @brief Set of accessor functions for the IWF FPGA + * + * + * ## Overview + * + * This components implements functionality to access or modify registers in + * the IWF FPGA. + * + * @see + * - CHEOPS-IWF-INST-IRD-020 _CHEOPS BEE DPU Hardware - Software Interface + * Requirements_ for FPGA register mappings + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * - functionality will be added as needed + * + * + */ + + +#include <io.h> +#include <iwf_fpga.h> +#include <compiler.h> + +/* oh the humanity */ +struct iwf_fpga_map fpga = { + (struct iwf_fpga_version *) IWF_FPGA_BASE, + (struct iwf_fpga_dpu *) IWF_FPGA_DPU_BASE, + (struct iwf_fpga_reset *) IWF_FPGA_RESET_BASE, + (struct iwf_fpga_irq *) IWF_FPGA_IRQ_BASE, + (struct iwf_fpga_sem *) IWF_FPGA_SEM_BASE, + (struct iwf_fpga_heater *) IWF_FPGA_HEATER_BASE, + (struct iwf_fpga_adc_ctrl *) IWF_FPGA_ADC_CTRL_BASE, + (struct iwf_fpga_adc_val *) IWF_FPGA_ADC_VAL_BASE, + (struct iwf_fpga_mem_ctrl *) IWF_FPGA_MEM_CTRL_BASE, + (struct iwf_fpga_flash_cmd *) IWF_FPGA_FLASH_CMD_BASE, + (struct iwf_fpga_flash_addr *) IWF_FPGA_FLASH_ADDR_BASE, + (struct iwf_fpga_flash_status *) IWF_FPGA_FLASH_STATUS_BASE, + { + (uint32_t *) IWF_FPGA_FLASH_1_DATA_BASE, + (uint32_t *) IWF_FPGA_FLASH_2_DATA_BASE, + (uint32_t *) IWF_FPGA_FLASH_3_DATA_BASE, + (uint32_t *) IWF_FPGA_FLASH_4_DATA_BASE, + } +}; + + +/** + * @brief get FPGA version register + * + * @return the FPGA version register + * + * @see DPU-HIRD-IF-4010 in CHEOPS-IWF-INST-IRD for definition of fields + */ + +uint32_t fpga_version_reg_get(void) +{ + return ioread32be(&fpga.fpga->version); +} + + +/** + * @brief get FPGA DPU status register + * + * @return the FPGA DPU status register + * + * @see DPU-HIRD-IF-4020 in CHEOPS-IWF-INST-IRD for definition of fields + */ + +uint32_t fpga_dpu_status_reg_get(void) +{ + return ioread32be(&fpga.dpu->status); +} + +/** + * @brief get FPGA DPU address register + * + * @return the FPGA DPU address register + * + * @see DPU-HIRD-IF-4030 in CHEOPS-IWF-INST-IRD for definition of fields + */ + +uint32_t fpga_dpu_addr_reg_get(void) +{ + return ioread32be(&fpga.dpu->addr); +} + + +/** + * @brief get FPGA SEM status register + * + * @return the FPGA SEM status register + * + * @see DPU-HIRD-IF-4080 in CHEOPS-IWF-INST-IRD for definition of fields + */ + +uint32_t fpga_sem_status_reg_get(void) +{ + return ioread32be(&fpga.sem->status); +} + + +/** + * @brief get FPGA Instrument Operational Heater status register + * + * @return the FPGA Instrument Operational Heater status register + * + * @see DPU-HIRD-IF-4090 in CHEOPS-IWF-INST-IRD for definition of fields + */ + +uint32_t fpga_oper_heater_status_reg_get(void) +{ + return ioread32be(&fpga.heater->status); +} + + +/** + * @brief switch on the SEM + */ + +void fpga_sem_switch_on(uint8_t keyword) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.sem->status); + + /* clear destination bits */ + flags &= 0xffff00fe; + + /* enter password */ + flags |= (keyword << 8); + + /* enter on bit */ + flags |= SEM_ON; + + iowrite32be(flags, &fpga.sem->ctrl); +} + + +/** + * @brief switch off the SEM + */ + +void fpga_sem_switch_off(uint8_t keyword) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.sem->status); + + /* clear destination bits */ + flags &= 0xffff00fe; + + /* enter password */ + flags |= (keyword << 8); + + /* enter off bit */ + flags &= SEM_OFF; + + iowrite32be(flags, &fpga.sem->ctrl); +} + + +/** + * @brief switch on the SEM heaters + */ + +void fpga_sem_heater_on(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.sem->status); + flags |= SEM_HEATER_ON; + + iowrite32be(flags, &fpga.sem->ctrl); +} + + +/** + * @brief switch off the SEM heaters + */ + +void fpga_sem_heater_off(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.sem->status); + flags &= SEM_HEATER_OFF; + + iowrite32be(flags, &fpga.sem->ctrl); +} + + +/** + * @brief check if SEM status is ON + */ + +uint32_t fpga_sem_get_status_on(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.sem->status) & SEM_STATUS_ON; + + return flags; +} + + +/** + * @brief check if SEM status is FAILURE + */ + +uint32_t fpga_sem_get_status_failure(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.sem->status) & SEM_STATUS_FAILURE; + + return flags; +} + + +/** + * @brief check if SEM heater status is ON + */ + +uint32_t fpga_sem_get_status_heater_on(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.sem->status) & SEM_STATUS_HEATER_ON; + + return flags; +} + +/* getter functions for the BEE FPGA analog values */ +uint16_t fpga_adc_get_adc_p3v3(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->adc_p3v3__adc_p5v) >> 16) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_p5v(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->adc_p3v3__adc_p5v) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_p1v8(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->adc_p1v8__adc_p2v5) >> 16) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_p2v5(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->adc_p1v8__adc_p2v5) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_n5v(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->adc_n5v__adc_pgnd) >> 16) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_pgnd(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->adc_n5v__adc_pgnd) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh1a(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->adc_tempoh1a__adc_temp1) >> 16) + & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_temp1(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->adc_tempoh1a__adc_temp1) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh2a(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->adc_tempoh2a__adc_tempoh1b) >> 16) + & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh1b(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->adc_tempoh2a__adc_tempoh1b) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh3a(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->adc_tempoh3a__adc_tempoh2b) >> 16) + & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh2b(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->adc_tempoh3a__adc_tempoh2b) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh4a(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->adc_tempoh4a__adc_tempoh3b) >> 16) + & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh3b(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->adc_tempoh4a__adc_tempoh3b) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_spare_01(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->spare_01__adc_tempoh4b) >> 16) + & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_adc_tempoh4b(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->spare_01__adc_tempoh4b) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_sem_p15v(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->sem_p15v__sem_p30v) >> 16) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_sem_p30v(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->sem_p15v__sem_p30v) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_sem_p5v0(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->sem_p5v0__sem_p7v0) >> 16) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_sem_p7v0(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->sem_p5v0__sem_p7v0) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_spare_02(void) +{ + uint16_t value; + + + value = (ioread32be(&fpga.adc_val->spare_02__sem_n5v0) >> 16) & 0xffff; + + return value; +} + +uint16_t fpga_adc_get_sem_n5v0(void) +{ + uint16_t value; + + + value = ioread32be(&fpga.adc_val->spare_02__sem_n5v0) & 0xffff; + + return value; +} + +/* other adc registers are spare 03 .. 12 */ + + +/** + * @brief read DPU board serial number + * + * @return the board serial number + */ + +uint32_t fpga_dpu_get_board_serial(void) +{ + uint32_t ser; + + + ser = (ioread32be(&fpga.dpu->status) >> 12) & 0x7; + + return ser; +} + + +/** +* @brief read 1.8v core power supply status + * + * @return 0 on core power supply failure, 1 otherwise + */ + +uint32_t fpga_dpu_get_core_power_status(void) +{ + uint32_t pwr; + + + pwr = (ioread32be(&fpga.dpu->status) >> 1) & 0x1; + + return pwr; +} + + +/** +* @brief read DPU 3.3V, 2.5V power status + * + * @return 0 on DPU power supply failure, 1 otherwise + */ + +uint32_t fpga_dpu_get_dpu_power_status(void) +{ + uint32_t pwr; + + + pwr = ioread32be(&fpga.dpu->status) & 0x1; + + return pwr; +} + + +/** + * @brief read configured remote terminal address + * + * @return the remote terminal address + */ + +uint16_t fpga_dpu_get_rt_addr(void) +{ + uint16_t rt_addr; + + + rt_addr = (uint16_t) (ioread32be(&fpga.dpu->addr) >> 11) & 0x1f; + + return rt_addr; +} + + +/** + * @brief set a flag in the reset control register of the FPGA + * + * @param flag the flag to set + */ + +void fpga_reset_ctrl_set(uint32_t flag) +{ + iowrite32be(flag, &fpga.reset->ctrl); +} + + +/** + * @brief get the reset status register of the FPGA + * + * @return the contents of the reset status register + */ + +uint32_t fpga_reset_status_get(void) +{ + return ioread32be(&fpga.reset->status); +} + + +/** + * @brief turn on a heater + * + * @param h a heater id + */ + +void fpga_heater_on(enum heater h) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.heater->status); + flags |= (0x1UL << h); + + iowrite32be(flags, &fpga.heater->ctrl); +} + + +/** + * @brief turn of a heater + * + * @param h a heater id + */ + +void fpga_heater_off(enum heater h) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.heater->status); + flags &= ~(0x1UL << h); + + iowrite32be(flags, &fpga.heater->ctrl); +} + + +/** + * @brief get the status of a heater + * + * @param h a heater id + * + * @return bit set if on, 0 if off + */ + +uint32_t fpga_heater_status(enum heater h) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.heater->status); + flags &= (0x1UL << h); + + return flags; +} + + +/** + * @brief check if the FLASH is in READY status + * + * return 0 if not ready + */ + +uint32_t fpga_flash_ready(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.mem_ctrl->status); + flags &= MEM_CTRL_FLASH_READY; + + return flags; +} + + +/** + * @brief read the flash edac status field of the FPGA + * + * @return the contents of the flash edac status field + */ + +uint32_t fpga_flash_read_edac_status(void) +{ + return ioread32be(&fpga.mem_ctrl->flash_edac); +} + + +/** + * @brief check if the FLASH EDAC is in READY status + * + * return 0 if not ready + */ + +uint32_t fpga_flash_edac_ready(void) +{ + uint32_t flags; + + + flags = fpga_flash_read_edac_status(); + flags &= MEM_CTRL_FLASH_EDAC_READY; + + return flags; +} + + +/** + * @brief check if a programmed FLASH block is marked empty + * + * return 0 if not empty + */ + +uint32_t fpga_flash_empty(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.mem_ctrl->status); + flags &= MEM_CTRL_FLASH_EMPTY; + + return flags; +} + + +/** + * @brief write a flash command to the FPGA register + * + * @param unit the flash unit + * @param cmd the flash command word + */ + +void fpga_flash_set_cmd(uint32_t unit, uint32_t cmd) +{ + iowrite32be(cmd, &fpga.flash_cmd[unit]); + + /* insert a delay, otherwise the ready bit may not + * have been pulled down by the FPGA + * the required delay is 200 ns, this corresponds to 5 nops at 25 Mhz + */ + __asm__ __volatile__("nop;nop;nop;nop;nop" : : : "memory"); + + /* NOTE: with 200ns, we still see false EDAC errors on reading. */ + /* We have added some extra delay to have margin (Mantis 2070). */ + + __asm__ __volatile__("nop;nop;nop;nop;nop" : : : "memory"); + __asm__ __volatile__("nop;nop;nop;nop;nop" : : : "memory"); + __asm__ __volatile__("nop;nop;nop;nop;nop" : : : "memory"); + __asm__ __volatile__("nop;nop;nop;nop;nop" : : : "memory"); + + while (!fpga_flash_ready()) + cpu_relax(); +} + + +/** + * @brief write a flash address to the FPGA register + * + * @param unit the flash unit + * @param addr the flash address + */ + +void fpga_flash_write_addr(uint32_t unit, uint32_t addr) +{ + iowrite32be(addr, &fpga.flash_addr[unit]); +} + +/** + * @brief read a word from the FPGA <-> FLASH data port + * + * @param unit the flash unit + * @return a data word + */ + +uint32_t fpga_flash_read_word(uint32_t unit) +{ + return ioread32be(fpga.flash_data[unit]); +} + +/** + * @brief write a word to the FPGA <-> FLASH data port + * + * @param unit the flash unit + * @param word the data word + */ + +void fpga_flash_write_word(uint32_t unit, uint32_t word) +{ + iowrite32be(word, fpga.flash_data[unit]); +} + + +/** + * @brief read the flash status field + * + * @param unit the flash unit + * + * @return the contents of the flash status field + */ + +uint32_t fpga_flash_read_status(uint32_t unit) +{ + return ioread32be(&fpga.flash_status[unit]); +} + + + + + +/** + * @brief check if SRAM2/FLASH mode is enabled + * + * return 0 if disabled + */ + +uint32_t fpga_mem_ctrl_sram_flash_enabled(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.mem_ctrl->status); + flags &= MEM_CTRL_SRAM_FLASH_ACTIVE; + + return flags; +} + + +/** + * @brief enable SRAM2/FLASH mode + */ + +void fpga_mem_ctrl_sram_flash_set_enabled(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.mem_ctrl->status); + flags |= MEM_CTRL_SRAM_FLASH_ACTIVE; + + iowrite32be(flags, &fpga.mem_ctrl->ctrl); +} + + +/** + * @brief clear (disable) SRAM2/FLASH mode + */ + +void fpga_mem_ctrl_sram_flash_clear_enabled(void) +{ + uint32_t flags; + + + flags = ioread32be(&fpga.mem_ctrl->status); + flags &= ~MEM_CTRL_SRAM_FLASH_ACTIVE; + + iowrite32be(flags, &fpga.mem_ctrl->ctrl); +} + + +/** + * @brief disable FLASH write protect bit + */ + +void fpga_flash_disable_write_protect(void) +{ + uint32_t flags; + + flags = ioread32be(&fpga.mem_ctrl->status); + flags |= MEM_CTRL_WRITE_PROTECT_OFF; + + iowrite32be(flags, &fpga.mem_ctrl->ctrl); +} + + +/** + * @brief enable FLASH write protect bit + */ + +void fpga_flash_enable_write_protect(void) +{ + uint32_t flags; + + flags = ioread32be(&fpga.mem_ctrl->status); + flags &= MEM_CTRL_WRITE_PROTECT_ON; + + iowrite32be(flags, &fpga.mem_ctrl->ctrl); +} diff --git a/IBSW/lib/leon3_dsu.c b/IBSW/lib/leon3_dsu.c new file mode 100644 index 0000000000000000000000000000000000000000..704913bdefe855e6d2e88d09be853002f6628d51 --- /dev/null +++ b/IBSW/lib/leon3_dsu.c @@ -0,0 +1,832 @@ +/** + * @file leon3_dsu.c + * @ingroup leon3_dsu + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date February, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup leon3_dsu LEON3 DSU interface + * + * @brief Access to the DSU of the GR712RC LEON3FT (and possibly others) + * + * + * ## Overview + * + * This component implements access to the debug support unit of the GR712RC + * LEON3 processor. + * + * ## Mode of Operation + * + * @see _GR712RC user manual v2.7 chapter 9_ for information on the DSU + * + * ## Error Handling + * + * None + * + * ## Notes + * + * - functionality is added as needed + * - this can be the basis for a grmon replacement + * + */ + +#include <io.h> +#include <errors.h> +#include <leon3_dsu.h> + + + +/** + * @brief calculate address of output register %on for a window + * @see GR712-UM v2.3 pp. 81 + * + * @param cpu the cpu number + * @param n the index of the output register %on + * @param cwp the index of the register window + * + * @return 0 if error, otherwise address of register + */ + +__attribute__((unused)) +static uint32_t dsu_get_output_reg_addr(uint32_t cpu, uint32_t n, uint32_t cwp) +{ + if (cwp > NWINDOWS) { + errno = ERR_DSU_CWP_INVALID; + return 0; + } + + return (DSU_BASE(cpu) + 0x300000 + + (((cwp * 64) + 32 + (n * 4)) % (NWINDOWS * 64))); +} + + +/** + * @brief calculate address of local register %ln for a window + * @see GR712-UM v2.3 pp. 81 + * + * @param cpu the cpu number + * @param n the index of the local register %ln + * @param cwp the index of the register window + * + * @return 0 if error, otherwise address of register + */ + +__attribute__((unused)) +static uint32_t dsu_get_local_reg_addr(uint32_t cpu, uint32_t n, uint32_t cwp) +{ + if (cwp > NWINDOWS) { + errno = ERR_DSU_CWP_INVALID; + return 0; + } + + return (DSU_BASE(cpu) + 0x300000 + + (((cwp * 64) + 64 + (n * 4)) % (NWINDOWS * 64))); +} + + +/** + * @brief calculate address of input register %in for a window + * @see GR712-UM v2.3 pp. 81 + * + * @param cpu the cpu number + * @param n the index of the input register %in + * @param cwp the index of the register window + * + * @return 0 if error, otherwise address of register + */ + +__attribute__((unused)) +static uint32_t dsu_get_input_reg_addr(uint32_t cpu, uint32_t n, uint32_t cwp) +{ + if (cwp > NWINDOWS) { + errno = ERR_DSU_CWP_INVALID; + return 0; + } + + return (DSU_BASE(cpu) + 0x300000 + + (((cwp * 64) + 96 + (n * 4)) % (NWINDOWS * 64))); +} + + +/** + * @brief calculate address of global register %gn + * @see GR712-UM v2.3 pp. 81 + * + * @param cpu the cpu number + * @param n the index of the global register %gn + * + * @return address of register + */ + +__attribute__((unused)) +static uint32_t dsu_get_global_reg_addr(uint32_t cpu, uint32_t n) +{ + return (DSU_BASE(cpu) + 0x300000 + n * 4); +} + + +/** + * @brief calculate address of floating point register %fn + * @see GR712-UM v2.3 pp. 81 + * + * @param cpu the cpu number + * @param n the index of the floating-point register %fn + * + * @return address of register + */ + +__attribute__((unused)) +static uint32_t dsu_get_fpu_reg_addr(uint32_t cpu, uint32_t n) +{ + return (DSU_BASE(cpu) + 0x301000 + n * 4); +} + + +/** + * @brief set bits in the DSU control register + * + * @param cpu the cpu number + * @param flags the bitmask to set + */ + +static void dsu_set_dsu_ctrl(uint32_t cpu, uint32_t flags) +{ + uint32_t tmp; + + + tmp = ioread32be((void *) (DSU_CTRL + DSU_OFFSET_CPU(cpu))); + tmp |= flags; + iowrite32be(tmp, (void *) (DSU_CTRL + DSU_OFFSET_CPU(cpu))); +} + + +/** + * @brief get the DSU control register + * + * @param cpu the cpu number + * + * @return the contents of the DSU control register + */ + +static uint32_t dsu_get_dsu_ctrl(uint32_t cpu) +{ + return ioread32be((void *) (DSU_CTRL + DSU_OFFSET_CPU(cpu))); +} + + +/** + * @brief clear bits in the DSU control register + * + * @param cpu the cpu number + * @param flags the bitmask of flags to clear + */ + +static void dsu_clear_dsu_ctrl(uint32_t cpu, uint32_t flags) +{ + uint32_t tmp; + + + tmp = ioread32be((void *) (DSU_CTRL + DSU_OFFSET_CPU(cpu))); + tmp &= ~flags; + iowrite32be(tmp, (void *) (DSU_CTRL + DSU_OFFSET_CPU(cpu))); +} + + +/** + * @brief clear the Integer Units register file + * + * @param cpu the cpu number + */ + +void dsu_clear_iu_reg_file(uint32_t cpu) +{ + uint32_t i; + /* (NWINDOWS * (%ln + %ion) + %gn) * 4 bytes */ + const uint32_t iu_reg_size = (NWINDOWS * (8 + 8) + 8) * 4; + + + for (i = 0; i < iu_reg_size; i += 4) + iowrite32be(0x0, (void *) (DSU_OFFSET_CPU(cpu) + + DSU_IU_REG + i)); +} + + +/** + * @brief enable forcing processor to enter debug mode if any other processor + * in the system enters debug mode + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 83 + */ + +void dsu_set_force_enter_debug_mode(uint32_t cpu) +{ + uint16_t tmp; + + struct dsu_mode_mask *dmm + = (struct dsu_mode_mask *) DSU_MODE_MASK; + + + tmp = ioread16be(&dmm->enter_debug); + tmp |= (1 << cpu); + iowrite16be(tmp, &dmm->enter_debug); +} + + +/** + * @brief disable forcing processor to enter debug mode if any other processor + * in the system enters debug mode + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 83 + */ + +void dsu_clear_force_enter_debug_mode(uint32_t cpu) +{ + uint16_t tmp; + + struct dsu_mode_mask *dmm + = (struct dsu_mode_mask *) DSU_MODE_MASK; + + + tmp = ioread16be(&dmm->enter_debug); + tmp &= ~(1 << cpu); + iowrite16be(tmp, &dmm->enter_debug); +} + + +/** + * @brief do not allow a processor to force other processors into debug mode + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 83 + */ + +void dsu_set_noforce_debug_mode(uint32_t cpu) +{ + uint16_t tmp; + + struct dsu_mode_mask *dmm + = (struct dsu_mode_mask *) DSU_MODE_MASK; + + + tmp = ioread16be(&dmm->debug_mode); + tmp |= (1 << cpu); + iowrite16be(tmp, &dmm->debug_mode); +} + + +/** + * @brief allow a processor to force other processors into debug mode + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 83 + */ + +void dsu_clear_noforce_debug_mode(uint32_t cpu) +{ + uint16_t tmp; + + struct dsu_mode_mask *dmm + = (struct dsu_mode_mask *) DSU_MODE_MASK; + + + tmp = ioread16be(&dmm->debug_mode); + tmp &= ~(1 << cpu); + iowrite16be(tmp, &dmm->debug_mode); +} + + +/** + * @brief force a processors into debug mode if Break on Watchpoint (BW) bit + * in DSU control register is set + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_set_force_debug_on_watchpoint(uint32_t cpu) +{ + uint16_t tmp; + + struct dsu_break_step *dbs + = (struct dsu_break_step *) DSU_BREAK_STEP; + + + tmp = ioread16be(&dbs->break_now); + tmp |= (1 << cpu); + iowrite16be(tmp, &dbs->break_now); +} + + +/** + * @brief clear forcing debug mode if Break on + * Watchpoint (BW) bit in the DSU control register is set; + * resumes processor execution if in debug mode + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 83 + */ + +void dsu_clear_force_debug_on_watchpoint(uint32_t cpu) +{ + uint16_t tmp; + + struct dsu_break_step *dbs + = (struct dsu_break_step *) DSU_BREAK_STEP; + + + tmp = ioread16be(&dbs->break_now); + tmp &= ~(1 << cpu); + iowrite16be(tmp, &dbs->break_now); +} + + +/** + * @brief check if cpu is in error mode + * + * @param cpu the cpu number + * @return 1 if processor in error mode, else 0 + * + * @see GR712-UM v2.3 pp. 82 + */ + +uint32_t dsu_cpu_in_error_mode(uint32_t cpu) +{ + return (dsu_get_dsu_ctrl(cpu) & DSU_CTRL_PE); +} + + +/** + * @brief clear debug and halt flag of processor + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_clear_cpu_error_mode(uint32_t cpu) +{ + dsu_clear_dsu_ctrl(cpu, DSU_CTRL_PE); +} + + +/** + * @brief check if cpu is in halt mode + * + * @param cpu the cpu number + * + * @return 1 if processor in halt mode, else 0 + * + * @see GR712-UM v2.3 pp. 82 + */ + +uint32_t dsu_cpu_in_halt_mode(uint32_t cpu) +{ + return (dsu_get_dsu_ctrl(cpu) & DSU_CTRL_HL); +} + + +/** + * @brief put cpu in halt mode + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_cpu_set_halt_mode(uint32_t cpu) +{ + dsu_set_dsu_ctrl(cpu, DSU_CTRL_HL); +} + + +/** + * @brief enable debug mode on error + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_set_cpu_debug_on_error(uint32_t cpu) +{ + dsu_set_dsu_ctrl(cpu, DSU_CTRL_BE); +} + + +/** + * @brief disable debug mode on error + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_clear_cpu_debug_on_error(uint32_t cpu) +{ + dsu_clear_dsu_ctrl(cpu, DSU_CTRL_BE); +} + + +/** + * @brief enable debug mode on IU watchpoint + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_set_cpu_break_on_iu_watchpoint(uint32_t cpu) +{ + dsu_set_dsu_ctrl(cpu, DSU_CTRL_BW); +} + + +/** + * @brief disable debug mode on IU watchpoint + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_clear_cpu_break_on_iu_watchpoint(uint32_t cpu) +{ + dsu_clear_dsu_ctrl(cpu, DSU_CTRL_BW); +} + + +/** + * @brief enable debug mode on breakpoint instruction (ta 1) + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_set_cpu_break_on_breakpoint(uint32_t cpu) +{ + dsu_set_dsu_ctrl(cpu, DSU_CTRL_BS); +} + + +/** + * @brief disable debug mode on breakpoint instruction + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_clear_cpu_break_on_breakpoint(uint32_t cpu) +{ + dsu_clear_dsu_ctrl(cpu, DSU_CTRL_BS); +} + + +/** + * @brief enable debug mode on trap + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_set_cpu_break_on_trap(uint32_t cpu) +{ + dsu_set_dsu_ctrl(cpu, DSU_CTRL_BX); +} + + +/** + * @brief disable debug mode on trap + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_clear_cpu_break_on_trap(uint32_t cpu) +{ + dsu_clear_dsu_ctrl(cpu, DSU_CTRL_BX); +} + + +/** + * @brief enable debug mode on error trap (all except: + * (priviledged_instruction, fpu_disabled, window_overflow, + * window_underflow, asynchronous_interrupt, ticc_trap) + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_set_cpu_break_on_error_trap(uint32_t cpu) +{ + dsu_set_dsu_ctrl(cpu, DSU_CTRL_BZ); +} + + +/** + * @brief disable debug mode on error trap (all except: + * (priviledged_instruction, fpu_disabled, window_overflow, + * window_underflow, asynchronous_interrupt, ticc_trap) + * + * @param cpu the cpu number + * + * @see GR712-UM v2.3 pp. 82 + */ + +void dsu_clear_cpu_break_on_error_trap(uint32_t cpu) +{ + dsu_clear_dsu_ctrl(cpu, DSU_CTRL_BZ); +} + +/** + * @brief get %y register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %y register + */ + +uint32_t dsu_get_reg_y(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_Y)); +} + + +/** + * @brief set %y register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_y(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_Y)); +} + + +/** + * @brief get %psr register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %psr register + */ + +uint32_t dsu_get_reg_psr(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_PSR)); +} + + +/** + * @brief set %psr register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_psr(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_PSR)); +} + + +/** + * @brief get %wim register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %wim register + */ + +uint32_t dsu_get_reg_wim(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_WIM)); +} + + +/** + * @brief set %wim register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_wim(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_WIM)); +} + + +/** + * @brief get %tbr register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %tbr register + */ + +uint32_t dsu_get_reg_tbr(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_TBR)); +} + + +/** + * @brief set %tbr register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_tbr(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_TBR)); +} + + +/** + * @brief get %pc register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %pc register + */ + +uint32_t dsu_get_reg_pc(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_PC)); +} + + +/** + * @brief set %npc register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_pc(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_PC)); +} + + +/** + * @brief get %npc register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %npc register + */ + +uint32_t dsu_get_reg_npc(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_NPC)); +} + + +/** + * @brief set %npc register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_npc(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_NPC)); +} + + +/** + * @brief get %fsr register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %fsr register + */ + +uint32_t dsu_get_reg_fsr(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_FSR)); +} + + +/** + * @brief set %fsr register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_fsr(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_FSR)); +} + + +/** + * @brief get %cpsr register of cpu + * + * @param cpu the cpu number + * + * @return contents of the %cpsr register + */ + +uint32_t dsu_get_reg_cpsr(uint32_t cpu) +{ + return ioread32be((void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_CPSR)); +} + +/** + * @brief set %cpsr register of cpu + * + * @param cpu the cpu number + * @param val the value to set + */ + +void dsu_set_reg_cpsr(uint32_t cpu, uint32_t val) +{ + iowrite32be(val, (void *) (DSU_OFFSET_CPU(cpu) + DSU_REG_CPSR)); +} + +/** + * @brief set stack pointer register (%o6) in a window of a cpu + * + * @param cpu the cpu number + * @param cwp the window number + * @param val the value to set + */ + +void dsu_set_reg_sp(uint32_t cpu, uint32_t cwp, uint32_t val) +{ + uint32_t reg; + + reg = dsu_get_output_reg_addr(cpu, 6, cwp); + + if (reg) + iowrite32be(val, (void *) reg); +} + + +/** + * @brief get stack pointer register (%o6) in a window of a cpu + * + * @param cpu the cpu number + * @param cwp the window number + * @return the value of the stack pointer register or 0 if window/cpu is invalid + */ + +uint32_t dsu_get_reg_sp(uint32_t cpu, uint32_t cwp) +{ + uint32_t reg; + + reg = dsu_get_output_reg_addr(cpu, 6, cwp); + + if (reg) + return ioread32be((void *) reg); + else + return 0; +} + + +/** + * @brief set frame pointer register (%i6) in a window of a cpu + * + * @param cpu the cpu number + * @param cwp the window number + * @param val the value to set + */ + +void dsu_set_reg_fp(uint32_t cpu, uint32_t cwp, uint32_t val) +{ + uint32_t reg; + + reg = dsu_get_input_reg_addr(cpu, 6, cwp); + + if (reg) + iowrite32be(val, (void *) reg); +} diff --git a/IBSW/lib/memcfg.c b/IBSW/lib/memcfg.c new file mode 100644 index 0000000000000000000000000000000000000000..23e04d633566dd44b6048132f06a37f7201a140d --- /dev/null +++ b/IBSW/lib/memcfg.c @@ -0,0 +1,653 @@ +/** + * @file memcfg.c + * @ingroup memcfg + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date March, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup memcfg Memory Configuration Register access + * + * @brief Implements memory configuration register access functions for the + * GR712RC + * + * ## Overview + * + * This module implements functionality to access or modify the memory + * configuration registers of the GR712RC. + * + * In addition, it provides functions to perform EDAC bypass reads and writes + * for fault injection. + * + * @see GR712-UM v2.7 5.14.1 - 5.14.4 + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * - functionality will be added as needed + * - does not provide support for the FTAHB memory configuration register! + * + */ + + +#include <io.h> +#include <memcfg.h> +#include <leon/leon_reg.h> + + +/** + * @brief set bits in the memory configuration register 1 by mask + * + * @param mask the bitmask to apply + */ + +static void memcfg_set_mcfg1(uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg1); + tmp |= mask; + iowrite32be(tmp, &memctrl->mcfg1); + +} + + +/** + * @brief get bits in the memory configuration register 1 by mask + * + * @param mask the bitmask to apply + */ +__attribute__((unused)) +static uint32_t memcfg_get_mcfg1(uint32_t mask) +{ + struct leon3_ftmctrl_registermap const *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + return ioread32be(&memctrl->mcfg1) & mask; +} + + +/** + * @brief clear bits in the memory configuration register 1 by mask + * + * @param mask the bitmask to apply (bits to clear are HIGH!) + */ + +static void memcfg_clear_mcfg1(uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg1); + tmp &= ~mask; + iowrite32be(tmp, &memctrl->mcfg1); + +} + + +/** + * @brief replace bits in the memory configuration register 1 by mask + * + * @param bits the bits to set + * @param mask the bitmask used to clear the field + */ + +static void memcfg_replace_mcfg1(uint32_t bits, uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg1); + tmp &= ~mask; + tmp |= bits; + iowrite32be(tmp, &memctrl->mcfg1); + +} + + +/** + * @brief set bits in the memory configuration register 2 by mask + * + * @param mask the bitmask to apply + */ + +static void memcfg_set_mcfg2(uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg2); + tmp |= mask; + iowrite32be(tmp, &memctrl->mcfg2); + +} + + +/** + * @brief get bits in the memory configuration register 2 by mask + * + * @param mask the bitmask to apply + */ + +__attribute__((unused)) +static uint32_t memcfg_get_mcfg2(uint32_t mask) +{ + struct leon3_ftmctrl_registermap const *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + return ioread32be(&memctrl->mcfg2) & mask; +} + + +/** + * @brief clear bits in the memory configuration register 2 by mask + * + * @param mask the bitmask to apply (bits to clear are HIGH!) + */ + +static void memcfg_clear_mcfg2(uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg2); + tmp &= ~mask; + iowrite32be(tmp, &memctrl->mcfg2); + +} + + +/** + * @brief replace bits in the memory configuration register 2 by mask + * + * @param bits the bits to set + * @param mask the bitmask used to clear the field + */ + +static void memcfg_replace_mcfg2(uint32_t bits, uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg2); + tmp &= ~mask; + tmp |= bits; + iowrite32be(tmp, &memctrl->mcfg2); + +} + +/** + * @brief set bits in the memory configuration register 3 by mask + * + * @param mask the bitmask to apply + */ + +static void memcfg_set_mcfg3(uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg3); + tmp |= mask; + iowrite32be(tmp, &memctrl->mcfg3); + +} + + +/** + * @brief get bits in the memory configuration register 3 by mask + * + * @param mask the bitmask to apply + */ + +static uint32_t memcfg_get_mcfg3(uint32_t mask) +{ + struct leon3_ftmctrl_registermap const *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + return ioread32be(&memctrl->mcfg3) & mask; +} + + +/** + * @brief clear bits in the memory configuration register 3 by mask + * + * @param mask the bitmask to apply (bits to clear are HIGH!) + */ + +static void memcfg_clear_mcfg3(uint32_t mask) +{ + uint32_t tmp; + + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + tmp = ioread32be(&memctrl->mcfg3); + tmp &= ~mask; + iowrite32be(tmp, &memctrl->mcfg3); + +} + +/** + * @brief set edac test checkbits + * + * @param tcb the checkbits to set + */ + +static void memcfg_set_checkbits(uint8_t tcb) +{ + memcfg_clear_mcfg3(MCFG3_TCB); + memcfg_set_mcfg3(((uint32_t) tcb) & MCFG3_TCB); +} + + +/** + * @brief get edac test checkbits + * + * @return the test checkbits + */ + +static uint8_t memcfg_get_checkbits(void) +{ + return (uint8_t) memcfg_get_mcfg3(MCFG3_TCB); +} + + + +/** + * @brief enable the prom edac + */ + +void memcfg_enable_prom_edac(void) +{ + memcfg_set_mcfg3(MCFG3_PROM_EDAC); +} + + +/** + * @brief disable the prom edac + */ + +void memcfg_disable_prom_edac(void) +{ + memcfg_clear_mcfg3(MCFG3_PROM_EDAC); +} + + +/** + * @brief enable the ram edac + */ + +void memcfg_enable_ram_edac(void) +{ + memcfg_set_mcfg3(MCFG3_RAM_EDAC); +} + + +/** + * @brief disable the ram edac + */ + +void memcfg_disable_ram_edac(void) +{ + memcfg_clear_mcfg3(MCFG3_RAM_EDAC); +} + + +/** + * @brief enable edac ram bypass read + */ + +void memcfg_enable_edac_read_bypass(void) +{ + memcfg_set_mcfg3(MCFG3_RB_EDAC); +} + + +/** + * @brief disable edac ram bypass read + */ + +void memcfg_disable_edac_read_bypass(void) +{ + memcfg_clear_mcfg3(MCFG3_RB_EDAC); +} + + +/** + * @brief enable edac ram bypass write + */ + +void memcfg_enable_edac_write_bypass(void) +{ + memcfg_set_mcfg3(MCFG3_WB_EDAC); +} + + +/** + * @brief disable edac ram bypass write + */ + +void memcfg_disable_edac_write_bypass(void) +{ + memcfg_clear_mcfg3(MCFG3_WB_EDAC); +} + + +/** + * @brief perform a bypass read and retrieve the checkbits + * + * @param addr the address pointer to read from + * @param tcb checkbits storage + * + * @return data word at address + */ + +uint32_t memcfg_bypass_read(void *addr, uint8_t *tcb) +{ + uint32_t val; + + memcfg_enable_edac_read_bypass(); + val = ioread32be(addr); + (*tcb) = memcfg_get_checkbits(); + memcfg_disable_edac_read_bypass(); + + return val; +} + + +/** + * @brief set custom checkbits and perform a bypass write + * + * @param addr the address pointer to write to + * @param value the data word to write + * @param tcb the checkbits to set + * + */ + +void memcfg_bypass_write(void *addr, uint32_t value, uint8_t tcb) +{ + memcfg_enable_edac_write_bypass(); + memcfg_set_checkbits(tcb); + iowrite32be(value, addr); + memcfg_disable_edac_write_bypass(); +} + + +/** + * @brief disable bus ready signalling for the prom area + */ + +void memcfg_clear_prom_area_bus_ready(void) +{ + memcfg_clear_mcfg1(MCFG1_PBRDY); +} + + +/** + * @brief disable asynchronous bus ready + */ + +void memcfg_clear_asynchronous_bus_ready(void) +{ + memcfg_clear_mcfg1(MCFG1_ABRDY); +} + + +/** + * @brief set IO bus width + * + * @note 0 (00) = 8 bits, 2 (01) = 32 bits + */ + +void memcfg_set_io_bus_width(uint32_t bus_width) +{ + memcfg_replace_mcfg1((bus_width << MCFG1_IOBUSW_OFF) + & MCFG1_IOBUSW_MASK, + MCFG1_IOBUSW_MASK); +} + + +/** + * @brief disable bus ready signalling for IO area + */ + +void memcfg_clear_io_bus_ready(void) +{ + memcfg_clear_mcfg1(MCFG1_IBRDY); +} + + +/** + * @brief disable bus error signalling + */ + +void memcfg_clear_bus_error(void) +{ + memcfg_clear_mcfg1(MCFG1_BEXCN); +} + + +/** + * @brief set IO waitstates + * + * @note 0000 = 0, 0001 = 1, 0010 = 2,..., 1111 = 15 + */ + +void memcfg_set_io_waitstates(uint32_t wait_states) +{ + memcfg_replace_mcfg1((wait_states << MCFG1_IO_WAITSTATES_OFF) + & MCFG1_IO_WAITSTATES_MASK, + MCFG1_IO_WAITSTATES_MASK); + +} + + +/** + * @brief enable access to memory IO bus area + */ + +void memcfg_set_io(void) +{ + memcfg_set_mcfg1(MCFG1_IOEN); +} + + +/** + * @brief set PROM bank size + * + * @note 0000 = 256 MiB, all others: bank_size = lg2(kilobytes / 8) + */ + +void memcfg_set_prom_bank_size(uint32_t bank_size) +{ + memcfg_replace_mcfg1((bank_size << MCFG1_ROMBANKSZ_OFF) + & MCFG1_ROMBANKSZ_MASK, + MCFG1_ROMBANKSZ_MASK); +} + + +/** + * @brief enable prom write cycles + */ + +void memcfg_set_prom_write(void) +{ + memcfg_set_mcfg1(MCFG1_PWEN); +} + + + +/** + * @brief set PROM data bus width + * + * @note 0 (00) = 8 bits, 2 (01) = 32 bits + */ + +void memcfg_set_prom_width(uint32_t prom_width) +{ + memcfg_replace_mcfg1((prom_width << MCFG1_PROM_WIDTH_OFF) + & MCFG1_PROM_WIDTH_MASK, + MCFG1_PROM_WIDTH_MASK); +} + + +/** + * @brief set PROM write waitstates + * + * @note 0000 = 0, 0001 = 2, 0010 = 4,..., 1111 = 30 + */ + +void memcfg_set_prom_write_waitstates(uint32_t wait_states) +{ + memcfg_replace_mcfg1((wait_states << MCFG1_PROM_WRITE_WS_OFF) + & MCFG1_PROM_WRITE_WS_MASK, + MCFG1_PROM_WRITE_WS_MASK); +} + +/** + * @brief set PROM read waitstates + * + * @note 0000 = 0, 0001 = 2, 0010 = 4,..., 1111 = 30 + */ + +void memcfg_set_prom_read_waitstates(uint32_t wait_states) +{ + memcfg_replace_mcfg1(wait_states & MCFG1_PROM_READ_WS_MASK, + MCFG1_PROM_READ_WS_MASK); +} + + +/** + * @brief disable SDRAM controller + */ + +void memcfg_clear_sdram_enable(void) +{ + memcfg_clear_mcfg2(MCFG2_SE); +} + + +/** + * @brief enable SRAM + */ + +void memcfg_clear_sram_disable(void) +{ + memcfg_clear_mcfg2(MCFG2_SI); +} + + +/** + * @brief set RAM bank size + * + * @note bank_size = lg2(kilobytes / 8) + */ + +void memcfg_set_ram_bank_size(uint32_t bank_size) +{ + memcfg_replace_mcfg2((bank_size << MCFG2_RAM_BANK_SIZE_OFF) + & MCFG2_RAM_BANK_SIZE_MASK, + MCFG2_RAM_BANK_SIZE_MASK); +} + + +/** + * @brief enable read-modify-write cycles + */ + +void memcfg_set_read_modify_write(void) +{ + memcfg_set_mcfg2(MCFG2_RMW); +} + + +/** + * @brief set RAM width + * + * @note 00 = 8 bits, 1X = 32 bits + */ + +void memcfg_set_ram_width(uint32_t ram_width) +{ + memcfg_replace_mcfg2((ram_width << MCFG2_RAM_WIDTH_OFF) + & MCFG2_RAM_WIDTH_MASK, + MCFG2_RAM_WIDTH_MASK); +} + + + +/** + * @brief set RAM write waitstates + * + * @note 00 = 0, 01 = 1, 10 = 2, 11 = 3 + */ + +void memcfg_set_ram_write_waitstates(uint32_t wait_states) +{ + memcfg_replace_mcfg2((wait_states << MCFG2_RAM_WRITE_WS_OFF) + & MCFG2_RAM_WRITE_WS_MASK, + MCFG2_RAM_WRITE_WS_MASK); +} + +/** + * @brief set RAM read waitstates + * + * @note 00 = 0, 01 = 1, 10 = 2, 11 = 3 + */ + +void memcfg_set_ram_read_waitstates(uint32_t wait_states) +{ + memcfg_replace_mcfg2(wait_states & MCFG2_RAM_READ_WS_MASK, + MCFG2_RAM_READ_WS_MASK); +} + + +/** + * @brief enable flash and ram access for use with IASW/IBSW + * @note does NOT change settings in the FPGA! + */ + +void memcfg_configure_sram_flash_access(void) +{ + struct leon3_ftmctrl_registermap *memctrl = + (struct leon3_ftmctrl_registermap *) LEON3_BASE_ADDRESS_FTMCTRL; + + /* NOTE: setting the bits individually does not work, + because some depend on others */ + + iowrite32be(MEMCFG1_FLASH, &memctrl->mcfg1); + iowrite32be(MEMCFG2_SRAM, &memctrl->mcfg2); + iowrite32be(MEMCFG3_SRAM, &memctrl->mcfg3); +} + diff --git a/IBSW/lib/memscrub.c b/IBSW/lib/memscrub.c new file mode 100644 index 0000000000000000000000000000000000000000..9a5bc58374464e0333044cf98af3c596c7743a23 --- /dev/null +++ b/IBSW/lib/memscrub.c @@ -0,0 +1,282 @@ +/** + * @file memscrub.c + * @ingroup memscrub + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date March, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup memscrub Memory Scrubbing + * @brief Implements memory scrubbing and repair of single-bit errors + * + * ## Overview + * + * This module provides functionality for memory scrubbing cycles, correctable + * error logging and memory repair. + * Note that only correctable errors are recorded and repaired, uncorrectable + * errors are reported via the @ref edac module + * + * ## Mode of Operation + * + * During each activation, starting from a specified address, a number of memory + * locations are read by forced data cache bypass in CPU-word sized (32 bit) + * increments. After each read, the AHB status register is inspected for single + * bit errors. If an error was raised and the registered failing address + * corresponds to the read address, it is logged for deferred memory repair. + * + * The user can call the repair function at any time. It masks interrupts and + * performs cache-bypassing read-write operations on the logged addresses. + * + * @startuml {memory_scrubbing.svg} "Memory Scrubbing process" width = 10 + * + * start + * + * repeat + * : read memory; + * : inspect AHB status; + * if (SBIT error) then (yes) + * if (address matches) then (yes) + * : log error; + * endif + * endif + * repeat while (done?) + * + * : mask interrrupts; + * + * while (logged error) + * : read memory; + * : write memory; + * endwhile + * + * : unmask interrrupts; + * + * stop + * + * @enduml + * + * + * ## Error Handling + * + * None + * + * + * ## Notes + * + * - There is no internal discrimination regarding repair of memory locations. + * Basically, a re-write is attempted for every single bit error detected. + * + * - To protect the system from unwanted re-writes by the repair function, any + * non-matching addresses expressing single-bit errors during scrubbing runs + * are rejected. This ensures that only memory ranges requested by the user + * will be re-written once the repair function is called. + * + * - If the memory error log is at capacity, no new errors will be added. + * + * - Irq masking is used to protect the re-write repair cycle within the + * bounds of the CPU, as there is no 32bit compare-and-swap atomic in the + * SPARC v8 instrution set. Be warned that it is not safe from memory + * interaction from (the) other CPU(s) for the same reason. If necessary, + * guards could be inserted to force other CPUs to pause execution via a + * dedicated synchronisation mechanism. In any case, this can never be safe + * from DMA unless all IP cores are deactivated. + * + * @example demo_memscrub.c + */ + +#include <event_report.h> +#include <io.h> +#include <ahb.h> +#include <list.h> +#include <compiler.h> +#include <spinlock.h> + +#define MEMSCRUB_LOG_ENTRIES 10 + +struct memscrub_log_entry { + uint32_t fail_addr; + struct list_head node; +}; + +static struct memscrub_log_entry memscrub_log_entries[MEMSCRUB_LOG_ENTRIES]; + +static struct list_head memscrub_log_used; +static struct list_head memscrub_log_free; + + + +/** + * @brief add an entry to the error log + * + * @param fail_addr the address of the single-bit error + * + * @note If no more free slots are available, the request will be ignored and + * the address will not be registered until another pass is made + */ + +static void memscrub_add_log_entry(uint32_t fail_addr) +{ + struct memscrub_log_entry *p_elem; + + + if (list_filled(&memscrub_log_free)) { + + p_elem = list_entry((&memscrub_log_free)->next, + struct memscrub_log_entry, node); + + list_move_tail(&p_elem->node, &memscrub_log_used); + p_elem->fail_addr = fail_addr; + } +} + + +/** + * @brief check the AHB status register for new single bit errors + * + * @return 0 if no error, + * 1 if error, + * -1 if error address does not match reference + */ + +static int32_t memscrub_inspect_ahb_status(uint32_t addr) +{ + uint32_t fail_addr; + + + if (ahbstat_new_error()) { + + fail_addr = ahbstat_get_failing_addr(); + + ahbstat_clear_new_error(); + + if (addr == fail_addr) + memscrub_add_log_entry(fail_addr); + + else + return -1; + + return 1; + } + + return 0; +} + + +/** + * @brief retrieve number of entries in the edac error log + * + * @return number of registered single-bit errors in the log + */ + +uint32_t memscrub_get_num_log_entries(void) +{ + uint32_t entries = 0; + + struct memscrub_log_entry *p_elem; + struct memscrub_log_entry *p_tmp; + + list_for_each_entry_safe(p_elem, p_tmp, &memscrub_log_used, node) + entries++; + + return entries; +} + + +/** + * @brief retrieve number of entries in the edac error log + * + * @return number of addresses repaired + */ + +uint32_t memscrub_repair(void) +{ + uint32_t psr; + uint32_t tmp; + uint32_t corr = 0; + + struct memscrub_log_entry *p_elem; + struct memscrub_log_entry *p_tmp; + + + list_for_each_entry_safe(p_elem, p_tmp, &memscrub_log_used, node) { + + psr = spin_lock_save_irq(); + tmp = ioread32be((void *) p_elem->fail_addr); + iowrite32be(tmp, (void *) p_elem->fail_addr); + spin_lock_restore_irq(psr); + + event_report(EDAC, LOW, p_elem->fail_addr); + list_move_tail(&p_elem->node, &memscrub_log_free); + + + corr++; + } + + ahbstat_clear_new_error(); + + return corr; +} + + + +/** + * @brief memory scrubbing of a range addr[0] ... addr[n] at a time + * + * Identified single-bit errors are stored in log for repair at a later time. + * + * @param addr the address pointer to start scrubbing from + * @param n the number of data words to scrub on top of starting address + * + * @return the next unscrubbed address + * + * @note + * - this function will never encounter a double bit error, since these + * must be handled via data_access_exception trap (0x9) for CPU errors + * and the AHB IRQ for all other AHB masters + * - the user is responsible to supply a valid address, range and proper + * alignment + * - this function will always access at least one address + */ + +uint32_t *memscrub(uint32_t *addr, uint32_t n) +{ + uint32_t *stop = addr + n; + + + ahbstat_clear_new_error(); + + for ( ; addr < stop; addr++) { + ioread32be(addr); + memscrub_inspect_ahb_status((uint32_t) addr); + } + + return stop; +} + + +/** + * @brief initialise the edac error log + * + * @note calling this function repeatedly will reset the log + */ + +void memscrub_init(void) +{ + uint32_t i; + + + INIT_LIST_HEAD(&memscrub_log_used); + INIT_LIST_HEAD(&memscrub_log_free); + + + for (i = 0; i < ARRAY_SIZE(memscrub_log_entries); i++) + list_add_tail(&memscrub_log_entries[i].node, + &memscrub_log_free); +} diff --git a/IBSW/lib/packet_tracker.c b/IBSW/lib/packet_tracker.c new file mode 100644 index 0000000000000000000000000000000000000000..8f78e24ea81356fa7970d68ec408b86eccb6db2e --- /dev/null +++ b/IBSW/lib/packet_tracker.c @@ -0,0 +1,370 @@ +/** + * @file packet_tracker.c + * @ingroup packet_tracker + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * + * + * @defgroup packet_tracker PUS packet container + * + * @brief a container for PUS packets implemented on top of the circular buffer + * interface + * + * ## Overview + * + * This is a container for packets in PUS format. It uses the regular circular + * buffers implementations to hold packet data in a @ref circular_buffer8 and + * tracks the corresponding packet sizes of the chunks in the packet data buffer + * in a @ref circular_buffer16. + * + * ## Mode of Operation + * + * ### Buffer Model + * + * This packet buffer is implemented using 2 circular buffers: + * one to hold the actual packet data (__Packet__, __[P]__), one to hold the + * size of the next packet (__Size__, __[S]__). + * + * The problem of synchronicity is solved the same way as in @ref cpus_buffer, + * by writing [S] only after [P] has been written and reading only after [S] + * appears to the reader. + * + * @startuml "[S] is a metabuffer \"containing\" [P]" width=5 + * node "[S]" { + * node "[P]" { + * } + * } + * @enduml + * + * + * The packet exchange sequence follows a similar logic as in @ref cpus_buffer, + * but does not use a validity buffer. + * + * @startuml{packet_tracker_exchange.svg} "Example: packet exchange" width=10 + * participant Writer + * database Packet + * database Size + * participant Reader + * control "No Action" + * + * Writer -> Packet : put packet + * activate Packet + * + * Reader <-- Size : get packet size + * "No Action" <-- Reader : empty + * + * Packet -> Size : put size + * activate Size + * + * Reader <-- Size : get packet size + * Size <- Reader : pop size + * Reader --> Packet : fetch packet + * Packet -> Reader : pop packet + * @enduml + * + * + * ## Notes + * + * As with the @ref cpus_buffer, a better performing version can be made by + * implementing a circular buffer that holds information of the following data + * block in a custom header per entry. + * + * If these buffers need to be accessible from multiple readers/writers, + * locks must be implement to ensure atomicity. + * + */ + + +#include <compiler.h> +#include <errors.h> +#include <packet_tracker.h> + +#include <stdlib.h> + + + +/** + * @brief sets up circular buffers to track pus packets + * @param p_pkt a struct packet_tracker + * @param p_buffer_pkts a pointer to a memory pool that will hold the + * pus packets + * @param p_buffer_size a pointer to a memory pool that will hold the + * sizes of the pus packets + * @note the size buffer must be able to hold at least + * size(pkts_buf)/12 elements + */ + +void ptrack_init(struct packet_tracker *p_pkt, + uint8_t *p_buf_pkts, uint32_t pkts_elem, + uint16_t *p_buf_size, uint32_t size_elem) +{ + cbuf_init8(&(p_pkt->pus_pkts), p_buf_pkts, pkts_elem); + cbuf_init16(&(p_pkt->pus_size), p_buf_size, size_elem); +} + + +/** + * @brief resets the packet tracker circular buffers + * @param p_pkt a struct packet_tracker + */ + +void ptrack_reset(struct packet_tracker *p_pkt) +{ + cbuf_reset8(&(p_pkt->pus_pkts)); + cbuf_reset16(&(p_pkt->pus_size)); +} + + +/** + * @brief gets the src/dest id field of the next packet + * @param packet_buffer a buffer holding packet data + * + * @returns packet src id + * @note the packet_buffer must be of appropriate size, buffer and packet + * validity are not checked + */ + +inline uint8_t ptrack_get_next_pkt_src_id(uint8_t *packet_buffer) +{ + return packet_buffer[PUS_SRC_ID_OFFSET]; +} + + +/** + * @brief gets the size of the next pus data field in the buffer + * @param packet_buffer a buffer holding packet data + * + * @returs data field size + * @note the packet_buffer must be of appropriate size, buffer and packet + * validity are not checked + */ + +static uint16_t ptrack_get_pus_data_size(uint8_t *packet_buffer) +{ + uint16_t pkt_size_hi, pkt_size_lo, pkt_size; + + pkt_size_hi = (uint16_t) packet_buffer[PUS_LEN_HI_OFFSET]; + pkt_size_hi &= PUS_LEN_HI_MASK; + + pkt_size_lo = (uint16_t) packet_buffer[PUS_LEN_LO_OFFSET]; + pkt_size_lo <<= PUS_LEN_LO_LSHIFT; + + pkt_size = (pkt_size_hi | pkt_size_lo); + + if (pkt_size) + pkt_size = PTRACK_PUS_DATA_LENGTH_ADJUST(pkt_size); + + return pkt_size; +} + + +/** + * @brief gets the size of the next packet in the buffer + * @param packet_buffer a buffer holding packet data + * + * @returns total size of pus packet + * @note the packet_buffer must be of appropriate size, buffer and packet + * validity are not checked + */ + +uint16_t ptrack_get_pkt_size(uint8_t *packet_buffer) +{ + uint16_t pkt_len; + + pkt_len = ptrack_get_pus_data_size(packet_buffer); + pkt_len += PTRACK_PUS_TMTC_HEADER_BYTES; + + return pkt_len; +} + + +/** + * @brief adds single packet to the circular buffers + * @param p_pkt a struct packet_tracker + * @param packet_buffer a buffer holding packet data + * @param packet_buffer_size the size of data in packet_buffer in bytes + * + * @returns bytes extracted from the buffer or -1 on error + */ + +int32_t ptrack_add_single_pkt(struct packet_tracker *p_pkt, + uint8_t *packet_buffer, + uint32_t packet_buffer_size) +{ + uint16_t pkt_len; + uint32_t ret; + + if (p_pkt == NULL) { + errno = E_PTRACK_INVALID; + return -1; + } + + ret = cbuf_get_free8(&(p_pkt->pus_pkts)); + if (ret < packet_buffer_size) { + errno = E_PTRACK_PKT_SIZE_LIMIT; + return -1; + } + + pkt_len = ptrack_get_pkt_size(packet_buffer); + + ret = cbuf_write8(&(p_pkt->pus_pkts), packet_buffer, pkt_len); + if (ret != pkt_len) { + errno = E_PTRACK_PKT_WRITE; + return -1; + } + + ret = cbuf_write16(&(p_pkt->pus_size), &pkt_len, 1); + if (!ret) { + errno = E_PTRACK_SIZE_WRITE; + return -1; + } + + return pkt_len; +} + + +/** + * @brief adds multiple packets to the circular buffers + * @param p_pkt a struct packet_tracker + * @param packet_buffer a buffer holding packet data + * @param packet_buffer_size the size of data in packet_buffer in bytes + * + * @returns bytes extracted from the buffer or -1 on error + */ + +int32_t ptrack_add_multiple_pkts(struct packet_tracker *p_pkt, + uint8_t *packet_buffer, + uint32_t packet_buffer_size) +{ + uint16_t pkt_len; + uint32_t ret; + + int32_t i = 0; + + + if (p_pkt == NULL) { + errno = E_PTRACK_INVALID; + return -1; + } + + ret = cbuf_get_free8(&(p_pkt->pus_pkts)); + if (ret < packet_buffer_size) { + errno = E_PTRACK_PKT_SIZE_LIMIT; + return -1; + } + + do { + pkt_len = ptrack_get_pkt_size(packet_buffer); + + ret = cbuf_write8(&(p_pkt->pus_pkts), + &packet_buffer[i], pkt_len); + + if (ret != pkt_len) { + errno = E_PTRACK_PKT_WRITE; + return -1; + } + + ret = cbuf_write16(&(p_pkt->pus_size), &pkt_len, 1); + if (!ret) { + errno = E_PTRACK_SIZE_WRITE; + return -1; + } + + i += pkt_len; + + } while (i <= (int32_t) (packet_buffer_size - PUS_PKT_MIN_SIZE)); + + + return i; +} + + + + +/** + * @brief peek at the size of the next packet in the buffer + * @param p_buf a pointer to a struct packet_tracker + * @note if the buffer is empty or cannot be read, the function will + * always return 0 + */ + +inline uint16_t ptrack_peek_next_pkt_size(struct packet_tracker *p_pkt) +{ + uint16_t pkt_size; + + if (cbuf_peek16(&(p_pkt->pus_size), &pkt_size, 1)) + return pkt_size; + + return 0; +} + + +/** + * @brief get the size of the next packet in the buffer + * @param p_buf a pointer to a struct packet_tracker + * @returns size of next packet in buffer + * + * @note if the buffer is empty or cannot be read, the function will + * always return 0 + */ + +static inline uint16_t ptrack_get_next_pkt_size(struct packet_tracker *p_pkt) +{ + uint16_t pkt_size; + + if (cbuf_read16(&(p_pkt->pus_size), &pkt_size, 1)) + return pkt_size; + + return 0; +} + + +/** + * @brief get a packet from the buffer + * @param p_pkt a struct packet_tracker + * @param p_buf a buffer large enough to hold a packet + * @returns 0 (failure, check errno), or size of packet read + */ + +uint16_t ptrack_get_next_pkt(struct packet_tracker *p_pkt, uint8_t *p_buf) +{ + uint16_t pkt_size; + + + pkt_size = ptrack_get_next_pkt_size(p_pkt); + + if (!pkt_size) { + errno = E_PTRACK_NOPKT; + return 0; + } + + if (pkt_size != cbuf_read8(&(p_pkt->pus_pkts), p_buf, pkt_size)) { + errno = E_PTRACK_PKT_READ; + return 0; + } + + return pkt_size; +} + + +/** brief get number of packets in buffer + * @param p_pkt a struct packet_tracker + * @returns number of packets + */ + +uint32_t ptrack_get_packets_in_buffer(struct packet_tracker *p_pkt) +{ + return cbuf_get_used16(&(p_pkt->pus_size)); +} diff --git a/IBSW/lib/reset.c b/IBSW/lib/reset.c new file mode 100644 index 0000000000000000000000000000000000000000..c2f90bce9681c3032bd8e9b9cc77447d3407cd0e --- /dev/null +++ b/IBSW/lib/reset.c @@ -0,0 +1,35 @@ +/** + * @file reset.c + * @ingroup edac + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @date October, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include <io.h> + +#include <iwf_fpga.h> +#include <ibsw_interface.h> + +/** + * @brief generic high level reset trap handler + */ + +void reset(void) +{ + CrIbResetDPU(DBS_EXCHANGE_RESET_TYPE_EX); +} diff --git a/IBSW/lib/stacktrace.c b/IBSW/lib/stacktrace.c new file mode 100644 index 0000000000000000000000000000000000000000..40433f41e9f6ddaef00274f297c4bdf6baa419f2 --- /dev/null +++ b/IBSW/lib/stacktrace.c @@ -0,0 +1,84 @@ +/** + * @file stacktrace.c + * @ingroup stacktrace + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @author Linus Torvalds et al. + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @note The stack tracing was inspired by __save_stack_trace() in + * linux/asm/sparc/kernel/stacktrace.c. Not particular author was given + * in the file, hence the generic credit. + * + * + * @defgroup stacktrace Stack Tracing + * @brief performs a trace back of a stack + * + * @example demo_trace.c + */ + +#include <stdlib.h> + +#include <io.h> +#include <compiler.h> +#include <timing.h> +#include <asm/leon.h> +#include <stacktrace.h> + + +/** + * @brief validates the stack pointer address + * @note stacks on v8 must be 8-byte aligned + */ +static int stack_valid(uint32_t sp) +{ + if (sp & (8UL - 1) || !sp) + return 0; + + return 1; +} + + +/** + * @brief performs a stack trace + * + * @param trace a struct stack_trace + * @param sp a stack/frame pointer + * @param pc a program counter + * + * @note When being called from a trap, the pc in %o7 is NOT the return program + * counter of the trapped function, so a stack/frame pointer by itself + * is not enough to provide a proper trace, hence the pc argument + */ + +void save_stack_trace(struct stack_trace *trace, uint32_t sp, uint32_t pc) +{ + struct sparc_stackf *sf; + + if (!stack_valid(sp)) + return; + + /* flush reg windows to memory*/ + leon_reg_win_flush(); + + do { + if (!stack_valid(sp)) + break; + + trace->entries[trace->nr_entries++] = pc; + + sf = (struct sparc_stackf *) sp; + pc = sf->callers_pc; + sp = (uint32_t) sf->fp; + + } while (trace->nr_entries < trace->max_entries); +} diff --git a/IBSW/lib/sysctl.c b/IBSW/lib/sysctl.c new file mode 100644 index 0000000000000000000000000000000000000000..6c6630334b2cd51f3235bfbb9c62833cba589ef1 --- /dev/null +++ b/IBSW/lib/sysctl.c @@ -0,0 +1,779 @@ +/** + * @file sysctl.c + * @ingroup sysctl + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @author Linus Torvalds et al. + * @date January, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * Note: explicit references to linux source files are not always given + * + * + * @defgroup sysctl System Control and Statistics Interface + * + * @brief + * An interface for examining and dynamically changing of parameters + * exported by a driver or other software subsystem to "user space". + * + * This system statistics/configuration functionality is tailored/derived + * from how sysfs and kobjects work in Linux. For obvious reasons, access via a + * virtual file system is not possible. The file system tree which would usually + * hold the references to registered objects is not present, hence objects know + * about their parents AND their children. Sets can be part of another set. + * Settings and values can be accessed by specifying the path to the object + * and their name. rees are built from objects and sets. Objects have + * attributes that can be read and/or set. + * + * + * ## Overview + * + * A core necessity of any type of on-board software is the ability to generate + * housekeeping data to be sent to ground, in order to provide information about + * the prevailing run-time parameters of both hardware and software. + * While requirements of update rates and number of variables, especially + * regarding software, may vary greatly for different mission profiles, there + * are generally hundreds of these data that are available for selection to + * form a housekeeping telemetry message. Usually, these are not solely + * read-only variables, but may also be patched by an appropriate tele-command + * in order to induce a mode change or adjust parameters to modify the behaviour + * of the software. + * + * These variables may be stored in large, monolithic, globally accessible + * "data pools". Such simplistic structures may at first glance be the logical + * choice, suggesting ease of both use and implementation, but are however + * very susceptible to breakage, particularly in top-down designs, where the + * data type of the implemented variables is not uniform and interaction with + * the data structure is only intended to occur via opaque accessor functions. + * + * If adjustments are made during development, memory violations may occur + * during runtime, and those can result in erratic, unpredictable, opaque bugs + * that are very difficult to track down. Another objection to this type of + * design is its re-usability, as there may exist multiple points of adaption, + * especially in circumstances where a great number of internally used + * variables, which are elemental to a software module or function, are stored + * in an externally administered data structure. + * + * Highly modular, encapsulated software modules with an as minimalistic as + * possible external interface are very preferable for re-use. Ideally, for + * example, a SpaceWire driver would only provide an interface to send or + * receive packets and handle all configuration of the underlying hardware + * internally. This however poses a problem to a user that would, for + * example, configure a particular link speed or continuously monitor data + * transfer rates. + * For such purposes, an interaction point is needed that exposes certain + * internal attributes via a generic interface and acts as a conduit between + * operating system elements and user-space. There are essentially four + * fundamental requirements for such functionality. + * + * First, internal interfaces or variables must not be slower to use than when + * not exposed. Second, all exposed functionality is defined by the module and + * exported to the generic interface when initialised. Third, the exposed + * functionality must not result in unpredictable behaviour, i.e. the software + * module must be insensitive to sudden changes in states or variables, or care + * must be taken by the module designer, so that interactions are properly + * handled. In any case, this must never be a concern for the user. Finally, + * any access must be on the user's processing time, not on that of the module. + * + * Given that the interaction point has to be completely generic to accommodate + * any kind of mapping defined by a module without restrictions, it must + * consequently be very simple. This is most easily achieved by implementing a + * character-buffer based interface that interacts with a module via functions + * provided by the latter to the generic interface structure. The necessary + * parsing or value conversion of text buffers on the user side is obviously + * slow compared to raw variable access, but given the underlying + * assumption that this system control interface is to be accessed in the + * order of no more than a few hundreds or at most several thousands times per + * second, the overhead is effectively negligible. + * + * The concept is very similar to the sysfs and sysctl interfaces found in + * Linux and BSD operating systems, with the former being file-system driven, + * while the latter is implemented as a system call. Since a file-system in the + * classic sense is not typically used for on-board software, this + * implementation can be seen as a hybrid of the two, which represents nodes in + * the configuration in the same fashion as a virtual file system tree, while + * all access is performed via a call interface. + * + * + * ## Mode of Operation + * + * + * __sysobjects__ are objects of type _struct sysobj_. They have a name and + * contain reference pointers to parent and child objects and the set of + * sysobjects they belong to, which allows them to be arrangend in hierarchical + * structures. They have no functionality on their own, instead, they are used + * to embed functionality as part of another software component. + * + * __syssets__ are the basic containers for collections of sysobjects and + * contain their own sysobject. A sysobject can have any parent, but if the + * parent of a sysobject is not specified when it is added to a sysset, the + * latter automatically becomes the parent of the set, but it does not become + * the child of the set. + * + * __attributes__ define the name and functional I/O of a sysobject. + * + * + * + * ### Usage example + * To create a system object for exporting items, a software module must define + * at least one attribute structure that configures the name and the appropriate + * _show_ and _store_ methods of that attribute. The following example is + * modeled on a subsystem that configures the state of an LED between _on_, + * _off_ and _flash_. + * + * First, the states of the LED are defined. This is the configuration variable + * that sets the operational mode of the "software module". By default, the LED + * will be in "flash" mode: + * + * @code {.c} + * enum modes {OFF, ON, FLASH}; + * static enum modes mode = FLASH; + * @endcode + * + * Next, _show()_ and _store()_ methods are defined. These allow the retrieval + * and the definition of the LED mode from user-space: + * + * @code {.c} + * static ssize_t mode_show(struct sysobj *sobj, struct sobj_attribute *sattr, + * char *buf) + * { + * switch(mode) { + * case OFF: return sprintf(buf, "off\n"); + * case ON: return sprintf(buf, "on\n"); + * case FLASH: return sprintf(buf, "flash\n"); + * default: return sprintf(buf, "Mode error\n"); + * } + * } + * + * static ssize_t mode_store(struct sysobj *sobj, struct sobj_attribute *sattr, + * const char *buf, size_t len) + * { + * if (!strncmp(buf, "on", len)) + * mode = ON; + * else if (!strncmp(buf, "off", len)) + * mode = OFF; + * else if (!strncmp(buf, "flash", len)) + * mode = FLASH; + * + * return len; + * } + * @endcode + * + * + * The mode and store functions are then combined into an attribute, that + * will, in this case, literally be called "mode": + * + * @code {.c} + * static struct sobj_attribute mode_attr = __ATTR(mode, mode_show, mode_store); + * @endcode + * + * The attribute is then added into a set of attributes that is terminated by + * NULL. A set can contain any number of attributes, in this case it is just + * one: + * + * @code {.c} + * static struct sobj_attribute *attributes[] = {&mode_attr, NULL}; + * @endcode + * + * A system object is created and the attribute set is associated to it: + * + * @code {.c} + * struct sysobj *sobj; + * + * sobj = sysobj_create(); + * sobj->sattr = mode_attr; + * @endcode + * + * The system object can now be attached as a node to a set of objects or + * logical tree, for example to a predefined "/sys/driver" branch under the + * name "myLEDmodule": + * + * @code {.c} + * sysobj_add(sobj, NULL, driver_set, "myLEDmodule"); + * @endcode + * + * The resulting tree can be shown by calling: + * + * @code {.c} + * sysset_show_tree(sys_set); + * @endcode + * + * resulting in the output: + * + @verbatim + + |__ sys + |__ driver + |__ myLEDmodule { mode } + + @endverbatim + * + * The flash mode can now be read by locating the node in the tree and querying + * "mode": + * + * @code {.c} + * sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/myLEDmodule"), "mode", buf); + * + * printf("led mode: %s\n", buf); + * @endcode + * + * resulting in the output: + * + @verbatim + mode: flash + @endverbatim + * + * + * The flash mode can be changed to value accepted by the _store()_ method: + * + * @code {.c} + * sysobj_store_attr(sysset_find_obj(sys_set, "/sys/driver/myLEDmodule"), "mode", "off", strlen("off")); + * + * sysobj_show_attr(sysset_find_obj(sys_set, "/sys/driver/myLEDmodule"), "mode", buf); + * + * printf("led mode: %s\n", buf); + * @endcode + * + * and the output now reads: + * + @verbatim + mode: off + @endverbatim + * + * + * + * + * There are no particular rules on how to use the sysctl tree, but it makes + * sense to put nodes into appropriate locations. + * For instance, a SpaceWire driver would register its attributes under a + * /sys/drivers tree, while an interrupt manager would register under + * /sys/irq, provided that these sets were already defined. + * + * Optionally, a new sub-set to hold the system objects of particular attributes + * may be created before attaching an object. If the SpaceWire driver was to + * manage multiple interfaces, it could create a logical sub-set + * /sys/drivers/spw and group interfaces SpW0, SpW1, etc. under that set. + * + * Since there are no formal restrictions on what qualifies to this system + * configuration tree, application software running on top of the operating + * system can (and should) make use of it as well. The aforementioned + * housekeeping data generation makes a good example for an application that + * both uses the the data provided by the registered software modules to + * generate housekeeping packets and is itself configured via this interface, + * e.g. its polling rate and the definition of housekeeping data to collect. + * + * + * ## Error Handling + * + * None + * + * ## Notes + * + * - To accelerate lookup of a node, a hash table should be added, where every + * entry is registered. This avoids searching the tree every time. + * - Ideally, a pointer reference to a particular node would be held when + * planning to to repetitive queries on the node. This needs reference + * counters so a node is "in use" and cannot be de-registered while a + * reference is held. This mandates "grab" and "release" functions to be + * called by by a user, which pass a such a reference instead of the raw + * pointer. + * - When reference counters are added, the sysobjects require a release method + * so their creating code can be asynchronously notified (see linux kobjects + * for similar logic). + * - At the moment, this is not supposed to be used from mutliple threads or + * any other possibly reentrant way. To allow this, modifications need to be + * made to at least include reference counts, atomic locking and a strtok_r + * function. + * - Objects and sets are not intended to be freed, this is not implemented due + * to the lack of available MMU support + * - At some point, an extension to binary i/o attributes may be sensible, e.g. + * for injection or retrieval of binary calibration data into a module or + * subsystem. + * + * + * @example demo_sysctl.c + * + */ + + +#include <stdio.h> + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <errno.h> + +#include <list.h> + +#include <sysctl.h> + + +struct sysset *sys_set; +struct sysset *driver_set; + + + + +static struct sysset *sysset_get(struct sysset *s); + + +/** + * @brief get the name of a sysobject + * @param sobj a reference to a sysobject + * @return a reference to the name buffer of the sysobject + */ + +const char *sysobj_name(const struct sysobj *sobj) +{ + return sobj->name; +} + + +/** + * @brief join a sysobject to its sysset + * @param sobj a reference to a sysobject + */ + +static void sobj_sysset_join(struct sysobj *sobj) +{ + if (!sobj->sysset) + return; + + sysset_get(sobj->sysset); + + list_add_tail(&sobj->entry, &sobj->sysset->list); +} + + +/** + * @brief get the reference to a sysobject + * @param sobj a reference to a sysobject + */ + +static struct sysobj *sysobj_get(struct sysobj *sobj) +{ + return sobj; +} + + +/** + * @brief set the name of a sysobject + * @param sobj a reference to a sysobject + * @param name the name buffer reference to assign + */ + +static void sysobj_set_name(struct sysobj *sobj, const char *name) +{ + sobj->name = name; +} + + +/** + * @brief initialise a sysobject's lists head + * @param sobj a reference to a sysobject + */ + +static void sysobj_init_internal(struct sysobj *sobj) +{ + if (!sobj) + return; + + INIT_LIST_HEAD(&sobj->entry); +} + + +/** + * @brief initialise a sysobject + * @param sobj a reference to a sysobject + */ + +void sysobj_init(struct sysobj *sobj) +{ + if (!sobj) + return; /* invalid pointer */ + + bzero(sobj, sizeof(struct sysobj)); + sysobj_init_internal(sobj); +} + + +/** + * @brief create a sysobject + * @return a reference to the new sysobject or NULL on error + */ + +struct sysobj *sysobj_create(void) +{ + struct sysobj *sobj; + + + sobj = malloc(sizeof(*sobj)); + + if (!sobj) + return NULL; + + sysobj_init(sobj); + + return sobj; +} + + +/** + * @brief add a sysobject and optionally set its sysset as parent + * @param sobj a reference to the sysobject + * @return -1 on error, 0 otherwise + */ + +static int32_t sysobj_add_internal(struct sysobj *sobj) +{ + struct sysobj *parent; + + + if (!sobj) + return -1; + + parent = sysobj_get(sobj->parent); + + /* join sysset if set, use it as parent if we do not already have one */ + if (sobj->sysset) { + if (!parent) + parent = sysobj_get(&sobj->sysset->sobj); + sobj_sysset_join(sobj); + sobj->parent = parent; + } + + return 0; +} + + +/** + * @brief add a sysobject to a set and/or a parent + * @param sobj a reference to the sysobject + * @param parent a reference to the parent sysobject + * @param sysset a reference to the parent sysset + * @param name the name of the sysobj + * @return -1 on error, 0 otherwise + */ + +int32_t sysobj_add(struct sysobj *sobj, struct sysobj *parent, + struct sysset *sysset, const char *name) +{ + if (!sobj) + return -1; + + sobj->sysset = sysset; + + sysobj_set_name(sobj, name); + + sobj->parent = parent; + + sysobj_add_internal(sobj); + + return 0; +} + + +/** + * @brief create and add a sysobject to a parent + * @parm name the name of a sysobj + * @param parent an optional parent to the sysobject + * @return a reference to the newly created sysobject or NULL on error + */ + +struct sysobj *sysobj_create_and_add(const char *name, struct sysobj *parent) +{ + struct sysobj *sobj; + + + sobj = sysobj_create(); + + if (!sobj) + return NULL; + + sysobj_add(sobj, parent, NULL, name); + + return sobj; +} + + +/** + * @brief call the "show" attribute function of a sysobject + * @param sobj a struct sysobj + * @param name the name of the attribute + * @param buf a buffer to return parameters + */ + +void sysobj_show_attr(struct sysobj *sobj, const char *name, char *buf) +{ + struct sobj_attribute **sattr; + + + if (!name) + return; + + if (!sobj) + return; + + if (!sobj->sattr) + return; + + + sattr = sobj->sattr; + + while ((*sattr)) { + + if (!strcmp((*sattr)->name, name)) + (*sattr)->show(sobj, (*sattr), buf); + + sattr++; + continue; + + } +} + + +/** + * @brief call the "store" attribute function of a sysobject + * @param sobj a struct sysobj + * @param name the name of the attribute + * @param buf a buffer holding parameters + * @param len the lenght of the buffer + */ + +void sysobj_store_attr(struct sysobj *sobj, const char *name, + const char *buf, size_t len) +{ + struct sobj_attribute **sattr; + + if (!name) + return; + + if (!sobj) + return; + + if (!sobj->sattr) + return; + + + sattr = sobj->sattr; + + while ((*sattr)) { + + if (!strcmp((*sattr)->name, name)) + (*sattr)->store(sobj, (*sattr), buf, len); + + sattr++; + continue; + + } +} + + +/** + * @brief get the sysset container of a sysobject + * @param s a struct sysset + * @return reference to the sysset or NULL + */ + +__extension__ +static struct sysset *to_sysset(struct sysobj *sobj) +{ + return sobj ? container_of(sobj, struct sysset, sobj) : NULL; +} + + +/** + * @brief get the sysset container of a sysset's sysobject + * @param s a struct sysset + * @return reference to the sysset or NULL + */ + +static struct sysset *sysset_get(struct sysset *s) +{ + return s ? to_sysset(sysobj_get(&s->sobj)) : NULL; +} + + +/** + * @brief initialise a sysset + * @param s a struct sysset + */ + +static void sysset_init(struct sysset *s) +{ + sysobj_init_internal(&s->sobj); + INIT_LIST_HEAD(&s->list); +} + + +/** + * @brief register a sysset + * @param s a struct sysset + * @return -1 on error, 0 otherwise + */ + +static int32_t sysset_register(struct sysset *s) +{ + if (!s) + return -1; + + sysset_init(s); + + return sysobj_add_internal(&s->sobj); +} + + +/** + * @brief create a sysset + * @param name a string holding the name of the set + * @param parent_sobj a struct sysobj or NULL if no sysobj parent + * @param parent_sysset a struct sysysset or NULL if no sysysset parent + * @return a reference to the new sysset + */ + +struct sysset *sysset_create(const char *name, + struct sysobj *parent_sobj, + struct sysset *parent_sysset) +{ + struct sysset *sysset; + + sysset = malloc(sizeof(*sysset)); + + if (!sysset) + return NULL; + + bzero(sysset, sizeof(*sysset)); + + + sysobj_set_name(&sysset->sobj, name); + + sysset->sobj.parent = parent_sobj; + sysset->sobj.child = &sysset->sobj; + + sysset->sobj.sysset = parent_sysset; + + return sysset; +} + + +/** + * @brief create and add a sysset + * @param name a string holding the name of the set + * @param parent_sobj a struct sysobj or NULL if no sysobj parent + * @param parent_sysset a struct sysysset or NULL if no sysysset parent + * @return a reference to the new sysset + */ + +struct sysset *sysset_create_and_add(const char *name, + struct sysobj *parent_sobj, + struct sysset *parent_sysset) +{ + struct sysset *sysset; + + + sysset = sysset_create(name, parent_sobj, parent_sysset); + + if (!sysset) + return NULL; + + sysset_register(sysset); + + return sysset; +} + + +/** + * @brief find the reference to an object in a sysset by its path + * @param sysset a struct sysset + * @param path a string describing a path + * @return a reference to the sysobj found + * + * @note this function is guaranteed to return, unless the machine's memory + * is either effectively a loop or infinite, but in this one instance. + * polyspace static analyzer appears fail here, the unit test clearly + * demonstrates that all sections of this function are reachable + * + * @note this function was modified to use a common exit point + */ + +__extension__ +struct sysobj *sysset_find_obj(struct sysset *sysset, const char *path) +{ + char str[256]; + char *token; + + struct sysobj *s; + struct sysobj *ret = NULL; + + + + memcpy(str, path, strlen(path) + 1); + + token = strtok(str, "/"); + + /* root node */ + if (strcmp(sysobj_name(&sysset->sobj), token)) + goto exit; + + while (1) { + + token = strtok(NULL, "/"); + + if (!token) + goto exit; + + list_for_each_entry(s, &sysset->list, entry) { + + if (!sysobj_name(s)) + goto exit; + + if (strcmp(sysobj_name(s), token)) + continue; + + if (!s->child) { + ret = s; + goto exit; + } + + sysset = container_of(s->child, struct sysset, sobj); + + break; + } + } + +exit: + return ret; +} + + +#if (__sparc__) +/** + * @brief initalises sysctl + * @note will not be covered by unit test + */ +int32_t sysctl_init(void) +{ + if (sys_set) + return -1; + + sys_set = sysset_create_and_add("sys", NULL, NULL); + + if (!sys_set) + return -1; + + driver_set = sysset_create_and_add("driver", NULL, sys_set); + + if (!driver_set) + return -1; + + return 0; +} +#endif diff --git a/IBSW/lib/timing/leon3_gptimer.c b/IBSW/lib/timing/leon3_gptimer.c new file mode 100644 index 0000000000000000000000000000000000000000..774ba4c9ab2343ecdc65a39e6cfbdb6fb82653ab --- /dev/null +++ b/IBSW/lib/timing/leon3_gptimer.c @@ -0,0 +1,363 @@ +/** + * @file leon3_gptimer.c + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements access to the LEON3 General Purpose Timer Unit + * @see GR712RC user manual chapter 11 + * + */ + + +#include <leon3_gptimer.h> +#include <leon3_timers.h> + + +/** + * @brief set scaler reload value of the timer block + * @param ptu a struct gptimer_unit + * + */ + +void gptimer_set_scaler_reload(struct gptimer_unit *ptu, uint32_t value) +{ + iowrite32be(value, &ptu->scaler_reload); +} + + +/** + * @brief get scaler reload value of the timer block + * @param ptu a struct gptimer_unit + * + */ + +uint32_t gptimer_get_scaler_reload(struct gptimer_unit *ptu) +{ + return ioread32be(&ptu->scaler_reload); +} + + +/** + * @brief sets the interrupt enabled flag of a timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_set_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&ptu->timer[timer].ctrl); + flags |= LEON3_TIMER_IE; + + iowrite32be(flags, &ptu->timer[timer].ctrl); +} + + +/** + * @brief sets the interrupt enabled flag of a timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_clear_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&ptu->timer[timer].ctrl); + flags &= ~LEON3_TIMER_IE; + + iowrite32be(flags, &ptu->timer[timer].ctrl); +} + + +/** + * @brief sets the load flag of a timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_set_load(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&ptu->timer[timer].ctrl); + flags |= LEON3_TIMER_LD; + + iowrite32be(flags, &ptu->timer[timer].ctrl); +} + + +/** + * @brief clears the load flag of a timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_clear_load(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&ptu->timer[timer].ctrl); + flags &= ~LEON3_TIMER_LD; + + iowrite32be(flags, &ptu->timer[timer].ctrl); +} + + +/** + * @brief set enable flag in timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ +void gptimer_set_enabled(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&ptu->timer[timer].ctrl); + ctrl |= LEON3_TIMER_EN; + + iowrite32be(ctrl, &ptu->timer[timer].ctrl); +} + + +/** + * @brief clear enable flag in timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_clear_enabled(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&ptu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_EN; + + iowrite32be(ctrl, &ptu->timer[timer].ctrl); +} + + +/** + * @brief set restart flag in timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ +void gptimer_set_restart(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&ptu->timer[timer].ctrl); + ctrl |= LEON3_TIMER_RS; + + iowrite32be(ctrl, &ptu->timer[timer].ctrl); +} + + +/** + * @brief clear restart flag in timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_clear_restart(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&ptu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_RS; + + iowrite32be(ctrl, &ptu->timer[timer].ctrl); +} + + +/** + * @brief set timer to chain to the preceeding timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_set_chained(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&ptu->timer[timer].ctrl); + ctrl |= LEON3_TIMER_CH; + + iowrite32be(ctrl, &ptu->timer[timer].ctrl); +} + + +/** + * @brief clear timer to chain to the preceeding timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_clear_chained(struct gptimer_unit *ptu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&ptu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_CH; + + iowrite32be(ctrl, &ptu->timer[timer].ctrl); +} + + +/** + * @brief get status of interrupt pending status + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +uint32_t gptimer_get_interrupt_pending_status(struct gptimer_unit *ptu, + uint32_t timer) +{ + return ioread32be(&ptu->timer[timer].ctrl) & LEON3_TIMER_IP; +} + + +/** + * @brief clear status of interrupt pending status + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +void gptimer_clear_interrupt_pending_status(struct gptimer_unit *ptu, + uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&ptu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_IP; + + iowrite32be(ctrl, &ptu->timer[timer].ctrl); +} + + +/** + * @brief get number of implemented general purpose timers + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +uint32_t gptimer_get_num_implemented(struct gptimer_unit *ptu) +{ + return ioread32be(&ptu->config) & LEON3_CFG_TIMERS_MASK; +} + + +/** + * @brief get interrupt ID of first implemented timer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + */ + +uint32_t gptimer_get_first_timer_irq_id(struct gptimer_unit *ptu) +{ + return (ioread32be(&ptu->config) & LEON3_CFG_IRQNUM_MASK) >> + LEON3_CFG_IRQNUM_SHIFT; +} + + +/** + * @brief set the value of a gptimer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + * @param value the timer counter value to set + */ + +void gptimer_set_value(struct gptimer_unit *ptu, uint32_t timer, uint32_t value) +{ + iowrite32be(value, &ptu->timer[timer].value); +} + +/** + * @brief get the value of a gptimer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + * @param value the timer counter value to set + */ + +uint32_t gptimer_get_value(struct gptimer_unit *ptu, uint32_t timer) +{ + return ioread32be(&ptu->timer[timer].value); +} + + +/** + * @brief set the reload of a gptimer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + * @param reload the timer counter reload to set + */ + +void gptimer_set_reload(struct gptimer_unit *ptu, + uint32_t timer, + uint32_t reload) +{ + iowrite32be(reload, &ptu->timer[timer].reload); +} + +/** + * @brief get the reload of a gptimer + * @param ptu a struct gptimer_unit + * @param timer the selected timer + * @param reload the timer counter reload to set + */ + +uint32_t gptimer_get_reload(struct gptimer_unit *ptu, uint32_t timer) +{ + return ioread32be(&ptu->timer[timer].reload); +} + + +/** + * @brief starts a gptimer; emits an irq but does not enable reload on underflow + * @param ptu a struct gptimer_unit + * @param timer the selected timer + * @param value the timer counter value to set + */ + +void gptimer_start(struct gptimer_unit *ptu, uint32_t timer, uint32_t value) +{ + gptimer_set_value(ptu, timer, value); + gptimer_set_reload(ptu, timer, value); + + gptimer_set_interrupt_enabled(ptu, timer); + gptimer_set_load(ptu, timer); + gptimer_set_enabled(ptu, timer); +} + + +/** + * @brief start a gptimer, emits an irq and enables reload on underflow + * @param ptu a struct gptimer_unit + * @param timer the selected timer + * @param value the timer counter value to set + */ + +void gptimer_start_cyclical(struct gptimer_unit *ptu, + uint32_t timer, uint32_t value) +{ + gptimer_set_value(ptu, timer, value); + gptimer_set_reload(ptu, timer, value); + + + gptimer_set_interrupt_enabled(ptu, timer); + gptimer_set_load(ptu, timer); + gptimer_set_restart(ptu, timer); + gptimer_set_enabled(ptu, timer); +} diff --git a/IBSW/lib/timing/leon3_grtimer.c b/IBSW/lib/timing/leon3_grtimer.c new file mode 100644 index 0000000000000000000000000000000000000000..e42d11d12433eed26e5f6ebc89d3542f4b4d6c9d --- /dev/null +++ b/IBSW/lib/timing/leon3_grtimer.c @@ -0,0 +1,390 @@ +/** + * @file leon3_grtimer.c + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + * @brief + * implements access to the LEON3 General Purpose Timer Unit with + * Time Latch Capability + * + * @see GR712RC user manual chapter 12 + * + */ + + +#include <leon3_grtimer.h> +#include <leon3_timers.h> + + + +/** + * @brief set scaler reload value of the timer block + * @param rtu a struct grtimer_unit + * + */ + +void grtimer_set_scaler_reload(struct grtimer_unit *rtu, uint32_t value) +{ + iowrite32be(value, &rtu->scaler_reload); +} + + +/** + * @brief get scaler reload value of the timer block + * @param rtu a struct grtimer_unit + * + */ + +uint32_t grtimer_get_scaler_reload(struct grtimer_unit *rtu) +{ + return ioread32be(&rtu->scaler_reload); +} + + +/** + * @brief sets the interrupt enabled flag of a timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_set_interrupt_enabled(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&rtu->timer[timer].ctrl); + flags |= LEON3_TIMER_IE; + + iowrite32be(flags, &rtu->timer[timer].ctrl); +} + + +/** + * @brief sets the interrupt enabled flag of a timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_clear_interrupt_enabled(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&rtu->timer[timer].ctrl); + flags &= ~LEON3_TIMER_IE; + + iowrite32be(flags, &rtu->timer[timer].ctrl); +} + + +/** + * @brief sets the load flag of a timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_set_load(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&rtu->timer[timer].ctrl); + flags |= LEON3_TIMER_LD; + + iowrite32be(flags, &rtu->timer[timer].ctrl); +} + + +/** + * @brief clears the load flag of a timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_clear_load(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t flags; + + flags = ioread32be(&rtu->timer[timer].ctrl); + flags &= ~LEON3_TIMER_LD; + + iowrite32be(flags, &rtu->timer[timer].ctrl); +} + + +/** + * @brief set enable flag in timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_set_enabled(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&rtu->timer[timer].ctrl); + ctrl |= LEON3_TIMER_EN; + + iowrite32be(ctrl, &rtu->timer[timer].ctrl); +} + + +/** + * @brief clear enable flag in timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_clear_enabled(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&rtu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_EN; + + iowrite32be(ctrl, &rtu->timer[timer].ctrl); +} + + +/** + * @brief set restart flag in timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_set_restart(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&rtu->timer[timer].ctrl); + ctrl |= LEON3_TIMER_RS; + + iowrite32be(ctrl, &rtu->timer[timer].ctrl); +} + + +/** + * @brief clear restart flag in timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_clear_restart(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&rtu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_RS; + + iowrite32be(ctrl, &rtu->timer[timer].ctrl); +} + + +/** + * @brief set timer to chain to the preceeding timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_set_chained(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&rtu->timer[timer].ctrl); + ctrl |= LEON3_TIMER_CH; + + iowrite32be(ctrl, &rtu->timer[timer].ctrl); +} + + +/** + * @brief clear timer to chain to the preceeding timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_clear_chained(struct grtimer_unit *rtu, uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&rtu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_CH; + + iowrite32be(ctrl, &rtu->timer[timer].ctrl); +} + + +/** + * @brief get status of interrupt pending status + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +uint32_t grtimer_get_interrupt_pending_status(struct grtimer_unit *rtu, + uint32_t timer) +{ + return ioread32be(&rtu->timer[timer].ctrl) & LEON3_TIMER_IP; +} + + +/** + * @brief clear status of interrupt pending status + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +void grtimer_clear_interrupt_pending_status(struct grtimer_unit *rtu, + uint32_t timer) +{ + uint32_t ctrl; + + ctrl = ioread32be(&rtu->timer[timer].ctrl); + ctrl &= ~LEON3_TIMER_IP; + + iowrite32be(ctrl, &rtu->timer[timer].ctrl); +} + + +/** + * @brief get number of implemented general purpose timers + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +uint32_t grtimer_get_num_implemented(struct grtimer_unit *rtu) +{ + return ioread32be(&rtu->config) & LEON3_CFG_TIMERS_MASK; +} + + +/** + * @brief get interrupt ID of first implemented timer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +uint32_t grtimer_get_first_timer_irq_id(struct grtimer_unit *rtu) +{ + return (ioread32be(&rtu->config) & LEON3_CFG_IRQNUM_MASK) >> + LEON3_CFG_IRQNUM_SHIFT; +} + + +/** + * @brief set the value of a grtimer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + * @param value the timer counter value to set + */ + +void grtimer_set_value(struct grtimer_unit *rtu, uint32_t timer, uint32_t value) +{ + iowrite32be(value, &rtu->timer[timer].value); +} + +/** + * @brief get the value of a grtimer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + * @param value the timer counter value to set + */ + +uint32_t grtimer_get_value(struct grtimer_unit *rtu, uint32_t timer) +{ + return ioread32be(&rtu->timer[timer].value); +} + + +/** + * @brief set the reload of a grtimer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + * @param reload the timer counter reload to set + */ + +void grtimer_set_reload(struct grtimer_unit *rtu, + uint32_t timer, + uint32_t reload) +{ + iowrite32be(reload, &rtu->timer[timer].reload); +} + +/** + * @brief get the reload of a grtimer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +uint32_t grtimer_get_reload(struct grtimer_unit *rtu, uint32_t timer) +{ + return ioread32be(&rtu->timer[timer].reload); +} + +/** + * @brief set an irq to trigger a latch + * @param rtu a struct grtimer_unit + * @param irq the irq number to latch on + */ + +void grtimer_set_latch_irq(struct grtimer_unit *rtu, uint32_t irq) +{ + uint32_t irq_select; + + irq_select = ioread32be(&rtu->irq_select); + irq_select |= (1 << irq); + + iowrite32be(irq_select, &rtu->irq_select); +} + + +/** + * @brief clear an irq triggering a latch + * @param rtu a struct grtimer_unit + * @param irq the irq number to disable latching for + */ + +void grtimer_clear_latch_irq(struct grtimer_unit *rtu, uint32_t irq) +{ + uint32_t irq_select; + + irq_select = ioread32be(&rtu->irq_select); + irq_select &= ~(1 << irq); + + iowrite32be(irq_select, &rtu->irq_select); +} + + +/** + * @brief set the timer's latch bit + * @param rtu a struct grtimer_unit + */ + +void grtimer_enable_latch(struct grtimer_unit *rtu) +{ + uint32_t config; + + config = ioread32be(&rtu->config); + config |= LEON3_GRTIMER_CFG_LATCH; + + iowrite32be(config, &rtu->config); +} + +/** + * @brief get the latch value of a grtimer + * @param rtu a struct grtimer_unit + * @param timer the selected timer + */ + +uint32_t grtimer_get_latch_value(struct grtimer_unit *rtu, uint32_t timer) +{ + return ioread32be(&rtu->timer[timer].latch_value); +} diff --git a/IBSW/lib/timing/leon3_grtimer_longcount.c b/IBSW/lib/timing/leon3_grtimer_longcount.c new file mode 100644 index 0000000000000000000000000000000000000000..95769815ed42ad3ba91eb018b58235ff25299cfc --- /dev/null +++ b/IBSW/lib/timing/leon3_grtimer_longcount.c @@ -0,0 +1,203 @@ +/** + * @file leon3_grtimer_longcount.c + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements a long-counting (uptime) clock using the LEON3 GRTIMER + * + */ + + +#include <timing.h> +#include <leon3_grtimer.h> + +#include <leon/irq.h> +#include <leon/irq_dispatch.h> +#include <sysctl.h> + + + + +/** + * @brief enable long count timer + * @param rtu a struct grtimer_unit + * @param reload a scaler reload value + * @param fine_ticks_per_sec a timer reload value in ticks per second + * @param coarse_ticks_max a timer reload value in ticks per second + * + * If properly configured, grtimer[0] will hold fractions of a second and + * grtimer[1] will be in seconds, counting down from coarse_ticks_max + * + * @return -1 if fine_ticks_per_sec is not an integer multiple of scaler_reload, + * 0 otherwise + * + * @note the return value warns about a configuration error, but will still + * accept the input + */ + + +int32_t grtimer_longcount_start(struct grtimer_unit *rtu, + uint32_t scaler_reload, + uint32_t fine_ticks_per_sec, + uint32_t coarse_ticks_max) +{ + grtimer_set_scaler_reload(rtu, scaler_reload); + grtimer_set_reload(rtu, 0, fine_ticks_per_sec); + grtimer_set_reload(rtu, 1, coarse_ticks_max); + + grtimer_set_load(rtu, 0); + grtimer_set_load(rtu, 1); + + grtimer_set_restart(rtu, 0); + grtimer_set_restart(rtu, 1); + + grtimer_set_chained(rtu, 1); + + grtimer_set_enabled(rtu, 0); + grtimer_set_enabled(rtu, 1); + + grtimer_enable_latch(rtu); + + /* not an integer multiple, clock will drift */ + if (fine_ticks_per_sec % scaler_reload) + return -1; + + return 0; +} + + +/** + * @brief get the time since the long counting grtimer was started + * @param rtu a struct grtimer_unit + * @param up a struct grtimer_uptime + * @note if configured properly, fine will be in cpu cycles and coarse will + * be in seconds + */ + +void grtimer_longcount_get_uptime(struct grtimer_unit *rtu, + struct grtimer_uptime *up) +{ + uint32_t sc; + uint32_t t0, t0a, t0b, t0c; + uint32_t t1, t1a, t1b, t1c; + uint32_t r0; + uint32_t r1; + + + sc = ioread32be(&rtu->scaler_reload); + + t0a = ioread32be(&rtu->timer[0].value); + t1a = ioread32be(&rtu->timer[1].value); + + t0b = ioread32be(&rtu->timer[0].value); + t1b = ioread32be(&rtu->timer[1].value); + + t0c = ioread32be(&rtu->timer[0].value); + t1c = ioread32be(&rtu->timer[1].value); + + if ((t0a >= t0b) && (t1a >= t1b)) + { + t0 = t0a; + t1 = t1a; + } + else + { + t0 = t0c; + t1 = t1c; + } + + r0 = ioread32be(&rtu->timer[0].reload); + r1 = ioread32be(&rtu->timer[1].reload); + + up->fine = (r0 - t0) * (sc + 1); + up->coarse = (r1 - t1); +} + + +/** + * @brief + * get the number of seconds elapsed between timestamps taken from the + * longcount timer + * + * @brief param time1 a struct grtime_uptime + * @brief param time0 a struct grtime_uptime + * + * @return time difference in seconds represented as double + */ + +double grtimer_longcount_difftime(struct grtimer_unit *rtu, + struct grtimer_uptime time1, + struct grtimer_uptime time0) +{ + uint32_t sc; + uint32_t rl; + double cpu_freq; + + double t0; + double t1; + + + sc = grtimer_get_scaler_reload(rtu); + rl = grtimer_get_reload(rtu, 0); + + cpu_freq = (double) (sc + 1) * rl; + + t0 = (double) time0.coarse + (double) time0.fine / cpu_freq; + t1 = (double) time1.coarse + (double) time1.fine / cpu_freq; + + return t1 - t0; +} + + + + +/** + * @brief get the time since last latch occured in cpu cycles + * @param rtu a struct grtimer_unit + * @note does not compensate for function overhead + */ + +uint32_t grtimer_longcount_get_latch_time_diff(struct grtimer_unit *rtu) +{ + uint32_t t0; + uint32_t t1; + + uint32_t t0_latch; + uint32_t t1_latch; + + uint32_t t0_reload; + uint32_t t0_scaler; + + uint32_t diff; + + + + t0_latch = grtimer_get_latch_value(rtu, 0); + t1_latch = grtimer_get_latch_value(rtu, 1); + t0_reload = grtimer_get_reload(rtu, 0); + t0_scaler = grtimer_get_scaler_reload(rtu); + + t0 = grtimer_get_value(rtu, 0); + t1 = grtimer_get_value(rtu, 1); + + diff = (t1_latch - t1) * t0_reload * (t0_scaler + 1); + + if (t0 < t0_latch) + diff += (t0_latch - t0); + else + diff += (t0_reload - t0); + + + return diff; +} diff --git a/IBSW/lib/timing/syncpulse.c b/IBSW/lib/timing/syncpulse.c new file mode 100644 index 0000000000000000000000000000000000000000..0b3549f5d7315bff73cd272bf3003c4cb3da95ed --- /dev/null +++ b/IBSW/lib/timing/syncpulse.c @@ -0,0 +1,248 @@ +/** + * @file syncpulse.c + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements 1553/SpW synchronisation and IASW notifications + */ + + +#include <timing.h> +#include <syncpulse.h> +#include <leon3_gptimer.h> +#include <event_report.h> + +/** + * @brief send a tick-in signal on a SpW link + * + * @param timekeeper a struct time_keeper + */ + +static void syncpulse_spw_tick(struct time_keeper *time) +{ + if (time->tick_in) { + if (time->spw) + grspw2_tick_in(time->spw); + /* Mantis 2073: we don't disable the tick, but keep it alive */ + /* syncpulse_disable_spw_tick(time); */ + } +} + + +/** + * @brief configure the syncpulse gpio port + * @brief port the i/o port to configure + * @brief gpio_base_addr the address of the gpio base register + */ + +void syncpulse_configure_gpio(uint32_t port, uint32_t gpio_base_addr) +{ + uint32_t flag; + + struct leon3_grgpio_registermap *gpio; + + + gpio = (struct leon3_grgpio_registermap *) gpio_base_addr; + + flag = (1 << port); + + /* disable output on pin 6 */ + gpio->ioport_direction &= ~flag; + + gpio->irq_mask |= flag; + gpio->irq_polarity |= flag; + gpio->irq_edge |= flag; +} + + +/** + * @brief sync pulse callback that needs to be attached to the corresponding + * interrupt; since we cannot receive the sync pulse with the GR712RC + * board, we attach it to the sync with dataword event of the 1553 driver + * for the time being + * @param userdata a pointer to arbitrary data (target must be a + * struct time_keeper) + * @note the API of this function varies depending on whether the sync pulse + * is available on the target device or if it is emulated via + * minor frame 0 of the 1553 bus + */ + + +int32_t syncpulse(void *userdata) +{ + struct time_keeper *time = (struct time_keeper *) userdata; + { + /* restart IASW notification cycle */ + gptimer_start(time->ptu, 2, T_CYC1); + + /* synchronise missing pulse timer to current syncpulse */ + gptimer_start(time->ptu, 1, GPTIMER_TICKS_PER_SEC + T_SYNC_TOL); + time->pulse_missed = 0; + + if (likely(time->cuc_recv)) { + timekeeper_set_cuc_time(time); + + if (unlikely(!time->synced)) { + as250_synchronized(time->brm); + time->synced = 1; + time->sync_status(time->synced); + } + + } else { + as250_desynchronized(time->brm); + time->synced = 0; + time->sync_status(time->synced); + time->miltime_desync_cnt++; + event_report(SYNC, MEDIUM, 0); + + } + + syncpulse_spw_tick(time); + + time->notify_cnt = 0; + time->cuc_recv = 0; + } + + return 0; +} + + +int32_t syncpulse_missed(void *userdata) +{ + struct time_keeper *time = (struct time_keeper *) userdata; + + + /* restart IASW notification cycle */ + gptimer_start(time->ptu, 2, T_CYC1 - T_SYNC_TOL); + + /* reconfigure timer to do one-second ticks */ + if (unlikely(!time->pulse_missed)) { + gptimer_start_cyclical(time->ptu, 1, GPTIMER_TICKS_PER_SEC); + as250_desynchronized(time->brm); + time->synced = 0; + time->sync_status(time->synced); + event_report(SYNC, MEDIUM, 0); + } + + time->pulse_missed = 1; + + /* set time for when pulse should have arrived */ + if (likely(time->cuc_recv)) + timekeeper_set_cuc_time(time); + else /* not even time arrived */ + time->miltime_desync_cnt++; + + time->pulse_desync_cnt++; + + /* keep ticking on sync loss */ + syncpulse_spw_tick(time); + + time->notify_cnt = 0; + time->cuc_recv = 0; + + return 0; +} + + + +/** + * @brief set a callback to propagate the time synchronisation status + * @param time a struct time_kepper + * @param sync_status a function callback + */ + +void syncpulse_status_set_callback(struct time_keeper *time, + void (*sync_status)(uint32_t sync)) +{ + time->sync_status = sync_status; +} + + +/** + * @brief enable SpW tick_in + * @param time a struct time_kepper + */ + +void syncpulse_enable_spw_tick(struct time_keeper *time) +{ + time->tick_in = 1; +} + + +/** + * @brief disable SpW tick_in + * @param time a struct time_kepper + */ + +void syncpulse_disable_spw_tick(struct time_keeper *time) +{ + time->tick_in = 0; +} + + + +/** + * @brief get the time at the (supposed) next sync pulse which corresponds + * to the time of the next SpW tick in + * @param time a struct time_keeper + * @param[out] coarse_time a variable to write the coarse time to + * @param[out] fine_time a variable to write the fine time to + * + * @note the next syncpulse time is always the local cuc coarse time + 1 second + * since the actual *current* time within a 1 second period + * is dynamically calculated from the long count timer + * Once this function is called, the SpW tick_in will be emitted every + * sync pulse (or its emulation) until explicitly disabled. + * + */ + +void syncpulse_spw_get_next_time(struct time_keeper *time, + uint32_t *coarse_time, + uint32_t *fine_time) +{ + (*coarse_time) = time->cuc_coarse + 1; + (*fine_time) = time->cuc_fine; + + syncpulse_enable_spw_tick(time); +} + + + +/** + * @brief notification timer callback + * @param userdata a pointer to arbitrary data (target must be a + * struct time_keeper) + */ + +int32_t syncpulse_notification_timer_underflow(void *userdata) +{ + struct time_keeper *time = (struct time_keeper *) userdata; + + + /* emit notification and restart timer */ + if (likely(time->notify_cnt < IASW_CPS)) { + + if (time->signal) + time->signal(time->userdata); + + time->notify_cnt++; + + gptimer_start(time->ptu, 2, T_CYC); + } + + return 0; +} + + + diff --git a/IBSW/lib/timing/timing.c b/IBSW/lib/timing/timing.c new file mode 100644 index 0000000000000000000000000000000000000000..e0affa447025827597c757b9580d2ab6118d1f79 --- /dev/null +++ b/IBSW/lib/timing/timing.c @@ -0,0 +1,358 @@ +/** + * @file timing.c + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup timing Timing and Watchdog + * @brief implements functions for Timing, Watchdog, 1553 Sync Pulse and + * SpW tick-in + * + * + * + * ## Overview + * + * This module implements access to the hardware timers found in the GR712RC as + * well as time keeping and synchronisation with the OBC and the SEM + * + * ## Mode of Operation + * + * ### Uptime Clock + * + * The BEE hardware does not include a real-time clock, so a long counting + * uptime reference timer is implemented using the _General Purpose Timer with + * Latch Capability_ of the GR712RC. + * + * The timers are used in chained mode, so that an underflow in the first timer + * causes the second timer's value to be decremented (see figure below). + * The reload value of the first timer and the reload value of the prescaler are + * selected such that their product is equal to the frequency of the CPU. + * This causes the first timer to underflow with a one second period. Thereby + * decrementing the second timer, which counts down from its initial reload + * value in one second decrements. + * + * The resolution of the first timer is determined by the cpu clock frequency + * and the chosen prescaler reload value. The smallest allowed prescaler value + * of this particular timer subsystem is 3. Given a clock frequency of + * _25 MHz_, the smallest possible prescale division factor is _4_, with + * a timer reload value of _6250000_. The best achievable accuracy in the + * uptime is therefore no better than __6.25 µs__. + * + * + * @startuml {grtimer_longcount.svg} "Uptime clock" width=10 + * + * control "-1" as sc + * control "-1" as t0 + * control "-1" as t1 + * [prescaler reload] -down-> [prescaler value] + * [timer 0 reload] -down-> [timer 0 value] + * [timer 1 reload] -down-> [timer 1 value] + * [cpu cycle] -> [prescaler value] : tick + * [prescaler value] -down-> sc + * sc -up-> [prescaler value] + * [prescaler value] -> [timer 0 value] : tick + * [timer 0 value] -down-> t0 + * t0 -up-> [timer 0 value] + * [timer 0 value] -> [timer 1 value] : tick + * [timer 1 value] -down-> t1 + * t1 -up-> [timer 1 value] + * + * + * @enduml + * + * @see _GR712RC user manual v2.7 chapter 11_ for information on the timer unit + * + * + * ### Current Time + * + * The current system time is calculated from the last time update performed. + * The difference between the current uptime and the reference + * time stamp recorded during the sync pulse event (see below) is added to the + * corresponding CUC time stamp written by the OBC via the 1553 link and + * returned to the user. + * + * + * ### 1553 Time Update, Sync Pulse and SpaceWire tick-in + * + * The 1553 direct time message used to determine the system time is written by + * the bus controller in _minor frame number 10_. The time is recorded and + * updated following either an external synchronisation pulse event or the + * timer-based pulse-emulated in case of a defect. + * + * At the sync event, the new time message replaces the previous one and a + * reference timestamp is taken from the uptime clock. + * + * The sync pulse is expected to occur periodically a one second intervals. In + * order to detect missing pulses, a timer with a period of one second plus a + * tolerance value is reloaded on every pulse. If the timer underflows, it is + * reconfigured to auto-reset every second and execute the same actions that + * would otherwise be triggered by a pulse. + * + * The synchronisation tick-in signal to the SEM is chained to the sync pulse + * action and self-disables when executed. This is done so that one time message + * sent corresponds to one tick-in generated. + * + * + * @startuml {syncpulse.svg} "External syncpulse event" width=10 + * + * start + * :pulse; + * :start notification timer; + * :start pulse timeout; +* + * if (CUC received) then (yes) + * :set CUC time; + * else + * :set status unsynched; + * endif + * + * :execute SpW tick; + * + * :clear counters and flags; + * + * stop + * @enduml + * + * + * @startuml {syncpulse_missed.svg} "Missed syncpulse event" width=10 + * + * start + * :timeout; + * :start notification timer; + * + * if (not emulating) then (yes) + * :configure sync emulation; + * :set status unsynched; + * endif + * + * if (CUC received) then (yes) + :set CUC time; + * endif + * + * :execute SpW tick; + * + * :clear counters and flags; + * stop + * @enduml + * + * + * ### Cyclical Notification + * + * + * The cyclical notification timer must be started once per one second period by + * an external trigger (sync pulse or emulation) and then executes a + * notification and restarts itself until the given number of cycles have + * passed. + * + * @startuml {notification_timer.svg} "Notification timer" width=10 + * + * start + * if (notifications < max) then (yes) + * :execute callback; + * :update counter; + * :restart notification timer; + * endif + * stop + * @enduml + * + * @note + * The notification period is restarted if the external sync pulse is + * generated while the emulation is running, i.e. the next notification can + * occur any time between _T_CYC1_ and _T_CYC1+T_CYC_ with regard to the + * previous one. + * + * + * ## Error Handling + * + * Missing sync pulse detection and emulation is the only timer-related FDIR + * performed. + * + * The number of missed sync pulses are counted, but not reported. Missed time + * messages written by the 1553 bus are counted as well, but this is effectively + * dead code and only implemented to fulfill an external requirement, as this + * situation is only conceivable if the hardware-executed 1553 BC framing is + * intentionally reconfigured or not functional at all, i.e. the OBC is at + * least partially defective and communication with the BEE therefore most + * likely not possible. + * + * + * ## Notes + * + */ + + +#include <timing.h> +#include <leon3_gptimer.h> +#include <leon3_grtimer.h> +#include <leon3_grtimer_longcount.h> +#include <string.h> + +#include <leon/irq.h> +#include <leon/irq_dispatch.h> +#include <sysctl.h> + + + +/** + * @brief initialise the timer structure and configure timers + * @param time a struct time_kepper + * @param ptu a struct gptimer_unit + * @param rtu a struct grtimer_unit + * @param brm a struct brm_config + * @param spw a struct grspw2_core_cfg + */ + +void timekeeper_init(struct time_keeper *time, + struct gptimer_unit *ptu, + struct grtimer_unit *rtu, + struct brm_config *brm, + struct grspw2_core_cfg *spw) +{ + + bzero((void *) time, sizeof(struct time_keeper)); + + time->ptu = ptu; + time->rtu = rtu; + + time->brm = brm; + time->spw = spw; + + grtimer_longcount_start(time->rtu, GRTIMER_RELOAD, + GRTIMER_TICKS_PER_SEC, GRTIMER_MAX); + + gptimer_set_scaler_reload(time->ptu, GPTIMER_RELOAD); +} + + +/** + * @brief set the notification signal callback + * @param time a struct time_kepper + * @param signal a function callback + * @param userdata a pointer to arbitrary userdata + */ + +void timekeeper_set_signal_callback(struct time_keeper *time, + void (*signal)(void *userdata), + void *userdata) +{ + time->signal = signal; + time->userdata = userdata; +} + + +/** + * @brief callback for the 1553 time event + * @param coarse_time the coarse time to set + * @param fine_time the fine time to set + * @param userdata a pointer to arbitrary data (target must be a + * struct time_keeper) + */ + +void timekeeper_set_1553_time(uint32_t coarse_time, + uint32_t fine_time, + void *userdata) +{ + double res; + + struct time_keeper *time = (struct time_keeper *) userdata; + + + /* convert 24 bits of fine time to be in cpu cycles. + * we can't avoid using the FPU while in interrupt mode (but we only + * do it once per second), because even when shifting, we would lose + * at least bits of accuracy during an integer-only conversion + */ + + res = ((double) fine_time) / ((double) 0xffffff) * ((double) CPU_CPS); + + time->mil_cuc_coarse = coarse_time; + time->mil_cuc_fine = (uint32_t) res; + time->cuc_recv = 1; +} + + +/** + * @brief sets local time to cuc time, also updates last sync time stamp + * @param time a struct time_keeper + * + * @note TIMEKEEPER_CORRECT_FOR_LATCHTIME has been removed + */ + +void timekeeper_set_cuc_time(struct time_keeper *time) +{ + struct grtimer_uptime up; + + + grtimer_longcount_get_uptime(time->rtu, &up); + + time->synctime.coarse = up.coarse; + time->synctime.fine = up.fine; + + time->cuc_coarse = time->mil_cuc_coarse; + time->cuc_fine = time->mil_cuc_fine; +} + + +/** + * @brief get current time relative to last CUC packet sent by the 1553 BC + * @param time a struct time_keeper + * @param[out] coarse_time a variable to write the coarse time to + * @param[out] fine_time a variable to write the fine time to + * @note needs timer to be configured correctly so that the "coarse" timer is + * chained to the fine timer "fine" timer which underflows + * in a 1 second cycle + * @note There is a possible race condition: as @ref timekeeper_set_cuc_time + * is called from an ISR and @ref timekeeper_get_current_time can be + * called from any task, the coarse and fine time parts might not be + * from the same timestamp. However, @ref set_cuc_time is only used by + * the "syncpulse" and "syncpulse_missed". Both are called only when + * the IASW has finished with cycle 8 and before cycle 1. + * @ref timekeeper_get_current_time is either called by the + * @ref CrIbGetCurrentTime, or by the @ref CrIbCrIbResetDPU function. + * These two are never called during the time slot in question, + * therefore the need to guarantee the atomicity of the operation can + * be relaxed. + */ + +void timekeeper_get_current_time(struct time_keeper *time, + uint32_t *coarse_time, + uint32_t *fine_time) +{ + uint32_t sc; + uint32_t rl; + uint32_t coarse; + uint32_t fine; + + + struct grtimer_uptime up; + + sc = grtimer_get_scaler_reload(time->rtu); + rl = grtimer_get_reload(time->rtu, 0); + + grtimer_longcount_get_uptime(time->rtu, &up); + + coarse = time->cuc_coarse + (up.coarse - time->synctime.coarse); + + if (up.fine > time->synctime.fine) { + fine = up.fine - time->synctime.fine; + } else { + coarse--; /* diff in fine time > 1 second */ + fine = up.fine + ((sc + 1) * rl - time->synctime.fine); + } + + fine += time->cuc_fine; + + + (*coarse_time) = coarse; + (*fine_time) = fine; +} diff --git a/IBSW/lib/timing/watchdog.c b/IBSW/lib/timing/watchdog.c new file mode 100644 index 0000000000000000000000000000000000000000..4e1cd4a0c937d85f258c4e50eedbafd197bb3465 --- /dev/null +++ b/IBSW/lib/timing/watchdog.c @@ -0,0 +1,88 @@ +/** + * @file watchdog.c + * @ingroup timing + * @author Armin Luntzer (armin.luntzer@univie.ac.at), + * @date July, 2016 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @brief implements a watchdog using the LEON3 GPTIMER + */ + + +#include <leon/irq.h> +#include <leon/irq_dispatch.h> + +#include <watchdog.h> +#include <leon3_gptimer.h> + + + +/** + * @brief the watchdog irq is triggered + * @param userdata a pointer to arbitrary data (target must be a + * struct time_keeper) + */ + +static int32_t watchdog_bark(void *userdata) +{ + struct time_keeper *time; + + time = (struct time_keeper *) userdata; + + if (time->bark) + time->bark(); + + return 0; +} + + +/** + * @brief enable the watchdog timer + * @param time a struct time_keeper + * @param shutdown_callback a function to call when the watchdog barks + * + */ + +void watchdog_enable(struct time_keeper *time, void (*shutdown_callback)(void)) +{ + time->bark = shutdown_callback; + irl1_register_callback(GR712_IRL1_GPTIMER_3, PRIORITY_NOW, + &watchdog_bark, time); + gptimer_start(time->ptu, 3, T_WATCHDOG); + time->watchdog_enabled = 1; +} + + +/** + * @brief disable the watchdog timer + * @param time a struct time_keeper + */ + +void watchdog_disable(struct time_keeper *time) +{ + gptimer_clear_enabled(time->ptu, 3); + irl1_deregister_callback(GR712_IRL1_GPTIMER_3, &watchdog_bark, time); + time->bark = NULL; + time->watchdog_enabled = 0; +} + + +/** + * @brief feed the watchdog + * @param time a struct time_keeper + */ + +void watchdog_feed(struct time_keeper *time) +{ + gptimer_set_load(time->ptu, 3); +} + diff --git a/IBSW/lib/traps.c b/IBSW/lib/traps.c new file mode 100644 index 0000000000000000000000000000000000000000..12e64fd498461ccc71d6844bbeee80b9481c78e9 --- /dev/null +++ b/IBSW/lib/traps.c @@ -0,0 +1,120 @@ +/** + * @file traps.c + * @ingroup traps + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * @author Linus Torvalds et al. + * @date September, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup traps Trap Table access + * @brief Implements functionality to access or modify SPARC v8 MVT trap + * table entries + * + * + * + * ## Overview + * + * This module implements functionality to access or modify SPARC v8 MVT trap + * table entries. + * + * ## Mode of Operation + * + * None + * + * ## Error Handling + * + * None + * + * ## Notes + * + * - functionality will be added as needed + * + * + */ + +#include <stdint.h> + +#include <io.h> +#include <compiler.h> + + +/** + * @brief installs a trap handler that executes a long jump + * + * @param trap a trap entry number + * @param handler a function to call when the trap is triggerd + * + * @note I'm not sure why this must be nested in another function call. If it + * isn't, the trap entry seemingly does not update properly. It might have + * to do with the rotation of the register window or some caching + * mechanism I'm not aware of at this time. The writes to the table are + * uncached, so the data cache is likely not the issue, and flusing it + * won't do anything either. When not nested in a wrapper, it however + * appears to work as expected if a function that in turn calls a + * function is executed after the trap entry is written - but it does not + * if the same function is called after this one has returned. O.o + * + * Installs a custom handler into a specified trap table entry. Note that it is + * not possible to install just any function, since traps are disabled when the + * call is executed and any further trap (such as window over/underflow) will + * force the processor to jump to trap 0 (i.e. reset). See lib/asm/trace_trap.S + * for a working example. + * + * + */ + +static void trap_longjump_install(uint32_t trap, void (*handler)()) +{ + uint32_t *trap_base; + uint32_t tbr; + uint32_t h; + + + h = (unsigned int) handler; + + /* extract the trap table address from %tbr (skips lower bits 0-11) */ + __asm__ __volatile__("rd %%tbr, %0" : "=r" (tbr)); + + /* calculate offset to trap, each entry is 4 machine words long */ + trap_base = (uint32_t *)((tbr & ~0xfff) + (trap << 4)); + + /* set up the trap entry: + * 0x29000000 sethi %hi(handler), %l4 + * 0x81c52000 jmpl %l4 + %lo(handler), %g0 + * 0x01000000 rd %psr, %l0 + * 0x01000000 nop + */ + iowrite32be(((h >> 10) & 0x3fffff) | 0x29000000, trap_base + 0); + iowrite32be((h & 0x3ff) | 0x81c52000, trap_base + 1); + iowrite32be(0xa1480000, trap_base + 2); + iowrite32be(0x01000000, trap_base + 3); + + barrier(); +} + +/** + * @brief installs a custom trap handler + * + * @param trap a trap entry number + * @param handler a function to call when the trap is triggerd + * + * Installs a custom handler into a specified trap table entry. Note that it is + * not possible to install just any function, since traps are disabled when the + * call is executed and any further trap (such as window over/underflow) will + * force the processor to jump to trap 0 (i.e. reset). See lib/asm/trace_trap.S + * for a working example. + */ + +void trap_handler_install(uint32_t trap, void (*handler)()) +{ + trap_longjump_install(trap, handler); +} diff --git a/IBSW/lib/wrap_malloc.c b/IBSW/lib/wrap_malloc.c new file mode 100644 index 0000000000000000000000000000000000000000..5aec741c7b37afe9aa0951a860e948480b4a752c --- /dev/null +++ b/IBSW/lib/wrap_malloc.c @@ -0,0 +1,289 @@ +/** + * @file wrap_malloc.c + * @ingroup malloc_wrapper + * @author Armin Luntzer (armin.luntzer@univie.ac.at) + * Roland Ottensamer (roland.ottensamer@univie.ac.at) + * @date August, 2015 + * + * @copyright GPLv2 + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * @defgroup malloc_wrapper Basic memory management + * + * @brief wraps malloc() and does some internal memory management according to + * a predefined memory map + */ + +#include <stdio.h> +#include <string.h> + +#include <wrap_malloc.h> +#include <sysctl.h> + + +static uint32_t heap; +static uint32_t heap_end; +static uint32_t semevt; +static uint32_t semevt_end; +static uint32_t hkstore; +static uint32_t hkstore_end; +static uint32_t flash; +static uint32_t flash_end; +static uint32_t aux; +static uint32_t aux_end; +static uint32_t res; +static uint32_t res_end; +static uint32_t swap; +static uint32_t swap_end; +static uint32_t sdb; +static uint32_t sdb_end; + +#define UINT32_T_FORMAT "%lu" + + +static ssize_t malloc_show(__attribute__((unused)) struct sysobj *sobj, + __attribute__((unused)) struct sobj_attribute *sattr, + char *buf) +{ + if (!strcmp(sattr->name, "heap")) + return sprintf(buf, UINT32_T_FORMAT, (heap - SRAM1_HEAP_ADDR)); + + if (!strcmp(sattr->name, "semevt")) + return sprintf(buf, UINT32_T_FORMAT, (semevt - SRAM1_SEMEVTS_ADDR)); + + if (!strcmp(sattr->name, "hkstore")) + return sprintf(buf, UINT32_T_FORMAT, (hkstore - SRAM1_HKSTORE_ADDR)); + + if (!strcmp(sattr->name, "flash")) + return sprintf(buf, UINT32_T_FORMAT, (flash - SRAM1_FLASH_ADDR)); + + if (!strcmp(sattr->name, "aux")) + return sprintf(buf, UINT32_T_FORMAT, (aux - SRAM1_AUX_ADDR)); + + if (!strcmp(sattr->name, "res")) + return sprintf(buf, UINT32_T_FORMAT, (res - SRAM1_RES_ADDR)); + + if (!strcmp(sattr->name, "swap")) + return sprintf(buf, UINT32_T_FORMAT, (swap - SRAM1_SWAP_ADDR)); + + if (!strcmp(sattr->name, "sdb")) + return sprintf(buf, UINT32_T_FORMAT, (sdb - SRAM2_SDB_ADDR)); + + return 0; +} + + +__extension__ +static struct sobj_attribute malloc_attr[] = { + __ATTR(heap, malloc_show, NULL), __ATTR(semevt, malloc_show, NULL), + __ATTR(hkstore, malloc_show, NULL), __ATTR(flash, malloc_show, NULL), + __ATTR(aux, malloc_show, NULL), __ATTR(res, malloc_show, NULL), + __ATTR(swap, malloc_show, NULL), __ATTR(sdb, malloc_show, NULL), + }; + +__extension__ +static struct sobj_attribute *malloc_attributes[] = { + &malloc_attr[0], &malloc_attr[1], + &malloc_attr[2], &malloc_attr[3], + &malloc_attr[4], &malloc_attr[5], + &malloc_attr[6], &malloc_attr[7], + NULL}; + +/** + * @brief add memory object to syscfg tree + * + * @return -1 on error, 0 otherwise + * + * @note this has to be delayed, because malloc needs to be initialied + * before the syscfg tree can be initialised and populated + */ + +int32_t malloc_enable_syscfg(void) +{ + struct sysobj *sobj; + + + sobj = sysobj_create(); + + if (!sobj) + return -1; + + sobj->sattr = malloc_attributes; + + sysobj_add(sobj, NULL, sys_set, "mem"); + + return 0; +} + + +/** + * @brief memory allocator for different ram areas + * @param size the amount of bytes to allocate + * @param ram the id of the ram block to allocate space in + */ + +void *alloc(uint32_t size, enum ram_block ram) +{ + uint32_t end = 0; + + uint32_t *mem = NULL; + uint32_t tmp; + + +#if (__sparc__) + static uint32_t init; + + + if (!init) { + heap = SRAM1_HEAP_ADDR; + semevt = SRAM1_SEMEVTS_ADDR; + hkstore = SRAM1_HKSTORE_ADDR; + flash = SRAM1_FLASH_ADDR; + aux = SRAM1_AUX_ADDR; + res = SRAM1_RES_ADDR; + swap = SRAM1_SWAP_ADDR; + sdb = SRAM2_SDB_ADDR; + + heap_end = SRAM1_HEAP_ADDR + SRAM1_HEAP_SIZE; + semevt_end = SRAM1_SEMEVTS_ADDR + SRAM1_SEMEVTS_SIZE; + hkstore_end = SRAM1_HKSTORE_ADDR + SRAM1_HKSTORE_SIZE; + flash_end = SRAM1_FLASH_ADDR + SRAM1_FLASH_SIZE; + aux_end = SRAM1_AUX_ADDR + SRAM1_AUX_SIZE; + res_end = SRAM1_RES_ADDR + SRAM1_RES_SIZE; + swap_end = SRAM1_SWAP_ADDR + SRAM1_SWAP_SIZE; + sdb_end = SRAM2_SDB_ADDR + SRAM2_SDB_SIZE; + + init = 1; + } +#endif + + if (!size) + return 0; + + switch (ram) { + + case HEAP: + mem = &heap; + end = heap_end; + break; + case SEMEVTS: + mem = &semevt; + end = semevt_end; + break; + case HKSTORE: + mem = &hkstore; + end = hkstore_end; + break; + case FLASH: + mem = &flash; + end = flash_end; + break; + case AUX: + mem = &aux; + end = aux_end; + break; + case RES: + mem = &res; + end = res_end; + break; + case SWAP: + mem = &swap; + end = swap_end; + break; + case SDB: + mem = &sdb; + end = sdb_end; + break; + default: + return NULL; + } + + tmp = (*mem); + + /* align start address to MEM_ALIGN byte boundaries */ + tmp = (tmp + (MEM_ALIGN - 1)) & 0xFFFFFFF8; + + /* check if it fits inside buffer */ + if ((tmp + size) <= end) { + (*mem) = tmp + size; + + return (void *)tmp; /* return the (modified) start address */ + } + + return NULL; +} + + +/** + * @brief resets the pointer of a particular memory memory segment; use with + * care + * @param ram the id of the ram block to reset + * + */ + +void release(enum ram_block ram) +{ + switch (ram) { + case HEAP: + heap = SRAM1_HEAP_ADDR; + break; + case SEMEVTS: + semevt = SRAM1_SEMEVTS_ADDR; + break; + case HKSTORE: + hkstore = SRAM1_HKSTORE_ADDR; + break; + case FLASH: + flash = SRAM1_FLASH_ADDR; + break; + case AUX: + aux = SRAM1_AUX_ADDR; + break; + case RES: + res = SRAM1_RES_ADDR; + break; + case SWAP: + swap = SRAM1_SWAP_ADDR; + break; + case SDB: + sdb = SRAM2_SDB_ADDR; + break; + default: + break; + } +} + + +/** + * @brief link time wrapper for malloc() + * @param size the amount of bytes to allocate + * @note needs linker flags to override: -Wl,--wrap=malloc + */ +#if (__sparc__) +__attribute__((unused)) +void *__wrap_malloc(size_t size) +{ + return alloc((uint32_t) size, HEAP); +} +#endif + +#if (__sparc__) +/** + * @brief a link-time wrapper to detect calls to free() + */ + +__attribute__((unused)) +void __wrap_free(void __attribute__((unused)) *ptr) +{ +} +#endif + + + diff --git a/README.md b/README.md index 299febf2c9b8c9ba1ce47089d52104be8332ec40..c7b9dd92d03f9488572f4a420a027077d5450eb6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ -# CHEOPS +CHEOPS Instrument Application Software +====================================== +Developed by the University of Vienna, Department of Astrophysics +Version: 1.1 (ee8c36db) +Date: Sep 25, 2018 +License: MPL2 +Point of contact: Roland Ottensamer <roland.ottensamer@univie.ac.at> + +This is the minimal set of source files to build the PC and the LEON version. +In order to do so, use BCC 4.4.2 release 1.0.51 for the LEON and gcc for the PC: + +> cd FwProfile +> make +> cd .. +> cd CrIa +> make ifsw-dpu +> make ifsw-pc + +Notes: +- it may be necessary to create an empty build directory CrIa/build first. +- newer versions of gcc complain about a missing cast to double in AngleMethod.c + +Enjoy, +RO diff --git a/TargetAcquisition/src/AngleMethod.c b/TargetAcquisition/src/AngleMethod.c new file mode 100644 index 0000000000000000000000000000000000000000..c81b5f7d3c3102c0c898e8fcf70ea849af7c9f72 --- /dev/null +++ b/TargetAcquisition/src/AngleMethod.c @@ -0,0 +1,3020 @@ +/** +* @file AngleMethod.c +* @author Philipp Löschl (roland.ottensamer@univie.ac.at) +* @date July, 2017 +* +* @defgroup AngleMethod Angle Method Algorithm +* @ingroup TargetAcquisition +* +* @brief The Angle Method algorithm is used to identify target stars with the help of star constellation pattern recognition and is part of @ref TargetAcquisition. +* +* +* +* # Introduction +* The Angle Method Algorithm (AMA) is a modified version of a technique that +* was originally suggested as a pattern recognition method for star tracker +* operation (REF LIEBE). It is independent of direct photometric measurements +* on stars and uses geometrical properties of the star distributions around +* the designated target star instead. +* More precisely, the angular distances between a potential target star and two of its +* neighbours are used in combination with the spherical angle at their vertex. +* This triplet if information is used to create a unique fingerprint, that can +* be matched with pre-calculated fingerprints in a reference star database. The +* latter is observation specific and has to be created for each target star. +* +* As one of two available identification methods, AMA is intended for +* acquisition procedures of non trivial identification cases where the +* target star cannot easily be distinguished from other field stars by the +* available photometric method. This will be the case for FOV with targets of +* 10 mag or fainter, where the chance for misidentification with another star of +* similar brightness is becoming a concern. (REF STAR STATISTICS). +* +* +* +* # Star Database +* The Angle Method Algorithm uses star positions to obtain the geometrical +* characteristics for an observation. While a dedicated @StarExtraction "Star Extraction" +* routine locates the star positions on each image, the GAIA star catalogue is used +* to provide a reference set of positions. These reference positions, along with +* other control parameters for the AMA are transmitted to the satellite with the +* Star Map Command (REF) for every single observation. The process to +* create unique identifiers from those star catalogues is described below. +* +* +* ## Fingerprint +* All positions in the provided star catalogues are grouped with the target to +* form star triplets, of which the relative distances between the target and the +* two other stars and their vertex angle are used. The distances and angle of such +* a triplet in their quantised form is what we call the __fingerprint__. +* \n\n +* Each fingerprint is made up from the combination of a __base star__ and two of +* their neighbouring stars, which will be referred to as __1st and 2nd partner +* stars__. While the partner stars can be any detectable star in the FOV, the +* star that is to be identified by the algorithm is always chosen as the base star. +* A collection of such fingerprints forms the star database. +* +* An example can be seen in Fig. +* +* @image html fingerprint.png "Fingerprint Example" width = 180px +* +* This shows a FOV with n=7 stars that are marked from A to G in order of their +* Y,X coordinates as would be the case after the Star Extraction process. here +* the target star (D) is in the center and marked as the base star (orange). +* Star B serves as the 1st partner star (orange) and star C as the 2nd partner +* star (blue). The used the distances between the base and the two partner +* stars B and D are measured in CCD pixel and the angle at the vertex of the +* base star (D) in degrees. They are marked as __edge 1__ (orange), __edge 2__ +* (blue) and angle __theta__ (red). Such a fingerprint will be described by the +* triplet ([DB], [DC], θ(DBC)), where [DB] marks the distance between stars +* B and C and θ(DBC) refers to the angle at the vertex D. The detailed +* quantisation process will be explained for the creation of the +* observed star database (REF). +* +* Note: Edge1 and edge2 are named base0 and base1 in the code as it predates +* a later change in nomenclature. This lack of creativity can be interpreted +* as another example of european astronomers' great naming capabilities. +* \n\n\n +* +* +* ## Reference Star Database +* Identification with a single fingerprint only is prone to errors and can lead +* to misidentificions. Therefore, all possible fingerprints are formed for the +* edge that is represented by the base star (D) and its current 1st partner star +* (B). This edge is also called the __base__ ([DB]) of a __set of fingerprints__. +* The set consists of all (n-2) fingerprints that can be formed by combinig the +* base with any available star as the 2nd partner. For the example in Fig (TBD) +* it contains the following five fingerprints: +* +*<table> +* <tr> <th> Set for base [DB]\n +* <tr> <td>([DB], [DA], θ(DBA)) \n +* <tr> <td>([DB], [DC], θ(DBC)) \n +* <tr> <td>([DB], [DE], θ(DBE)) \n +* <tr> <td>([DB], [DF], θ(DBF)) \n +* <tr> <td>([DB], [DG], θ(DBG)) \n +*</table> +* +* Although the full set of fingerprints prevents the risk of misidentificions +* due to single mismatched fingerprints, it does not address the problem of +* potentially missing stars in the star positions, that are used to produce the +* fingerprints. If the above set were provided to identify star D in an observation +* were star B is not present, none of the fingerprints would be detected. +* In order to conquer this problem the sets for fingerprints of the remaining +* possible bases are also included to collectively form the __reference star +* database__ (RFDB). Utilising all possible sets results in a total of +* (n-1)*(n-2) fingerprints as can be seen below: +* +* <table> +* <tr> <th> Set for base [DA] <th> Set for base [DB] <th> Set for base [DC] <th> Set for base [DE] <th> Set for base [DF] <th> Set for base [DG] \n +* <tr> <td> ([DA], [DB], θ(DAB)) <td> ([DB], [DA], θ(DBA)) <td> ([DC], [DA], θ(DCA)) <td> ([DE], [DA], θ(DEA)) <td> ([DF], [DA], θ(DFA)) <td> ([DG], [DA], θ(DGA))\n +* <tr> <td> ([DA], [DC], θ(DAC)) <td> ([DB], [DC], θ(DBC)) <td> ([DC], [DB], θ(DCB)) <td> ([DE], [DB], θ(DEB)) <td> ([DF], [DB], θ(DFB)) <td> ([DG], [DB], θ(DGB))\n +* <tr> <td> ([DA], [DE], θ(DAE)) <td> ([DB], [DE], θ(DBE)) <td> ([DC], [DE], θ(DCE)) <td> ([DE], [DC], θ(DEC)) <td> ([DF], [DC], θ(DFC)) <td> ([DG], [DC], θ(DGC))\n +* <tr> <td> ([DA], [DF], θ(DAF)) <td> ([DB], [DF], θ(DBF)) <td> ([DC], [DF], θ(DCF)) <td> ([DE], [DF], θ(DEF)) <td> ([DF], [DE], θ(DFE)) <td> ([DG], [DE], θ(DGE))\n +* <tr> <td> ([DA], [DG], θ(DAG)) <td> ([DB], [DG], θ(DBG)) <td> ([DC], [DG], θ(DCG)) <td> ([DE], [DG], θ(DEG)) <td> ([DF], [DG], θ(DFG)) <td> ([DG], [DF], θ(DGF))\n +* </table> +* (@ref create_ref_DB "Create Reference Star Database") +* \n +* \n +* ### Reference Stars +* The stars for a reference database are chosen such that the covered sky +* includes all possible orientations that could be observed by the spacecraft. +* The star positions are provided by the GAIA star catalogue and considered +* without error, since their positional uncertainty is magnitdues below the +* accuracy of the @StarExtraction "Star Extraction". (REF + NUMBERS) +* To guarantee that no additional and unexpected stars are detected, the +* @StarExtraction "Star Extraction" procedure parameters are set to reflect +* the composition of the reference star database. +* \n +* \n +* \n +* ## Observed Star Database +* The counterpart to the reference star database is the __observed star database__ +* (OSDB), which is created from the observed positions that are provided by +* the @StarExtraction "Star Extraction" process. While the basic principle +* of fingerprint creation is the same as described above, it comes with two +* major differences to the reference star database: +* <ol> +* <li> The target star position is not known and can only be restricted to +* a subregion that is defined by the expected spacecraft pointing +* uncertainty. Therefore, every star in that area has to be considered as +* base star </li> +* +* <li> Observed positions come with positional uncertainty that is high enough +* to affect a correct match of the inter-star distances (edges) and angles </li> +* +*</ol> +* +* This introduces two additional layers to the database structure. While +* the reference star database consists of 3 layers +* - Reference Star Database +* - Sets of Fingerprints +* - Fingerprints +* \n +* \n +* the observed star database structure has 5 +* - Observed Star Database +* - Sub Database for each Base Star +* - Sets of Fingerprints +* - Subsets of Fingerprints with Uncertainties +* - Fingerprints +* +* (@ref create_obs_DB "Create Observed Star Database") +* \n +* \n +* ### Base Star Selection +* The observed star database has to choose the same base star as the +* reference star database to achieve a positive matching result. Since the +* intended target star position on the image and the maximum pointing +* uncertainty of the spacecraft are known, this information can be utilised to +* to reduce the extracted star positions to a few potential target candidates. +* These candidates can then used as base stars to create sets of fingerprints +* from combinations with the other observed stars (not only the candidates). +* Each candidate forms a database from its respective set of fingerprints. +* These databases are considered to be the sub databases that make up the +* whole observed star database (see Fig (TBD)). +* (@ref find_target_candidates "Find Target Candidates") +* +* @image html obsDB_fingerprint.png "Fingerprint Example" width = 180px +* +* The intended __Target Location__ (yellow dot) is at the center of the +* __Candidate Area__ (yellow circle), which covers all possible placements of +* the target star. Its radius is limited by the maximum pointing uncertainty, +* and may differ between observations. All stars within, in this case D and E, +* might be the desired target star, so each of them is used as base star to +* create all possible sets of fingerprints through combinations with all of the +* other 6 stars. +*\n\n +* +*### Positional Uncertainties for Fingerprints +* The star positions provided by the @StarExtraction "Star Extraction" can +* sometimes be inaccurate to about 1.5 px (REF), which affects the +* calculation of the distances between the base star and its partner stars. +* This variation is the reason for the above mentioned quantisation +* of the edge lengths and the vertex angle. Therefore, a maximum separation error +* δr of ±3 px is assumed by default (customisable) and used for the quantisation +* process, that is described by the following example: +* \n\n +* Consider a maximum separation error between two stars δr as ±3 px. +* Therefore the separation of 238.93 px of the stars D and B will be detected as +* 238.93 ± 3 px. Since all measures in the database are stored as integers, it opens +* the range of 7 possible values [235, 241] for this edge alone. +* To account for the extreme compressed and stretched cases of 235 px and 241 px +* the quantisation is done with a factor of two δr: +* \n +* \n +* <center> +* edge length r = [DB] = 238.93 px, dr = 3 px\n +* (r - δr) / 2δr = 39.32 \n +* (r ) / 2δr = 39.82 \n +* (r + δr) / 2δr = 40.32 \n +* </center> +* \n +* This transforms the edge [DB] to \f$39.82 ± 0.5\f$ px and can be represented by the +* significantly smaller quantised interval of [39, 40]. +* \n +* \n +* The method comes with several advantages. While it the maximum number of values +* for a particular edge is reduced by a factor of __x = (1+2·δr)/2__, the +* database size with two edges per fingerprint is affected by __x²__. +* In addition it also detaches the theoretical upper limit for the database size +* from the position errors of a specfic star pair and therefore fixes the number +* of the quantised edge interval to two. +* \n +* \n +* Lastly angle can also be affected, which is especially the case when position +* errors of the two partner stars point to opposite directions in the line of +* their (unused) edge. Since this depends on the specific orientation of +* a star triplet, it can be highly variable within the set of fingerprints for +* a specific base. For this reason, there is no general maximum error that +* could be used for the quantisation as described for the edges. Instead, everything +* is quantised by an interval of 5 degrees, which is chosen as a trade off +* between angle accuracy and database size to also guarantee an +* allocation to a maximum of two different classes. +* (@ref calculate_dAng "Calculate Angle Uncertainty") +* \n +* \n +* Considering all uncertainties for both edges and the angle gives a maximum +* of up to __8 variations__ for a single fingerprint. Therefore, each fingerprint +* in the reference star database is described by a __subset of fingerprints__ +* with all possible variations in the observed star database. These variations +* are indicated by the subscripts 1 and 2 for the two possible quantised +* classes of each quantity. By convention single fingerprints are indicated by +* round brackets () and subsets of fingerprints by curly brackets {}. +* Such a set with the maximum number of fingerprints can be seen in Tab (TBD). +* <table> +* <tr> <th> __Subset {[DB], [DC], θ(DBC)}__ +* <tr> <td>([DB]_1, [DC]_1, θ(DBC)_1) +* <tr> <td>([DB]_1, [DC]_2, θ(DBC)_1) +* <tr> <td>([DB]_1, [DC]_1, θ(DBC)_2) +* <tr> <td>([DB]_1, [DC]_2, θ(DBC)_2) +* <tr> <td>([DB]_2, [DC]_1, θ(DBC)_1) +* <tr> <td>([DB]_2, [DC]_2, θ(DBC)_1) +* <tr> <td>([DB]_2, [DC]_1, θ(DBC)_2) +* <tr> <td>([DB]_2, [DC]_2, θ(DBC)_2) +* </table> +* \n +* ### Database Index +* The variable size of fingerprint set prevents the ability to navigate the +* database solely by the number of stars and the order of the total number of +* fingerprints given by (n-1)(n-2). This introduces the necessity +* of an index system that keeps track of the locations of every stored +* set of fingerprints. Therefore two indices that can be navigated by the relation +* abvoe are introduced. The __base index__ stores the first database index of +* each set of fingerprints and the __value index__ stores the quantised +* distance measure for both edges. Utilising both indices together enables faster +* search operations in the database during the matching process, which is described +* in the section Database Matching (REF). +* \n +* \n +* ### Database Size +* An a priori calculation of the exact database size is not possible due to the +* dependency on the variable number of angle classes per fingerprint set and the +* number of target candidates, which can also vary for different FOV orientations. +* +* With nc = number of target candidates and n = number of stars in the FOV the +* database size can be estimated by +* \n\n +* <center> +* max = nc * (n-1) * (n-2) * 8 +* \n\n +* min = nc * (n-1) * (n-2) * 4 +* </center> +* \n\n +* where nc is limited to 10 target candidates and 4/8 mark the minimal and +* maximal number of fingerprints per set. The full observed star database for +* the example case in Tab (TBD) and has a theoretical maximum of 480 fingerprints. +* \n\n +* +* <table> +* <caption id="multi_row">Observed Star Database</caption> +* <tr> <td colspan="6" align="center"> __Sub-Database for Base Star D__ +* <tr> <th> Set for base [DA] <th> Set for base [DB] <th> Set for base [DC] <th> Set for base [DE] <th> Set for base [DF] <th> Set for base [DG] \n +* <tr> <td> {[DA], [DB], θ(DAB)} <td> {[DB], [DA], θ(DBA)} <td> {[DC], [DA], θ(DCA)} <td> {[DE], [DA], θ(DEA)} <td> {[DF], [DA], θ(DFA)} <td> {[DG], [DA], θ(DGA)}\n +* <tr> <td> {[DA], [DC], θ(DAC)} <td> {[DB], [DC], θ(DBC)} <td> {[DC], [DB], θ(DCB)} <td> {[DE], [DB], θ(DEB)} <td> {[DF], [DB], θ(DFB)} <td> {[DG], [DB], θ(DGB)}\n +* <tr> <td> {[DA], [DE], θ(DAE)} <td> {[DB], [DE], θ(DBE)} <td> {[DC], [DE], θ(DCE)} <td> {[DE], [DC], θ(DEC)} <td> {[DF], [DC], θ(DFC)} <td> {[DG], [DC], θ(DGC)}\n +* <tr> <td> {[DA], [DF], θ(DAF)} <td> {[DB], [DF], θ(DBF)} <td> {[DC], [DF], θ(DCF)} <td> {[DE], [DF], θ(DEF)} <td> {[DF], [DE], θ(DFE)} <td> {[DG], [DE], θ(DGE)}\n +* <tr> <td> {[DA], [DG], θ(DAG)} <td> {[DB], [DG], θ(DBG)} <td> {[DC], [DG], θ(DCG)} <td> {[DE], [DG], θ(DEG)} <td> {[DF], [DG], θ(DFG)} <td> {[DG], [DF], θ(DGF)}\n +* +* <tr> <td colspan="6" align="center"> __Sub-Database for Base Star E__ +* <tr> <th> Set for base [EA] <th> Set for base [EB] <th> Set for base [EC] <th> Set for base [ED] <th> Set for base [EF] <th> Set for base [EG] \n +* <tr> <td> {[EA], [EB], θ(EAB)} <td> {[EB], [EA], θ(EBA)} <td> {[EC], [EA], θ(ECA)} <td> {[ED], [EA], θ(EDA)} <td> {[EF], [EA], θ(EFA)} <td> {[EG], [EA], θ(EGA)}\n +* <tr> <td> {[EA], [EC], θ(EAC)} <td> {[EB], [EC], θ(EBC)} <td> {[EC], [EB], θ(ECB)} <td> {[ED], [EB], θ(EDB)} <td> {[EF], [EB], θ(EFB)} <td> {[EG], [EB], θ(EGB)}\n +* <tr> <td> {[EA], [ED], θ(EAD)} <td> {[EB], [ED], θ(EBD)} <td> {[EC], [ED], θ(ECD)} <td> {[ED], [EC], θ(EDC)} <td> {[EF], [EC], θ(EFC)} <td> {[EG], [EC], θ(EGC)}\n +* <tr> <td> {[EA], [EF], θ(EAF)} <td> {[EB], [EF], θ(EBF)} <td> {[EC], [EF], θ(ECF)} <td> {[ED], [EF], θ(EDF)} <td> {[EF], [ED], θ(EFD)} <td> {[EG], [ED], θ(EGD)}\n +* <tr> <td> {[EA], [EG], θ(EAG)} <td> {[EB], [EG], θ(EBG)} <td> {[EC], [EG], θ(ECG)} <td> {[ED], [EG], θ(EDG)} <td> {[EF], [EG], θ(EFG)} <td> {[EG], [EF], θ(EGF)}\n +* </table> +* \n +* Each sub database is made from fingerprints of the different target candidates. +* The matching process for a solvable case will mostly identify fingerprints of +* one of the sub databases and identify its respective target candidate as the +* target star. +* \n +* \n +* \n +* # Matching Process +* With both databases in place the next and most important step for the +* target identification is matching process. Here every set of fingerprints +* in the observed star database will be assigned to a matching set of fingerprints +* of the reference star database. The process itself consists of the initial +* fingerprint matching, a subsequent elimination of ambiguous matching +* results and eventually a decision whether the target can be clearly identified +* or not. +* \n +* \n +* ## Database Matching +* For the matching process the algorithm iterates over every fingerprint in each +* set of fingerprints in the reference star database. To avoid repeated full +* scans of the observed star database each fingerprint is gradually matched with +* the value and base index. This index supported search drastically reduces the +* runtime of the matching process at the expense of some additional memory +* requirements for the search index. +* Let's assume a matching attempt for the reference fingerprint +* ([DA], [DB], θ(DAB)) with simulated databases for our sample observation:\n +* \n +* First the quantised value of the edge [DA] is being searched in the value index. +* In the above exmaple it can be found in the observed subdatabase with index 0 +* in the set for the base [DA] which also has index 0. These matching results +* are used to build a subset of the whole observed database, which reduces the +* potentially interesting part of the database from the full 480 to only 40 +* fingerprints. This sub sample is then used for the scan for the second edge [DB] +* which is again found at index 0 within the set of fingerprints for base [DA]. +* Utilising this to further reduce the potentially interesting database limits +* the search sample for the quantised angle to the maximum of 8 fingerprints for +* the subset with the edge combination [DA], [DB]. Eventually the reference +* fingerpint is found at index 2 of the subset in question.\n +* (@ref match_databases "Match Star Databases") +* \n +* \n +* The whole tracking record with all of the above mentioned indices is stored +* as (0, 0, 0, 2). This is done for each matched fingerprint and can be seen +* in Tab.: (TBD)\n +* \n +* <table> +* <tr> <td colspan="6" align="center"> __Match results for Fingerprint Sets with Base Star D__ +* <tr> <th> Base [DA] <th> Base [DB] <th> Base [DC] <th> Base [DE] <th> Base [DF] <th> Base [DG] \n +* <tr> <td> (0, 0, 0, 2) <td> (0, 1, 0, 1) <td> (0, 2, 0, 3) <td> (0, 3, 0, 7) <td> (0, 4, 0, 3) <td> (0, 5, 0, 1) \n +* <tr> <td> (0, 0, 1, 5) <td> (0, 1, 1, 0) <td> (0, 2, 1, 0) <td> (0, 3, 1, 2) <td> (0, 4, 1, 2) <td> (0, 5, 1, 0) \n +* <tr> <td> (0, 0, 2, 7) <td> (0, 1, 2, 1) <td> (0, 2, 2, 2) <td> (0, 2, 2, 2) <td> (0, 4, 2, 2) <td> (0, 5, 2, 0) \n +* <tr> <td> (0, 0, 3, 3) <td> (0, 1, 3, 1) <td> (0, 3, 2, 4) <td> (0, 3, 2, 4) <td> (0, 4, 3, 7) <td> (0, 5, 3, 2) \n +* <tr> <td> (0, 0, 4, 2) <td> (0, 1, 4, 0) <td> (0, 2, 3, 1) <td> (0, 3, 3, 7) <td> (0, 4, 4, 2) <td> (0, 5, 4, 1) \n +* <tr> <td> <td> <td> (0, 2, 4, 0) <td> (0, 3, 4, 4) <td> <td> \n +* </table> +* \n +* Since the reference and observed star databases were contructed from the same +* observation and hence the same order of stars, the indices in Tab (TBD) +* can easily be translated to a readable format. Therefore (0, 0, 0, 2) +* becomes (D, A, B, 2). This indicates that the reference fingerprint was matched +* with the observed fingerprint that is stored in the observed sub database for +* __base star D__, build its first edge with __partner star A__, its second +* edge with __parnter star B__ and was stored with the __subset index 2__. The +* translated match result is shown in Tab (TOOD REF). +* \n +* <table> +* <tr> <td colspan="6" align="center"> __Match results for Fingerprint Sets with Base Star D__ +* <tr> <th> Base [DA] <th> Base [DB] <th> Base [DC] <th> Base [DE] <th> Base [DF] <th> Base [DG] \n +* <tr> <td> (D, A, B, 2) <td> (D, B, A, 1) <td> (D, C, A, 3) <td> (D, E, A, 7) <td> (D, F, A, 3) <td> (D, G, A, 1) \n +* <tr> <td> (D, A, C, 5) <td> (D, B, C, 0) <td> (D, C, B, 0) <td> (D, E, B, 2) <td> (D, F, B, 2) <td> (D, G, B, 0) \n +* <tr> <td> (D, A, E, 7) <td> (D, B, E, 1) <td> (D, C, E, 2) <td> (D, C, E, 2) <td> (D, F, C, 2) <td> (D, G, C, 0) \n +* <tr> <td> (D, A, F, 3) <td> (D, B, F, 1) <td> (D, E, C, 4) <td> (D, E, C, 4) <td> (D, F, E, 7) <td> (D, G, E, 2) \n +* <tr> <td> (D, A, G, 2) <td> (D, B, G, 0) <td> (D, C, F, 1) <td> (D, E, F, 7) <td> (D, F, G, 2) <td> (D, G, F, 1) \n +* <tr> <td> <td> <td> (D, C, G, 0) <td> (D, E, G, 4) <td> <td> \n +* </table> +* \n +* The maximum number of matches per base for this case should be (n-2) = 5. +* While this is true for the majority of matched bases, base [DC] and [DE] +* contain an additional false positive match that is a result of the isosceles +* triangle of the stars D, C and E. Stars in such an orientation cannot be +* distinguished by the Angle Method Algorithm and will introduce false matches. +* For this reason the match results are corrected from ambiguous matches in a +* subsequent step. To ensure that enough matches are left after this correction, +* ideally five or more stars should be available in observations that use the +* Angle Method Algorithm for target identification. This increases the number of +* available fingerprints per base and therefore compensates for deleted matches +* in the rare cases with such orientations or accidental matching. +* \n +* \n +* ## Match Result Corrections +* ### Base Specific Correction +* The first correction step analyses the matched fingerprints for each base +* separately. All matched fingerprints have to be from the same obserserved base +* (base star and first partner star) to be considered valid. Therefore, the +* so called __star tracker__ compares the base star of all matched fingerprints, +* and discards fingerprints that don't fit with the majority of the matches. In +* addition it also stores the matched observed base star for each reference base. +* The same is done with the __base tracker__ for the partner star. The match record +* for reference base [DC] is an example for this. While the first partner star +* is C for five of the matches it is E for only one. Since the majority was matched +* to observed base [DC], the match for the base [DE] seems out of place and is +* considered wrong. The contrary is true for the match record of reference base +* [DE]. In both cases the wrong match is discarded and not considered for the +* quality of the match result. The preliminary number of valid matches for a +* reference base can then be determined by the count of fingerprints made from +* unique second partner stars. This number is stored for each reference base +* in the so called __match histogram__ and can be decreased by the subsequent +* correction steps. The match histogram for our example case can be seen below: +* (@ref find_majority_matches "Find Majority Matches") +* \n +* <table> +* <tr> <td colspan="7" align="center"> __Match Histogram__ +* <tr> <th> Reference Base <th> [DA] <th> [DB] <th> [DC] <th> [DE] <th> [DF] <th> [DG]\n +* <tr> <th> No. of Matches <td> 5 <td> 5 <td> 5 <td> 5 <td> 5 <td> 5 \n +* </table> +* It also represents the final match result since no further corrections are +* necessary for this constructed example case. Therefore a 100% of the +* fingerprints in the observed star database could be matched. Further +* evaluation of this result is discussed in +* Match Results Validation/Validation Metric (REF). Generally, observations +* might not match this well and are therefore treated with additional corrections +* steps as described in the following subsections. +* \n +* \n +* ### Cross Base Correction +* Although each observed base and its set of fingerprints should only match a +* specific reference base, some fingerprint variations might match with the wrong +* reference base as described above. While most of these matches are eliminated +* by the previous correction step it sometimes happens that a single observed base +* is assigned to multiple reference bases. This behaviour can be observed +* in very crowded fields with short inter-star distances, since they are prone +* to be mapped to similar quantised distance classes that can match within the +* observed fingerprint variations. The other case are reference bases of stars +* that were provided by the reference positions but aren't visible in the FOV +* of the observation. Such bases might accidentally match 1-2 fingerprint +* variations but are not corrected be the previous step due to the lack of real +* matches. +* \n +* The star and base tracker are used to identify observed bases that were matched +* to multiple reference bases. In such a case the reference base with more matched +* fingerprints is considered to be the valid match. The respective number of +* matched fingerprints can be retrieved from the match histogram. The process +* then discards all matches of the invalid base(s). In addition all fingerprints +* that were matched to both of the reference bases in question are considered +* to be ambiguous and are also discarded from the valid reference base. All +* changes are also reflected in the match histogram. +* \n +* Since this particular matching fail is rather rare and not present in the above +* example let's consider an hypothetical additional reference star H that is +* located such that it would produce the following match result situation: +* \n +* <table> +* <tr> <td colspan="6" align="center"> __Cross Base Validation for Base Star D__ +* <tr> <th> Base [DA] <th> Base [DH] \n +* <tr> <td> (D, A, B, 2) <td> (D, A, B, 1) \n +* <tr> <td> (D, A, C, 5) <td> (D, A, C, 3) \n +* <tr> <td> (D, A, E, 7) <td> \n +* <tr> <td> (D, A, F, 3) <td> \n +* <tr> <td> (D, A, G, 2) <td> \n +* </table> +* \n +* The algorithm would identify base [DA] and [DH] to be matched with fingerprints +* from the same observed base. Since there are more matches for [DA] base [DH] +* would be discarded as the invalid match. Even though the fingerprints +* ([DA],[DB], θ(DBA)) and ([DA],[DC], θ(DBC)) were matched for different variations +* they are still considered ambiguous and are therefore discarded. Hence, this +* operation would reduce the number of valid matches for base [DA] to three. +* (@ref correct_multiple_base_matches "Correct Multiple Base Matches") +* \n +* \n +* ### Base Star Correction +* After the previous correction steps across the reference base matches the +* matching base star can be determined. Since the majorily matching base star and +* first partner star were determined separately for each reference base it is +* possible that the different reference bases were matched to different base stars. +* As there can only be one valid base star, all matches with the less frequently +* matched base star are discarded from the match histogram. +* Similar to the correction step before this is a rather rare issue that's more +* often present in tighter packed star distributions and didn't occur in the +* above example. Therefore, consider the hypothetical alternative match result +* in Tab.: (TOOD REF) below: +* \n +* <table> +* <tr> <td colspan="6" align="center"> __Hypothetical Match Results for Fingerprint Sets with Base Star D__ +* <tr> <th> Base [DA] <th> Base [DB] <th> Base [DC] <th> Base [DE] <th> Base [DF] <th> Base [DG] \n +* <tr> <td> (E, A, B, 2) <td> (D, B, A, 1) <td> (D, C, A, 3) <td> (D, E, A, 7) <td> (D, F, A, 3) <td> (D, G, A, 1) \n +* <tr> <td> (E, A, C, 5) <td> (D, B, C, 0) <td> (D, C, B, 0) <td> (D, E, B, 2) <td> (D, F, B, 2) <td> (D, G, B, 0) \n +* <tr> <td> (E, A, D, 7) <td> (D, B, E, 1) <td> (D, C, E, 2) <td> (D, E, C, 4) <td> (D, F, C, 2) <td> (D, G, C, 0) \n +* <tr> <td> (E, A, F, 3) <td> (D, B, F, 1) <td> (D, C, F, 1) <td> (D, E, F, 7) <td> (D, F, E, 7) <td> (D, G, E, 2) \n +* <tr> <td> (E, A, G, 2) <td> (D, B, G, 0) <td> (D, C, G, 0) <td> (D, E, G, 4) <td> (D, F, G, 2) <td> (D, G, F, 1) \n +* </table> +* \n +* Here, only reference base [DA] would be matched with the base star E, while the +* remaining 5 reference bases clearly fit the fingerprints of star D. For this +* reason D is selected as the most likely target star and all matches with base +* star E are discarded from the match histogram. +* (@ref find_valid_star_candidate "Base Star Correction") +* \n +* \n +* ### Statistical Correction +* Even though the target star has been suggested at this point, a last step is +* taken to clean the match histogram from problematic matches and arrive at a +* more conservative result. Still existing accidental matches with unused reference +* bases (similar to the case in Cross Base Corrections REF) and the sparse +* leftovers of corrected bases with significantly less matches than the well +* matched references bases are being discarded in this step. This is done by +* calculation of the average number of matched fingerprints per reference base. +* Together with the respective standard deviation a minimum number of matches is +* defined by +* <center> minimum matches = average matches - 2 * standard deviation </center> +* \n +* All results from reference bases with less than the minimum amount of matched +* fingerprints are removed from the match histogram. This final step marks +* the completion of the match result correction. All remaining matches are +* considered to be valid and can be used to determine if the selected target +* candidate was matched well enough to be clearly identified as the target star. +* (@ref find_valid_star_candidate "Statistical Correction") +* \n +* \n +* ## Match Result Validation +* The selected target candidate cannot directly be considered as the identified +* target star for various reasons. Beside the obvious case where the actual +* target star is not present and a few accidental matches could trigger a +* misidentification, the specific way how the database matching process was +* implemented for cases with multiple target candidates is another one. Whenever +* a fingerprint can be identified within one of the observed subdatabases +* the search is not continued to check if it can also be found in the remaining +* subdatabases. This was done for two reasons. It is quite unlikely +* to encounter the same fingerprint in another subdatabase, due to the random +* nature of star distributions and the way the fingerprint geometry works. +* Therefore a continued search is mostly a waste of computational resources +* and overall reduced matching times to meet the stricter initial runtime +* requirements were more favourable. While it optimised the execution time and +* memory usage it can theoretically lead to an extreme match result like in +* Tab.: (REF) in very special cases. +* \n +* <table> +* <tr> <td colspan="6" align="center"> __Hypothetical Match Results for Fingerprint Sets with Base Star D__ +<tr> <th> Base [DA] <th> Base [DB] <th> Base [DC] <th> Base [DE] <th> Base [DF] <th> Base [DG] \n +* <tr> <td> (E, A, B, 2) <td> (D, B, A, 1) <td> (D, C, A, 3) <td> <td> <td> \n +* <tr> <td> (E, A, C, 5) <td> (D, B, C, 0) <td> (D, C, B, 0) <td> <td> <td> \n +* <tr> <td> (E, A, D, 7) <td> (D, B, E, 1) <td> (D, C, E, 2) <td> <td> <td> \n +* <tr> <td> (E, A, F, 3) <td> (E, B, F, 1) <td> (E, C, F, 1) <td> <td> <td> \n +* <tr> <td> (E, A, G, 2) <td> (E, B, G, 0) <td> (E, C, G, 0) <td> <td> <td> \n +* </table> +* \n +* The algorithm would decide that base star D is dominant in 2/3 matched reference +* bases and suggest base star D as the valid target candidate. Upon closer +* inspection one can see that star E actually has one more match than star D +* and generally less than half of the total possible matches was achieved. +* Considering that base star E can only be matched if there is no match with +* star D in the first subdatabase it could be that E would have matched all of +* the reference bases [DA], [DB], [DC]. Although this is some inherently problematic +* behaviour of the Angle Method Algorithm it hardly has any significance for +* real observational cases. A star distribution to trigger such a case would +* have glitch degraded star positions and has to be highly symmetric along an +* axis that separates the two target candidates. One could argue that every +* matched fingerprint might have matched another one in the next subdatabase, +* but star distributions that fulfill such a level of symmetry are so rare that +* the case is considered negligible. Similar to the isosceles case +* it would be just unsolvable and should be solved with with photometric means. +* \n +* To also avoid these rare cases and keep such poorly and maybe ambiguously +* matched orientations from triggering positive target identifications it was +* decided that the total number of matched fingerprints in the match histogram +* has to overcome a certain threshold. +* \n +* \n +* ### Validation Metric +* The main threshold that has to be met in order to fulfill the requirements for +* a positive identification is defined by the maximum possible number of fingerprints +* for the extracted positions in an observation. Out of the (n-1)(n-2) possible +* combinations (where n represents the number of detected stars) at least 50% +* must be matched for a candidate to be recognised as the target star. In order +* to match such large fractions of the observed star database it is required that +* every observed star also is also represented in the set of reference stars. +* For this reason the @StarExtraction "Star Extraction" is configured in +* dependency of the expected reference stars so that it always only finds less +* and brighter stars than are provided by the reference. +* \n +* \n +* The above 50% criteria is meant to guarantee that the algorithm selects the +* best possible target candidate as the valid match. While some reference +* fingerprints might be wrongly assigned to another candidate's database, the +* example presented in the section above is an exception that usually does not +* happen. This in turn means that the vast majority of fingerprints are unique +* to their subdatabase which makes it impossible for two competing target +* candidates to achieve results above 50% at the same time. Therefore such a +* result can be confidently viewed as the successfully identified target star. +* \n +* \n +* This requirement will easily be met for the majority of generally identifiable +* orientations. An exception are sparsely populated FOV with one or more +* interloping stars, that are not covered by the reference. In such cases +* additional stars have a larger effect on the match quality than in +* observations with plenty of stars. A more detailled description of their +* effects can be found in the next section (REF). While the match results +* of such observations can be degraded to the point where the validity criteria +* cannot be met, they are not necessarily wrong. To save such an otherwise +* perfectly fine result an alternative measure for the validity is used. +* For this, the maximum possible number of matched fingerprints is calculated +* from the number of matched reference bases +* \n +* <center> max_items = (n_matched_bases)(n_matched_bases-1)</center> +* \n +* which is not directly affected by interlopers but a less conservative measure. +* The amount of possible matched bases on the other hand still depends on the +* number of observed stars, which also includes the interlopers. To still be +* considered a valid identification currently 65% of the possible reference +* bases have to be matched with at least 65% of each of their fingerprints. This +* results in a total matching threshold of 42.25% of the observed database, +* which saves observations that only slightly failed the main criteria as +* described above. If this more forgiving threshold also cannot be met a final +* layer of reduced thresholds might save the identification. +* \n +* Even though the match result will be returned as failed at this point, the +* Angle Method can also be used in combination with the Magnitude Validation +* (REF). Insufficient match results can be saved with a subsequent +* photometric analysis of the target candidate's signal. Although the combination +* of the method is a potentially robust way for the identification problem, the +* photometric verification should not be used on exceptionally bad Angle Method +* results. As described in section (REF) the photometry is rather coarse. +* Since the Angle Method is meant for faint targets, the other target candidate +* might be within the signal uncertainty of the Magnitude Validation. For this +* reason, a photometric misidentification would verify a poor and potentially +* wrong Angle Method result, which in turn could lead to a misidentified target +* star. To prevent such false positive cases the matching threshold for this method +* is set to a conservative 40%. While this is only slightly below the threshold +* for the previous recovery method, it doesn't have the additional base specific +* matching requirements. This makes it applicable to generally poor and even +* worse results than covered by the previous method but still requires them to +* be good enough to be considered an indicator for a potential match. +* \n +* \n +* ### Effects of Interloping or Missing Observed Stars +* Additional and missing stars affect the result in different ways. While a +* missing star only increases the negative impact of fingerprints that cannot be +* assigned to a reference base, an interloper introduces several fingerprints +* which don't exist in the reference. Depending on the detected number of stars, +* this can render big parts of the observed star database as corrupted and +* therefore not matchable and is shown in Fig (REF) and (REF) +* below. +* \n +* @image html Interlopers_1.png "Effects of One Interloper" width = 180px +* \n +* Fig (REF) shows how a single interloper affects the fingerprints in the +* observed star database. While the red line illustrates the total number of +* fingerprints, the blue line describes the number of unaffected valid +* fingerprints. In addition their respective fractions of the observed database +* are indicated by the red and blue filled areas. The effect is especially profound +* for observations with a low amount of detected stars. An observation with only +* 5 stars that contains even a single interloper results in an observed star +* database with 50% corrupted fingerprints that won't be able to match the reference. +* Therefore it is almost unsolvable by the above defined validity criteria for +* a positive target identification. Fortunately the impact of interlopers +* diminishes with a growing number of available stars and settles between 10-15% +* for the expected star counts. +* \n +* @image html Interlopers_2.png "Effects of Two Interlopers" width = 180px +* \n +* Introducing a second interloper has more devastating effects and prevents +* detections with the main criteria to up to 8 detected stars (Fig.: REF). +* Even at higher star counts the corrupted fraction of fingerprints is still +* between 25-30% and thus requires very good matching results with the +* remaining stars. For this reason the Angle Method is meant to be configured +* such that it will operate on 10 or more stars. +* \n +* \n +* Generally, such interloping stars can originate from +* +* - overlapping faint stars +* - detections of too faint stars with an overlapping cosmic +* - detections of extremely bright cosmics +* - planets and asteroids +* +* and are usually encountered in crowded fields that favour the change of +* above mentioned overlaps. Misdetection of cosmics usually only occurs during +* SAA transits. Even though the chances to appear in sparsely populated FOV +* are low, the calculation of the observation specific __detection threshold__ +* is focused on the prevention of such glitch induced star detections. +* Depending on the available reference stars for an observation cosmic rays +* are not expected to interfere with the identification until currently up to +* 150 times the nominal cosmic ray rate (REF). Together with the careful +* selection of reference stars, interlopers are generally avoided and should +* only pose a problem in extreme SAA environments and poorly configured cases. +* \n +* \n +* ### Target Selection +* Once the target star could be identified its position on the CCD is used +* to calculate the offset to the originally intended __target location__. This +* offset is then reported to the attitude and orbital control system +* with a valid centroiding report. +* \n +* \n +* ### Identification Failure +* Simulations have shown that identification failures should be the exception +* (REF). The most common reason for this are: +* +* - bad the star positions +* - target location change +* - preemptive target acquisition during slew maneuvres +* - wrong input parameters (eg. wrong target location) +* +* whereas the first three are recoverable by repeated observation. Exceptionally +* heavy glitch rates or unlucky glitch positions can lead to offsets for the +* detected stars. This affects the edge lengths of fingerprints, which then +* cannot be matched with the reference star database. Repeated observation +* changes the FOV orientation, glitch positions and maybe also the rate. +* Therefore a successive observation under different conditions might be +* successful. The number of iterations in the case of identification failures +* is part of the input parameters that are provided with the Star Map (REF). +* The second recoverable occurrence is during target location changes. In the case +* of the CHEOPS AOCS the target is always placed at the target location of the +* previous observation. If it changes between two observations, the target candidates are +* being searched for in the wrong area of the image. For this reason the actual +* target won't be part of the target candidates and the attempt fails. Since +* the AOCS will place the target star in the correct location after the first +* failed attempt, any successive target acquisition iterations should be +* successful. The same is true for preemptive acquisition attempts. sometimes +* the target star might still be on the way to its designated target acquisition +* and therefore either be smeared or just not in the right place. Repeated +* attempts will lead to acquisition success once the slewing maneuver is finished. . +* \n +* The only critical algorithm fail stems from faulty algorithm configuration. This +* should be prevented by the mostly automated parameter setup and preview +* simulation capabilities of the Star Map Generator tool (REF). Therefore +* such cases usually originate from wrong input data or random operator failure. +* No matter what the nature of the acquisition fail was, they are also +* communicated to the parent level of the flight software by a centroiding +* report through the validity status parameter. +* +* +* +* +* +* +* +* +* @defgroup MagnitudeValidation Magnitude Validation Algorithms +* @ingroup TargetAcquisition +* +* @brief The Magnitude Validation Algorithm is used to identify target stars by photometry and is part of @ref TargetAcquisition. +* +* ## Introduction +* The __Magnitude Validation Algorithm (MVA)__ is an identification method +* that utilises photometry to compare a measured target candidates' signal to +* a reference signal that is provided for each observation. While initially +* only intended to be used as a secondary layer of verification for weak +* Angle Method Algorithm results, it was extended to also serve as the main +* identification method for sparse FOV with bright target stars in the form +* of the __Magnitude Validation Acquisition Algorithm (MVAA)__. These cases either +* prohibit long enough exposure times to image enough stars for the Angle Method +* or are easily identifiable due to a lack of similarly bright target candidates. +* \n +* \n +* ## Magnitude Validation Algorithm (MVA) +* This variant is used to confirm weak Angle Method results as stated above +* and hence can only be run in succession to it. The position for the best matched +* target candidate from the Angle Method, along with an expected reference target +* signal [ADU], the respective signal tolerance [%] and an estimate for the +* background signal are provided to the algorithm. The target candidate in +* question will be confirmed if the result of the radius photometry are within +* in the tolerance. Otherwise the acquisition attempt will be continued to be +* considered a failure. (@ref target_magnitude_validation "Magnitude Validation Algorithm") +* \n +* \n +* ## Magnitude Validation Acquisition Algorithm (MVAA) +* The standalone acquisition variant is slightly more complex as it also has to +* deal with the target candidate selection from the general @StarExtraction +* "Star Extraction" output.\n +* \n +* Comparable to the target candidate selection in the Angle Method, available +* star positions are only considered if they are within the __candidate area__ +* (REF) around the __target location__. Radius photometry is then used on +* each of these target candidates to determine the closest match with the +* target specific reference signal. While ideally one target candidate +* matches the reference signal there are exceptions that can lead to +* identification failures. +* +* - multiple target candidates with similar signal within the tolerance +* - stacked signal from overlapping stars +* - signal saturation +* - corrupt candidate positions with multiple detections on single objects +* - +* +* The first three cases are unsolvable since they will lead to either +* ambiguous or completely wrong photometric results. Fortunately, they should +* usually be avoidable by proper algorithm parameter selection and be identified +* by the ground segment before the observation attempt. +* +* The issue of faulty star positions on other hand is expected to sometimes happen +* independent of the algorithm configuration with relatively bright objects for +* a certain exposure time. For this reason safe guards that are meant to +* recover identification fails for such cases are in place. If up to five +* target candidates match the reference signal, they are not immediately discarded +* as multiple ambiguous matches but rather analysed whether they might describe +* the same object. Cases where the distances are all within the typical PSF +* diameter of 24 pixel (REF) and measured signals don't vary more than +* 3 percent, are considered to be a multiple detection of a single object. +* The 3 percent threshold is chosen well below the signal tolerance, so it +* addresses the signal variation that comes with the slight change in position +* Therefore, it fails on larger changes where the signal could be corrupted by +* the influence of a close neighbour or one of the positions in question actually +* is a close neighbour with a signal within the tolerance. The combination of +* these geometric and photometric criteria ensure that seperate candidates are +* not accidently considered as the same object. If they are met, the target +* candidate with the best signal match is considered to be the most central on +* the PSF and will be chosen as the identified target. +* (@ref target_magntitude_validation_acquisition "Magnitude Validation Acquisition Algorithm") +* +* +* As with the result of the Angle Method Algorithm, the outcome of the +* identification attempt is reported via the Centroid Report Service (196,1). +* \n +* \n +* ## Radius Photometry +* The __Radius Photometry__ determines the star signal on the full frame +* image within a radius of 25 pixel around a provided star position. This radius +* is guaranteed to contain the majority of the Point Spread Function +* (PSF) as defined in the respective CHEOPS science requirements (REF). +* Every pixel in the thereby covered area is corrected from the effects of the +* background signal and added up to obtain the remaining star signal in ADU. +* (@ref perform_radius_photometry "Perform Radius Photometry") +* +* +* ### PSF Shape +* Even though it was the intention to concentrate the PSF within the above +* mentioned radius of 25 pixel, the real optical system of CHEOPS does not +* perfectly achieve this goal. A comparison of the signal distribution of +* the intended case with a simulated PSF and the measured PSF can be seen in +* the figures below. While the full signal was contained in a rather compact +* spherical triangle in the simulation shown by Fig.: (REF), the real +* optical system features stronger diffractive effects. These result in a larger +* PSF that partly extends beyond the photometric radius (Fig.: (REF)). +* Fortunately, only a small fraction of about 1.5% of the signal is lost by this +* due to the relatively strong focus to the central pixels that can be seen in +* Fig.: (TBD). As a result only 98.5% of the expected signal will be measured +* by this implementation of the radius photometry. Addressing the problem by an +* extension of the photometry radius would lead to a problematic influence by +* the signal of close-by stars. Therefore it is just considered as a systematic +* difference in the comparision with the reference signal. +* +* @image html radius_photometry_sim_psf.png "Simulated PSF signal distribution" +* +* @image html radius_photometry_real_psf_shape.png "Measured PSF shape" +* +* @image html radius_photometry_real_psf_signal.png "Measured PSF distribution" +* \n +* \n +* ### Background Signal +* The background signal is calculated for the observation specific exposure time +* and includes estimates for the __bias__, __dark current__ and __sky signal__. +* It can be seen in Equation (REF) below: +* <center> +* bkgd_signal = bias + exposure_time * (sky_bkgd + dark_mean)); +* </center> +* \n +* \n +* ## Reference Signal Calculation +* The reference signal in ADU for the photometric methods is calculated from +* V-band of the GAIA star catalogue. Besides a slight colour correction for +* CHEOPS V-magnitudes it is especially important to account for different +* spectral distributions, since they highly affect the electron flux on the CCD. +* A more detailled description of the conversion can be found in section +* (REF) about the Star Map Generator Tool. +* +* The prediction of the star signal is currently limited by this conversion and +* is accurate to about 10%, which is significantly higher than any other +* component of the signal noise (REF) and therefore also the limiting +* factor of the photometric validation options. +* \n +* \n +*/ + + + +/***************************************************************** + * * + * LIEBE METHOD * + * * + *****************************************************************/ + +#include "AngleMethod.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "TaDatatypes.h" +#include "StarExtractor.h" +#include "IfswMath.h" + + +extern struct match_candidates_t *g_candidates; +extern struct unique_output_t *g_output; +extern struct unique_output_t *g_unique_base0; +extern struct unique_output_t *g_unique_duplicate_entry; +extern struct where_output_t *g_multi_base_skip_index; +extern struct where_output_t *g_multi_base_index; +extern struct where_output_t *g_duplicate_base0; +extern struct where_output_t *g_duplicate_base1; +extern struct unique_output_t *g_unique_stars; +extern struct where_output_t *g_base0_count; + + +/***************************************************************** + * * + * DATABASE GENERATION * + * * + *****************************************************************/ +/** + * @brief Create Reference Database uses provded reference positions to build + * the database of distance and angle combinations that are used + * for pattern recognition to identify the target star. + * @param pos Observation specific reference positions provided by StarMap telecommand + * @param target_index Index of the target in pos [default: 0] + * @param ref_DB Output structure for the reference database + * @param dr Estimated maximum position error that is considered in + * the database creation + */ +void create_ref_DB (struct ref_pos_t *pos, int target_index, struct ref_db_t *ref_DB, unsigned short dr) +{ + int i, j, k, fingerprint_counter; + float r[2], theta, x[2], y[2], cosinus; + + i = target_index; /* index of target star position */ + + fingerprint_counter = 0; + + /* dr is AMA tolerance from StarMap make sure it is != 0 */ + if (dr == 0) + dr = 1; + + /* Loop over all stars for possible combinations */ + for(j=0; j < pos->n; j++) + { + if (i != j) /* prevent self-pairing */ + { + x[0] = pos->x[i] - pos->x[j]; /* x-component of distance vector */ + y[0] = pos->y[i] - pos->y[j]; /* y-component of distance vector */ + r[0] = TaNorm(x[0], y[0]); /* length of distance vector */ + + /* Loop over still remaining stars for the second pair */ + for(k=0; k < pos->n; k++) + { + if((j!=k) && (i!=k)) /* prevent self-pairing */ + { + x[1] = pos->x[i] - pos->x[k]; /* x-component of distance vector */ + y[1] = pos->y[i] - pos->y[k]; /* y-component of distance vector */ + r[1] = TaNorm(x[1], y[1]); /* length of distance vector */ + + /* r[0] and r[1] are != 0, because in order to enter here, + pos must be > 3, i.e. there are more than 2 non-zero r */ + cosinus = (x[0]*x[1] + y[0]*y[1])/(r[0]*r[1]); + + /* prevent floating point rounding errors */ + if (cosinus < -1) + cosinus = -1; + if (cosinus > 1) + cosinus = 1; + + theta = acosf (cosinus)*180.0 / PI; /* angle between distance vectors */ + + /* store results in output structure */ + /* distances and angle are quanticed before storage */ + ref_DB->data[fingerprint_counter + 0] = (int)(r[0] / (2 * dr)); + ref_DB->data[fingerprint_counter + 1] = (int)(r[1] / (2 * dr)); + ref_DB->data[fingerprint_counter + 2] = (int)(theta / 5); + + fingerprint_counter += 3; + } + } + } + } + + ref_DB->n_stars = pos->n; /* store number of stars */ + + return; +} + +/** + * @brief Create Observed Database uses observation specific star positions which + * are provided by the @ref StarExtraction "Star Extraction procedure" to + * create the database of distance and angle combinations for the respective + * observation. This database will be compared to the @ref create_ref_DB + * "Reference Database" to identify the target star. + * @param pos Observation specific star positions provided + * by the Star Extraction process. + * @param obs_DB Output structure for the Observed Database + * @param target_location Intended target position on the CCD + * @param target_candidate_radius Search radius around the Target Location in + * which the target star should be located due + * to the pointing uncertainty + * @param dr Estimated maximum position error that is considered in + * the database creation + */ +void create_obs_DB (struct obs_pos_t *pos, struct obs_db_t *obs_DB, float *target_location, int target_candidate_radius, unsigned short dr) +{ + unsigned int i, j, k; + + int ii, r1, r2, r1_ulim, r1_llim, r2_ulim, r2_llim, ang, ang_llim, ang_ulim; + int base0_counter, base1_counter, fingerprint_counter; + int base0_value_counter, base1_value_counter, current_candidate; + float x[2], y[2], r[2], cosinus, theta, dAng; + + base0_counter = 0; /* tracks the number of target/first neighbour pairs */ + obs_DB->counter = 0; /* tracks the number of entries in obs_DB */ + obs_DB->candidate_counter = 0; + + /* dr is AMA tolerance from StarMap + make sure it is != 0 */ + if (dr == 0) + dr = 1; + + /* scan positions for eligible target candidates */ + find_target_candidates (pos, target_location, target_candidate_radius); + + /* only create a database for stars that qualify as candidates */ + for (ii=0; ii < pos->n_candidates; ii++) + { + /* tracks the amount of created databases. 1 for each candidate */ + obs_DB->candidate_counter++; + + /* tracks the amount of target/neighbour combinations */ + base0_counter = 0; + + /* tracks how many distance/distance/angle combinations existing + for each base0 combination. This number varies due to positional + error that is considered for the observed positions */ + base0_value_counter = 0; + base1_value_counter = 0; /* see above comment */ + + i = pos->candidate_index[ii]; + + /* iterate over all star combinations to create distance/angle database */ + for (j=0; j < pos->n; j++) + { + /* prevent self-pairing */ + if (j != i) + { + /* set starting index of current target/neighbour pair */ + /* total amount of target/neighbour pair defined by (n-1)*/ + obs_DB->base0_index[(ii*(pos->n-1)) + base0_counter] = obs_DB->counter; + + x[0] = pos->x[i] - pos->x[j]; /* x-component of distance vector */ + y[0] = pos->y[i] - pos->y[j]; /* y-component of distance vector */ + r[0] = TaNorm(x[0], y[0]); /* length of distance vector */ + + /* Possible position errors from the star extraction and hence + errors in the star separatoin measurements are compensated + for the observed database. The next two lines define upper and + lower limits for the quantisation of the distance measurement */ + r1_llim = (int)((r[0]-dr)/(2*dr)); + r1_ulim = (int)((r[0]+dr)/(2*dr)); + + /* tracks the amount of base0 + 2nd neighbour combinations */ + base1_counter = 0; + + for (k=0; k < pos->n; k++) + { + /* prevent self-pairing */ + if ((k != j) && (k != i)) /* NOTE: k!=i is redundant */ + { + /* track total amount of distance/distance/angle pairs(= fingerprint) */ + fingerprint_counter = 0; + /* set starting index of current base0 + 2nd neighbour pair */ + /* total amount of base0 + 2nd neighbour defined by (n-1)(n-2)*/ + obs_DB->base1_index[(ii*(pos->n-1)*(pos->n-2)) + base0_counter*(pos->n-2) + base1_counter] = obs_DB->counter; + x[1] = pos->x[i] - pos->x[k]; /* x-component of distance vector */ + y[1] = pos->y[i] - pos->y[k]; /* y-component of distance vector */ + r[1] = TaNorm(x[1], y[1]); /* length of distance vector */ + + /* r[0] and r[1] are always != 0, because in order to + enter here, pos must be > 3, i.e. there are more than + 2 non-zero r */ + cosinus = (x[0]*x[1] + y[0]*y[1])/(r[0]*r[1]); + + /* prevent floating point rounding errors */ + if (cosinus < -1) + cosinus = -1; + if (cosinus > 1) + cosinus = 1; + + theta = acosf (cosinus)*(180.0 / PI); /* angle between distance vectors*/ + dAng = calculate_dAng(x, y, dr, theta); /* calcualte angle error for quantisation */ + + r2_llim = (int)((r[1]-dr)/(2*dr)); /* define distance limits for quantisation */ + r2_ulim = (int)((r[1]+dr)/(2*dr)); + + ang_llim = (int)((theta-dAng)/5); /* define angle limits for quantisation*/ + ang_ulim = (int)((theta+dAng)/5); + + /* iterate of all distance and angle limits */ + for (r1=r1_llim; r1 <= r1_ulim; r1++) + { + for (r2=r2_llim; r2 <= r2_ulim; r2++) + { + for (ang=ang_llim; ang <= ang_ulim; ang++) + { + /* store quantised fingerprint data to database */ + obs_DB->data[obs_DB->counter + 0] = r1; + obs_DB->data[obs_DB->counter + 1] = r2; + obs_DB->data[obs_DB->counter + 2] = ang; + obs_DB->counter += 3; /* total number of db entries */ + fingerprint_counter++; /* number of fingerprints */ + } + } + } + + /* index in obs_DB->value_index of current candidate*/ + current_candidate = ii*(2*(pos->n-1)+2*(pos->n-1)*(pos->n-2)); + /* value_index stores the quantised values of base1 + current_candidate skips over previous candidate database + 2*(pos->n-1) left empty for base0 value index + 2*base1_value_counter finds the current index */ + obs_DB->value_index[current_candidate + 2*(pos->n-1) + 2*base1_value_counter + 0] = r2_llim; + obs_DB->value_index[current_candidate + 2*(pos->n-1) + 2*base1_value_counter + 1] = r2_ulim; + + /* base1_data_count stores the amount of fingerprints for + each base0/base1 combination. This number varies due to + the quantisation process and the integer nature + of the quantised values: + (n-1)(n-2) total base0/base1 combintaions are possible + (ii*(pos->n-1) * (pos->n-2)) skips over previous candidate's databases + (base0_counter*(pos->n-2) skips over previous base0 for the current candidate + base1_counter finds the current index of the current candidate + */ + obs_DB->base1_data_count[(ii*(pos->n-1) * (pos->n-2)) + (base0_counter*(pos->n-2) + base1_counter)] = fingerprint_counter; + + base1_counter++; + base1_value_counter++; + } + } + /* index in obs_DB->value_index of current candidate*/ + current_candidate = ii*(2*(pos->n-1) + 2*(pos->n-1)*(pos->n-2)); + /* value_index stores the quantised values of base0 */ + obs_DB->value_index[current_candidate + 2*base0_value_counter + 0] = r1_llim; + obs_DB->value_index[current_candidate + 2*base0_value_counter + 1] = r1_ulim; + + base0_counter++; + base0_value_counter++; + } + } + } + + /* store amount of created base0*/ + obs_DB->base0_counter = base0_counter; + + return; +} + +/** + * @brief Looks for detected stars in the Candidate Radius around the + * Target Location and stores them in the @ref obs_pos_t + * "Observerd Positions" structure + * + * @param pos Observation specific star positions provided + * by the Star Extraction process. + * @param target_location Intended target position on the CCD + * @param target_candidate_radius Search radius around the Target Location in + * which the target star should be located due + * to the pointing uncertainty + */ +void find_target_candidates (struct obs_pos_t *pos, float *target_location, int target_candidate_radius) +{ + unsigned int i; + float x, y; + float distSqX, radSq, distSqY; + + radSq = (float) target_candidate_radius; + radSq *= radSq; + + pos->n_candidates = 0; /* initialise number of candidates */ + + x = target_location[0]; + y = target_location[1]; + + for(i=0; i<pos->n; i++) + { + /* if (sqrt(pow((pos->x[i] - x), 2) + pow((pos->y[i] - y), 2)) < target_candidate_radius) */ + + distSqX = (pos->x[i] - x); + distSqX *= distSqX; + distSqY = (pos->y[i] - y); + distSqY *= distSqY; + /* check if distance to target location is below candidate radius */ + if ((distSqX + distSqY) < radSq) + { + /* check the new candidate doesn't exceed the maximum number of candidates */ + if (pos->n_candidates < NCAND) + { + /* store the candidates observed position index */ + pos->candidate_index[pos->n_candidates] = i; + pos->n_candidates++; + } + else + { + /* exit function once number of maximum candidates is reached */ + return; + } + } + } + + return; +} + + +/** + * @brief Calculates an estimate for the maximum error for the angle used in the + * @ref create_obs_DB "Observed Database" creation. This is used as limit + * in the quantisation process. + * @param x x-components of the two distance vectors + * @param y y-components of the two distance vectors + * @param dr Distance error + * @param theta Calculated angle + * @return Estimated angle error + */ +float calculate_dAng (float *x, float *y, unsigned short dr, float theta) +{ + float dAng; + float r[2], xx[2], yy[2], cosinus; + + /* copy values to preserve source variables */ + xx[0] = x[0]; + xx[1] = x[1]; + yy[0] = y[0]; + yy[1] = y[1]; + + /* Increases the separation of the 2 neighbour stars outwards by 2 dr + by assuming that their positional error is oriented towards each other */ + stretch_fingerprint(xx, dr); + stretch_fingerprint(yy, dr); + + r[0] = TaNorm(xx[0], yy[0]); /* calculate new separations after stretching */ + r[1] = TaNorm(xx[1], yy[1]); + + /* r[0] and r[1] are guaranteed to be > 0 by the parent function */ + cosinus = (xx[0]*xx[1] + yy[0]*yy[1])/(r[0]*r[1]); + + /* prevent floating point rounding errors */ + if (cosinus < -1) + cosinus = -1; + if (cosinus > 1) + cosinus = 1; + + /* Calculate difference between stretched and unstretched angle */ + dAng = fabsf(theta - acosf (cosinus) * (180.0 / PI)); + + /* Return it as the estimated maximum error */ + return dAng; +} + +/** + * @brief Stretches the angle of a fingerprint by increasing the distance + * vector separation by a total of twice the positional error + * + * @param x x or y components of both distance vectors. Depends on what the + * fuction receives + * @param dr Positional error from the @ref StarExtraction "Star Extraction" + * process + */ +void stretch_fingerprint (float *x, unsigned short dr) +{ + if (x[0] < 0) /* base star is below the first partner */ + { + if (x[1] < 0) /* base star is below the second partner*/ + { + if (x[0] < x[1]) /* determine order of partners */ + { + x[0] -= dr; /* increase the distance between them */ + x[1] += dr; /* to approximate a maximum angle error */ + } + else + { + x[0] += dr; /* increase the distance between them */ + x[1] -= dr; /* to approximate a maximum angle error */ + } + } + else + { + x[0] -= dr; /* increase the distance between them */ + x[1] += dr; /* to approximate a maximum angle error */ + } + } + else if (x[0] > 0) /* base star is above the first partner */ + { + if (x[1] > 0) /* base star is below the second partner*/ + { + if (x[0] > x[1]) /* determine order of partners */ + { + x[0] -= dr; /* increase the distance between them */ + x[1] += dr; /* to approximate a maximum angle error */ + } + else + { + x[0] += dr; /* increase the distance between them */ + x[1] -= dr; /* to approximate a maximum angle error */ + } + } + else + { + x[0] += dr; /* increase the distance between them */ + x[1] -= dr; /* to approximate a maximum angle error */ + } + } + + return; /* return via x pointer */ +} + +/** + * @brief Calculates the norm of a vector + * @param x x-component + * @param y y-component + * @return Norm + */ +float TaNorm (float x, float y) +{ + return fsqrts(x*x + y*y); +} + + +/***************************************************************** + * * + * MATCHING PROCESS * + * * + *****************************************************************/ + +/** + * @brief The match_databases function is the core of the Angle Method algorithm. + * It uses the previously created observed and reference databases as + * input and compares their fingerprints to determine if they were made from + * the same source star. The matching process tries to identify each entry + * of the reference database in the observed database and tracks both the + * number of positive matches as well as the location of all matching + * database entries. In a final matching quality assuring step all + * ambiguous matches are removed to provide a conservative and secure + * matching result. + * + * @param ref_DB Reference database from the reference positions provided + * for this observation + * @param obs_DB Observed database built positions provided by the @StarExtraction + * "Star Extraction" routine. + * @param results Output structure to store the matching results + */ +void match_databases (struct ref_db_t *ref_DB, struct obs_db_t *obs_DB, struct match_results_t *results) +{ + /* match_databases matches all entries and discards false positives */ + unsigned int i, j, ref_base0, ref_base1, ref_angle; + + /* initialize results constants and counter */ + results->n_obs_pos = obs_DB->base0_counter + 1; + results->n_ref_pos = ref_DB->n_stars; + + results->counter = 0; + results->base0_match_count_index = 0; + + /* Scan obs_DB for matching ref_DB entries in order of + ref_target and ref_star i base0 */ + for (i=0; i < ref_DB->n_stars-1; i++) + { + /* initialize results->base0_match_count array */ + results->base0_match_count[results->base0_match_count_index] = 0; + + /* filter obs_DB entries with matching base0 */ + ref_base0 = ref_DB->data[i*3*(ref_DB->n_stars-2)]; + find_base0(ref_base0, g_candidates, obs_DB); + + for (j=0; j < ref_DB->n_stars-2; j++) + { + /* filter base0 matched obs_DB entries for matching base1 */ + ref_base1 = ref_DB->data[i*3*(ref_DB->n_stars-2) + 3*j + 1]; + find_base1(ref_base1, g_candidates, obs_DB); + + /*n find full matches in base0/base1 pre filtered obs_DB entries */ + ref_angle = ref_DB->data[i*3*(ref_DB->n_stars-2) + 3*j + 2]; + find_matches(ref_base0, ref_base1, ref_angle, g_candidates, results, obs_DB); + } + /* store number of matches with ref_base0 of ref_target and ref_star i */ + results->base0_index[results->base0_match_count_index] = i; + results->base0_match_count_index++; + } + + /* discard duplicate matches of bases with different ref_star i */ + find_majority_matches(results); + + /* discard duplicate matches of different ref_bases with same obs_bases */ + correct_multiple_base_matches(results); + + /* discard matches of different obs_star (minority matches)*/ + find_valid_star_candidate(results); + + return; +} + +/** + * @brief Find base0 is used to reduce the scanned observed database to + * fingerprints with a matching base0 to the compared reference + * database. Therefore, it scans the @obs_db_t "value index" of the + * observed database for matching base0 lengths and stores the + * starting indices in the database of those fingerprints. Subsequent + * search operations for the base1 length and the angle will only be + * performed in the within the results of this operation for the current + * reference database entry. + * @param ref_base0 Quanticed base0 length for the current reference fingerprint + * @param candidates Temporary storage for eligible fingerprint indices + * @param obs_DB Observed database built positions provided by the @StarExtraction + * "Star Extraction" routine. + */ +void find_base0 (unsigned int ref_base0, struct match_candidates_t *candidates, struct obs_db_t *obs_DB) +{ + unsigned int i, j, n, n_base0, n_base1; + + n = obs_DB->base0_counter + 1; /* # of stars on which the DB is based */ + n_base0 = 2*(n-1); /* 2 entries each due to uncertainties */ + n_base1 = 2*(n-1)*(n-2); + + candidates->base0_match_counter = 0; /* initialise base0_match_counter */ + + /* iterate over databases of all possible target candidates */ + for(i=0; i < obs_DB->candidate_counter; i++) + { + /* iterate over all base0 entries in the observed database*/ + for(j=0; j < obs_DB->base0_counter; j++) + { + /* check if the current ref_base0 matches one of the two obs_base0 entries*/ + if ((ref_base0 == obs_DB->value_index[i*(n_base0 + n_base1) + 2*j]) || (ref_base0 == obs_DB->value_index[i*(n_base0 + n_base1) + 2*j + 1])) + { + /* store matching indices */ + candidates->base0_match_index[2*candidates->base0_match_counter + 0] = i; + candidates->base0_match_index[2*candidates->base0_match_counter + 1] = j; + candidates->base0_match_counter++; + } + } + } + + return; +} + +/** + * @brief Find base1 is used to further reduce the matching base0 sample, + * that was retrieved by @find_base0 in an earlier step. Again the + * @obs_db_t "value index" of the observed database is scanned for + * matching base1 lengths. Utilising the already reduced sample from + * the previous scan only the indices of matching base0 lengths are + * considered now. + * @param ref_base1 Quanticed base1 length for the current reference fingerprint + * @param candidates Temporary storage for eligible fingerprint indices + * @param obs_DB Observed database built positions provided by the @StarExtraction + * "Star Extraction" routine. + */ +void find_base1 (unsigned int ref_base1, struct match_candidates_t *candidates, struct obs_db_t *obs_DB) +{ + unsigned int i, j, star, base0, n, n_base0, n_base1; + + n = obs_DB->base0_counter + 1; /* # of stars on which the DB is based */ + n_base0 = 2*(n-1); /* 2 entries each due to quantisation */ + n_base1 = 2*(n-1)*(n-2); + + candidates->base1_match_counter = 0; /* initialise base1_match_counter */ + + /* Iterate over all fingerprints with matching base0 lengths */ + for (i=0; i < candidates->base0_match_counter; i++) + { + /* Extract target candidate (star) and base0 length data */ + star = candidates->base0_match_index[2*i + 0]; + base0 = candidates->base0_match_index[2*i + 1]; + + /* Iterage over all base1 entries (n = base0-1) in the value index */ + for (j=0; j < obs_DB->base0_counter-1; j++) + { + /* value index navigation: + star*(n_base0 + n_base1) skips entries for other target candidates + n_base0 skips base0 entries for current candidate + 2*base0*(n-2) skips previous base1 entries + 2 entries per (n-2) base1 for each base0 + */ + /* check if the current ref_base1 matches one of the two obs_base1 entries*/ + if ((ref_base1 == obs_DB->value_index[star*(n_base0 + n_base1) + n_base0 + 2*base0*(n-2) + 2*j]) || (ref_base1 == obs_DB->value_index[star*(n_base0 + n_base1) + n_base0 + 2*base0*(n-2) + 2*j + 1])) + { + /* store matching indices */ + candidates->base1_match_index[3*candidates->base1_match_counter + 0] = star; + candidates->base1_match_index[3*candidates->base1_match_counter + 1] = base0; + candidates->base1_match_index[3*candidates->base1_match_counter + 2] = j; + candidates->base1_match_counter++; + } + } + } + return; +} + +/** + * @brief Find matches scans the remaining sample observed database after the + * reductions by find_base0 and find_base1 for the current full + * reference fingerprint. Inidces and number of matching fingerprint + * are stored in this step. + * @param ref_base0 Quanticed base0 length for the current reference fingerprint + * @param ref_base1 Quanticed base1 length for the current reference fingerprint + * @param ref_angle Quanticed angle for the current reference fingerprint + * @param candidates Temporary storage for eligible fingerprint indices + * @param results Output structure to store the matching results + * @param obs_DB Observed database built positions provided by the @StarExtraction + * "Star Extraction" routine. + */ +void find_matches (unsigned int ref_base0, unsigned int ref_base1, unsigned int ref_angle, struct match_candidates_t *candidates, struct match_results_t *results, struct obs_db_t *obs_DB) +{ + unsigned int i, j, star, base0, base1, n, index, data_index; + unsigned int counter_ini, counter_end, n_matches; + + n = obs_DB->base0_counter + 1; /* # of stars on which the DB is based */ + + counter_ini = results->counter/(float)4; /* initialize counter for current ref_base */ + + /* iterate pre filtered entries with matching base0 and base1 */ + for (i=0; i < candidates->base1_match_counter; i++) + { + /* Extract target candidate (star) and base0/base1 length data */ + star = candidates->base1_match_index[3*i + 0]; + base0 = candidates->base1_match_index[3*i + 1]; + base1 = candidates->base1_match_index[3*i + 2]; + + /* create index to access the right obs_DB-> data entries */ + /* index is used to navigate the logical obs_DB structure */ + /* index navigation: + star*(n-1)*(n-2) skips entries for other target candidates + n number of stars + (n-1) number of base0 + (n-2) number of base1 + + base0*(n-2) skips previous base0 entrie + each base0 has (n-2) entries for its base1 combinations + + base1 skips previous base1 entries + */ + index = (star*(n-1)*(n-2)) + base0*(n-2) + base1; + /* data_index contains the actual position in the obs_DB data. This is + necessary since not every base0/base1 combination produces an equal + amount of fingerprints. */ + data_index = obs_DB->base1_index[index]; + + /* Iterate over the number of fingerprints for base0/base1 combination*/ + for (j=0; j < obs_DB->base1_data_count[index]; j++) + { + /* compare base0, base1, angle (full fingerprint) */ + if ((ref_base0 == obs_DB->data[data_index + 3*j + 0]) && (ref_base1 == obs_DB->data[data_index + 3*j + 1]) && (ref_angle == obs_DB->data[data_index + 3*j + 2])) + { + /* store matched indices */ + results->match_results[results->counter + 0] = star; + results->match_results[results->counter + 1] = base0; + results->match_results[results->counter + 2] = base1; + results->match_results[results->counter + 3] = j; + results->counter += 4; + } + } + } + + counter_end = results->counter/(float)4; + + /* calculate number of matches for current ref_base */ + n_matches = counter_end - counter_ini; + + if (n_matches > 0) + results->base0_match_count[results->base0_match_count_index] += n_matches; + + return; +} + +/** + * @brief This function is the first step in the process to eliminate false + * positive matches. Due to the quantisation process during the database + * creations some fingerprints can be ambiguously matched to the wrong + * reference base. Therefore all matches for a certain reference base0 + * and base1 length are checked to be from the same observed base0. If + * this is not the case matches that don't fit the majority of matches + * for this set of fingerprints will be discarded. + * @param results Output structure to store the matching results + */ +void find_majority_matches (struct match_results_t *results) +{ + unsigned int i, current_match_index; + + current_match_index = 0; + + /* initialize trackers and histogram */ + /* The dimensions of the trackers and the histogram are defined + by the amount of available base0 combinations and thus each represent + such a base0. The histogram tracks the amount of matches for each base0, + while the trackers log the index observed star or base0 with which the + majority of matches occured. The logged indices from the previous + Find Matches routine are used as input data for this process. Since they + are a certain base combintaion they are numbered from [0:n stars-1] and + don't represent any quanitsed entities. + The value if -1 is used to indicate when no match was found. + */ + for (i=0; i < results->n_ref_pos-1; i++) + { + results->match_histogram[i] = 0; + results->star_tracker[i] = -1; + results->base0_tracker[i] = -1; + } + /* iterate through all matched bases via results->base0_match_count */ + for (i=0; i < results->base0_match_count_index; i++) + { + /* find the dominant result for the matched observed star */ + find_unique_matches(results, g_output, i, current_match_index, 0); + + /* Store the results if there is a match for this reference base*/ + if (g_output->index_max_count != -1) + results->star_tracker[results->base0_index[i]] = g_output->items[g_output->index_max_count]; + + /* Delete minority matches if the reference was matched with multiple stars */ + if (g_output->n_items > 1) + delete_results(results, i, current_match_index, 0); + + /* find the dominant result for the matched observed base0 */ + find_unique_matches(results, g_output, i, current_match_index, 1); + + /* Store the results if there is a match for this reference base*/ + if (g_output->index_max_count != -1) + results->base0_tracker[results->base0_index[i]] = g_output->items[g_output->index_max_count]; + + /* Delete minority matches if the reference was matched with multiple base0 */ + if (g_output->n_items > 1) + delete_results(results, i, current_match_index, 1); + + /* Due to the quantisation multiple variations of a single observed + fingerprint can be matched to several fingerprints of that reference + base0. Such multiple and hence ambiguous matches are identified here */ + find_unique_matches(results, g_output, i, current_match_index, 2); + + /* The match histogram is incremented by the number of matches uniquely + identified in the previous step of the find_unique_matches function. + Selective counter only counts items marked as unique */ + results->match_histogram[results->base0_index[i]] = selective_counter(g_output->counts, g_output->n_items, 1); + + /* update navigation index */ + current_match_index += 4*results->base0_match_count[i]; + } + + return; +} + +/** + * @brief Scans the match result for a certain reference base0 for its unique + * matches with a certain observed base0. If matching with Additional + * observed base0 occurs, the dominantly matched observed base0 for the + * reference is considered to be the correct match. Matches with other + * observed base0, including their contribution to the overall match + * count are discarded. + * @param results Output structure to store the matching results + * @param output Output structure for the TaUnique function + * Stores unique items and their number of occurrence + * Used as return value. + * @param match_count_index Index of the of the current base0 to access + * the respective number of matches + * @param match_results_index Starting index for match results access + * @param entry Selects which part of the fingerprint is used. + * 0: star, 1: base0, 2:base1 + */ +void find_unique_matches (struct match_results_t *results, struct unique_output_t *output, int match_count_index, int match_results_index, int entry) +{ + unsigned int i, j; + int item, tmp_max; + + output->n_items = 0; + + /* Iterate over the number of matched fingerprints */ + for(i=0; i < results->base0_match_count[match_count_index]; i++) + { + /* select the current matched entity (star/base0/base1/fp) */ + item = results->match_results[match_results_index + 4*i + entry]; + + /* only call unique if the current item is a valid entry */ + if (item == -1) + continue; + + /* Count the amount of uniquely matched entities for this base0 */ + TaUnique(output, item); + } + + /* find the item with the maximum number of counts */ + if (output->n_items == 1) + /* Only 1 item? Select first item (position = 0)*/ + output->index_max_count = 0; + + else if (output->n_items > 1) + { + /* More than one item? Find index of the item with the maximum count */ + tmp_max = output->counts[0]; + for (j=1; j < output->n_items; j++) + { + if (output->counts[j] > tmp_max) + { + tmp_max = output->counts[j]; + output->index_max_count = j; + } + } + } + else + /* Invalid result */ + output->index_max_count = -1; + + return; +} + + +/** + * @brief This function is a further step in the reduction of false positive + * identifications to identify matches of multiple reference bases with + * the same observed fingerprint (the previous step dealt with the same + * problem within single reference base0).Therefore the exact matching + * history for each reference base0 is analysed to identify different + * reference base0 that matched with the same observed fingerprint which + * must not happen for unambiguous results. These cases are compared + * amongst each other and only the best result is kept and corrected + * for all fingerprints that were also matched to other reference base0. + * @param results Output structure to store the matching results + */ +void correct_multiple_base_matches(struct match_results_t *results) +{ + int index, tmp_max, maximum, valid_base_match_index, duplicate_base_match_index, base0_max_index; + unsigned int h, i, j, k, l, max_index, base0_match_index; + + /* Scan which observed star was matched for each reference base0*/ + find_unique_tracker_items (results->star_tracker, results->n_ref_pos-1, g_unique_stars, 0, 0); + + /* Iterate over every matched star to correct mutlitple base0 matches */ + for(h=0; h < g_unique_stars->n_items; h++) + { + /* Find tracker items that don't belong to the currently analysed star */ + TaWhere (results->star_tracker, results->n_ref_pos-1, g_multi_base_skip_index, g_unique_stars->items[h], 5); + + /* Scan which observed base0 was matched for each reference base0 for the current star */ + find_unique_tracker_items (results->base0_tracker, results->n_ref_pos-1, g_unique_base0, g_multi_base_skip_index->n_items, g_multi_base_index->items); + + /* Analyse the result of the previous step to find if a certain observed + base0 was matched with more than one reference base0. The fingerprints + of one reference base must only match the fingerprints of one particular + observed base. These cases are stored in g_multi_base_index for further + investigation */ + TaWhere (g_unique_base0->counts, g_unique_base0->n_items, g_multi_base_index, 1, 3); + + /* Iterate through each multi base flagged reference base results */ + for(i=0; i < g_multi_base_index->n_items; i++) + { + /* g_multi_base_index stores the index of a multiply matched + base0 in g_unique_base0. It is used to access the respective base0 to + identify which observed base0 was multiply matched.*/ + index = g_multi_base_index->items[i]; + + /* All reference base matches with the multiply matched observed base0 + are extracted from the Base0 Tracker. The observed base0 of interest + is identified by its number stored in g_unique_base0->items[index]. The + result contains the affected reference base0 indices and is stored in + g_duplicate_base0 */ + TaWhere (results->base0_tracker, results->n_ref_pos-1, g_duplicate_base0, g_unique_base0->items[index], 0); + + /* The reference base0 indices in g_duplicate_base0 are used to access the + number of matches in the Match Histogram. The reference base0 with more + matches of the observed base0 will be considered as the valid match */ + tmp_max = results->match_histogram[g_duplicate_base0->items[0]]; + max_index = 0; + maximum = TRUE; + + /* find the duplicate base0 with more matches */ + for(j=1; j < g_duplicate_base0->n_items; j++) + { + /* the base at max index is seen as the best match and hence valid base */ + if (results->match_histogram[g_duplicate_base0->items[j]] > tmp_max) + { + tmp_max = results->match_histogram[g_duplicate_base0->items[j]]; + max_index = j; /* Index of the base with most matches */ + maximum = TRUE; + } + /* check if clear maximum can be determined */ + else if (results->match_histogram[g_duplicate_base0->items[j]] == tmp_max) + { + maximum = FALSE; + } + } + + /* If no maximum could be found due to the same number of matches for + all affected reference bases all their results are discarded and their + Match Histogram counters set to 0 */ + if (!maximum) + { + /* reset all match counts to 0 if no clear maximum could be found */ + for (j=0; j < g_duplicate_base0->n_items;j++) + { + results->match_histogram[g_duplicate_base0->items[j]] = 0; + } + } + /* If a maximum for the matches with a reference base0 can be identified + the counts in the Match Histogram have to be corrected*/ + else + { + /* used for match_results with all indices to star/base0/base1/fp */ + valid_base_match_index = 0; + + /* find match results start index for the valid reference base */ + for (j=0; j < g_duplicate_base0->items[max_index]; j++) + { + valid_base_match_index += 4*results->base0_match_count[j]; + } + + /* Index of best matched base0 in the tracker [0:n-1] */ + base0_max_index = g_duplicate_base0->items[max_index]; + + /* Iterate over all reference base0 that were flagged to be matched with + the same observed base0 and discard invalid results */ + for (j=0; j < g_duplicate_base0->n_items; j++) + { + if (j != max_index) + { + /* Extract index of not best matched reference base0 with duplicates */ + base0_match_index = g_duplicate_base0->items[j]; + + /* Initisalise variables */ + g_duplicate_base1->n_items = 0; + duplicate_base_match_index = 0; + + /* reset match counts to 0 for this reference */ + results->match_histogram[g_duplicate_base0->items[j]] = 0; + + /* find match results start index for the invalid reference base */ + for (k=0; k < base0_match_index; k++) + { + duplicate_base_match_index += 4*results->base0_match_count[k]; + } + + /* iterate over all matches of the valid reference base0 */ + for (k=0; k < results->base0_match_count[base0_match_index]; k++) + { + /* Skip for invalid/previously discarded entries */ + if (results->match_results[duplicate_base_match_index + 4*k + 2] == -1) + continue; + + /* Iterate over valid base matches and compare if the matched + fingerprints (base0/base1 combinations) are the same as the + the fingerprints that were matched to the other reference base0 + with less overall matches. Consider them as ambiguous and + store them in g_duplicate_base1 for later deletion */ + for (l=0; l < results->base0_match_count[base0_max_index]; l++) + { + if (results->match_results[duplicate_base_match_index + 4*k + 2] == results->match_results[valid_base_match_index + 4*l + 2]) + { + g_duplicate_base1->items[g_duplicate_base1->n_items] = results->match_results[duplicate_base_match_index + 4*k + 2]; + g_duplicate_base1->n_items++; /* matched with same base1? -> store base1 for later removal */ + break; /* break is valid as each base1 entry is unique at this point */ + } + } + } + } + } + + /* Initialise g_unique_duplicate_entry counter */ + g_unique_duplicate_entry->n_items = 0; + + /* Find how often duplicate entries show up for a certain base1 to only + correct the count of the valid reference base once. + In each iteration a new items is fed into the g_unique_duplicate_ + entry structure to analyse if it already occured or not. */ + for (k=0; k < g_duplicate_base1->n_items; k++) + { + TaUnique (g_unique_duplicate_entry, g_duplicate_base1->items[k]); + } + + /* correct match_histogram from multiple matches */ + results->match_histogram[g_duplicate_base0->items[max_index]] -= g_unique_duplicate_entry->n_items; + } + } + } + + return; +} + +/** + * @brief After discarding false positives within the reference bases the + * best target candidate is chosen as the target and all matches + * with other target candidates are deleted from the Match Histogram. + * In addition fingerprints that were matched by chance are identified + * by the match statistics and discarded as well. The remaining matches + * are used to calculate the final match count. + * + * @param results Output structure to store the matching results + */ +void find_valid_star_candidate (struct match_results_t *results) +{ + int max_index, min_matches; + unsigned int i; + float avg_match, std; + + /* Scan which observed target candidate was matched for each reference base0 */ + find_unique_tracker_items (results->star_tracker, results->n_ref_pos-1, g_unique_stars, 0, 0); + + /* Determine the valid result by choosing the star with most matches */ + max_index = TaArgmax (g_unique_stars->counts, g_unique_stars->n_items); + + /* Case when maximum was found */ + if (max_index > -1) + { + /* Store valid target candidate star */ + results->target_star = g_unique_stars->items[max_index]; + + /* Reset match_histogram entries that were matched to another candidate */ + for (i=0; i < results->n_ref_pos - 1; i++) + { + if (results->star_tracker[i] != results->target_star) + results->match_histogram[i] = 0; + } + + /* Most false positives have been discarded at this point. Only + fingerprints that matched by chance are left. These can be easily spotted + since a reference base with such will have significantly fewer matches + in the single digits. Therefore set a minimum number of matches for + each reference base0 in the histogram to sort them out as well */ + + /* Check if matches survived all the reduction process */ + if (TaMax(results->match_histogram, results->n_ref_pos-1) > 0) + { + /* Calculate the average number of matches per reference base0 and the + respective standard deviation for this result */ + avg_match = TaAverage (results->match_histogram, results->n_ref_pos-1); + std = TaStdev (results->match_histogram, results->n_ref_pos-1, avg_match); + + /* Define minimum number of matches to be within 2 sigma of the average */ + min_matches = (int)avg_match - (int)(2*std); + + /* Discard matches of all reference bases + that don't satisfy the minimum match number */ + for (i=0; i < results->n_ref_pos - 1; i++) + { + if (results->match_histogram[i] < min_matches) + results->match_histogram[i] = 0; + } + + /* Count how many reference bases have matched observed bases */ + TaWhere (results->match_histogram, results->n_ref_pos-1, g_base0_count, 1, 4); + /* Store number of total matches over all reference bases */ + results->n_matched_items = TaSum (results->match_histogram, results->n_ref_pos-1); + /* Store number of reference bases matched to observed bases */ + results->n_matched_bases = g_base0_count->n_items; + } + else + /* No target candidate can clearly be identified as the target. + -> matching process failed */ + { + results->target_star = -1; + results->n_matched_items = 0; + results->n_matched_bases = 0; + } + } + else + { + /* No target candidate can clearly be identified as the target. + -> matching process failed */ + results->target_star = -1; + results->n_matched_items = 0; + results->n_matched_bases = 0; + } + + return; +} + + +/** + * @brief This function serves as a wrapper to set up TaUnique to identify the + * unique entries in the tracker structures that stores the indices + * of star/base0/base1/fp matched with a reference base + * + * @param tracker Array of the results structure that stores with which + * star/base0/base1/fp a certain reference base was matched + * @param n Number of entries in the tracker + * @param output Output structure of the TaUnique function + */ +void find_unique_tracker_items (int *tracker, unsigned int n, struct unique_output_t *output, unsigned int n_skip, unsigned int *skip_entries) +{ + unsigned int i, j; + int item; + + output->n_items = 0; + + /* iterate over current match star/base0/base1/fp */ + for (i=0; i < n; i++) + { + /* check if the current index is on the list for skipped indices */ + for(j=0; j< n_skip; j++) + { + if (i == skip_entries[j]) + continue; + } + + item = tracker[i]; + + /* invalid entries are marked as -1. Everything else is >= 0 */ + if (item < 0) + continue; + /* Feed the item into the TaUnique structure to determine if it is a + unique entry amongst the other items in this loop. */ + TaUnique (output, item); + } + + return; +} + + +#define TA_MATCHED_ITEMS_PCT 50 +#define TA_MATCHED_BASES_PCT 50 +#define TA_MATCHED_BASEITEMS_PCT 65 +/** + * @brief The match quality determined by the total number of matches in the + * Match Histogram of the results compared to the theoretical maximum + * for the given observed positions. If more than 50% of the possible + * matches are met the target identification is considerd to be valid. + * @param results Output structure to store the matching results + * @param obs_pos Observed positions that were extracted by the Star Extraction + * process + */ +void determine_match_quality (struct match_results_t *results, struct obs_pos_t *obs_pos) +{ + int max_possible_items, possible_items; + float identified_items_percent = 0.0, identified_base_items_percent = 0.0, identified_bases_percent = 0.0; +#ifdef GROUNDSW + float x, y; +#else + (void) obs_pos; +#endif + /* The number of possible fingerprints is defined by (n-1)*(n-2) where + n is the number of available stars + (n-1) is the number of base0 combinations between the stars + (n-2) is the number of base1 combinations between the stars. + + possible_items number of total possible fingerprints including + reference bases which results might have been discarded + during the previous steps. Theoretical maximum from the + reference point of view. + */ + possible_items = results->n_matched_bases * (results->n_obs_pos-2); + + /* max_possible_items number of total possible fingerprints created form the + observed positions. Not all of these possible + fingerprints will be found in the reference database + since interloping stars or false positive positions + from cosmics might contaminate the observed positions */ + /* n_obs_pos > 3, thus the result is > 0 */ + max_possible_items = (results->n_obs_pos-1)*(results->n_obs_pos-2); + + /* Percentage of matched observed fingerprints */ + if (max_possible_items > 0) + { + identified_items_percent = (results->n_matched_items / (float)max_possible_items) * 100; + } + + /* Percentage of matched referece base0 */ + if (results->n_obs_pos-1 >= 2) + { + identified_bases_percent = (results->n_matched_bases / ((float)results->n_obs_pos-1)) * 100; /* n_obs_pos > 3 */ + } + + /* Percentage of matched fingerprints relative to the maximum possible + matches from the reference POV (base_items = fingerprints) */ + if (possible_items > 0) + { + identified_base_items_percent = (results->n_matched_items / (float)possible_items) * 100; + } + + /* the match quality is used by the TargetAcquisition */ + /* it will be used in the target acquisition main function and has to + represent the percentage that is closest to the theoretical maximum + from the reference POV */ + results->match_quality = identified_items_percent; + + /* The result based solely on the observed position is used to determine + the validity of the target acquisition first. Reference stars for the + database and the detection threshold for the Star Extraction routine are + selected such that all observed positions should also be included in the + reference. Therefore a good observation without false positives from + cosmic rays etc will be well matched with the available reference. + + A positive identification as target requires more than 50% of the + possible fingerprints for the observed positions to be matched. Even + though the earlier match result reduction tried to exclude all ambiguous + matched it is theoretically possible that a very difficult case could + lead to a wrongly selected target candidate. Requiring more than half of + the database to uniquely match to the candidate garantuees that no other + candidate would have been a better match. */ + if (identified_items_percent > TA_MATCHED_ITEMS_PCT) + results->valid_quality = TRUE; + + /* For observations with a low number of observed stars in sparse fields + a single false detection can degrade the result comparatively stronger + than it would in a crowded field. Therefore otherwise good observations + might fail the target acquisition. To counter this the number of matches + is compared to the theoretical values from the reference POV. To be on + the safe side restrictions for positive identifications are a bit stronger + so that the result has to satisfy 65% as minimum value for the matched + reference bases and the matches in each reference base.*/ + /*else if ((identified_bases_percent > TA_MATCHED_BASES_PCT) && (identified_base_items_reduced_percent > TA_MATCHED_BASEITEMS_PCT))*/ + else if ((identified_bases_percent > TA_MATCHED_BASES_PCT) && (identified_base_items_percent > TA_MATCHED_BASEITEMS_PCT)) + results->valid_quality = TRUE; + + /* Otherwise the identification through the Angle Method is marked as failed */ + else + results->valid_quality = FALSE; + +#ifdef GROUNDSW + if (results->target_star >= 0) + { + x = obs_pos->x[obs_pos->candidate_index[results->target_star]]; + y = obs_pos->y[obs_pos->candidate_index[results->target_star]]; + + TA_DEBUG("Target identified as observed star %d (target candidate %d) at position [x, y]: [%.2f, %.2f]\n", obs_pos->candidate_index[results->target_star], results->target_star, x, y); + TA_DEBUG("%.2f percent detected database items (%d / %d matched items)\n", identified_items_percent, results->n_matched_items, max_possible_items); + TA_DEBUG("%.2f percent detected items (%d / %d) within the identified bases (%d / %d)\n", identified_base_items_percent, results->n_matched_items, possible_items, results->n_matched_bases, results->n_obs_pos-1); + + if (results->valid_quality) + TA_DEBUG("\nTarget validation successful.\n"); + else + TA_DEBUG("\nTarget validation unsuccessful.\n"); + } +#endif + + return; +} + +/** + * @brief Uses the target star position obtained from the Angle Method Algorithm + * to calculate the pixel offset to the intended Target Location in + * centipixel [cpx]. The offset is returned by the pointer to the shift + * array. + * @param obs_pos Observed positions that were extracted by the + * Star Extraction process +* @param results Output structure to store the matching results + * @param shift Calculated offset from the Target Location [cpx] + * @param target_location Intended Target Location provided by ground support + */ +void calculate_target_shift_AMA (struct obs_pos_t *obs_pos, struct match_results_t *results, int *shift, float *target_location) +{ + float x, y, dx, dy; + + /* retrieve x/y coordinates from the observed positions and results */ + + /* NOTE: The maximum number of obs_pos->candidate_index members is counted in find_target_candidates and assigned to obs_pos->n_candidates. + The members in obs_pos->n_candidates are then used to construct the entries in the observed star database (obs_DB) and results->target_star + is restricted to its length. Therefore results->target_star cannot exceed the array */ + + x = obs_pos->x[obs_pos->candidate_index[results->target_star]]; + y = obs_pos->y[obs_pos->candidate_index[results->target_star]]; + + /* calculate offset */ + dx = target_location[0] - x; + dy = target_location[1] - y; + + /* conversion to centi-pixel */ + shift[0] = (int)(dx * 100); + shift[1] = (int)(dy * 100); + +#ifdef GROUNDSW + /* Redudant information. Displayed by TargetAcquisitionMain.c */ + /* printf("\nMove satellite by dx: %.2f, dy: %.2f pixel to center it.\n", dx, dy);*/ +#endif + + return; +} + + +/***************************************************************** + * * + * GENERAL FUNCTIONS * + * * + *****************************************************************/ + +/** + * @brief The TaUnique function analyses its input data to determine if the + * items in the data are unique. In addition it counts how often a + * provided item occurs. It works with one item at a time and stores all + * the provided data in the output structure. Therefore it is usually + * embedded in some form of loop in the calling function. + * The function is designed after the unique function in numpy. + * @param output Output structure to store the provided data and result + * @param item Iteratively provided data of the parent function + */ +void TaUnique (struct unique_output_t *output, int item) +{ + unsigned int j, new_item; + + if (output->n_items == 0) + { + /* add the first item to the item list and increase count */ + output->items[output->n_items] = item; + output->counts[output->n_items] = 1; + output->n_items++; + } + else + { + new_item = TRUE; /* initialize new_item */ + + /* look if current item matches existing item */ + for (j=0; j < output->n_items; j++) + { + if (item == output->items[j]) + { + /* increase count if it's already in the list */ + output->counts[j]++; + new_item = FALSE; + break; + } + } + + /* add it to the end of the list if it's new */ + if (new_item) + { + output->items[output->n_items] = item; + output->counts[output->n_items] = 1; + output->n_items++; + } + } + + return; +} + +/** + * @brief The TaWhere function scans the provided array for items + * = / </ <= / > / >= compared to a provided argument. The respective + * operation can be defined by the operator variable. The result is an + * array with the items that satisfy the condition and their count. + * The function is designed to support more operators than necessary + * for the target acquitision. + * + * The function is designed after the where function in numpy. + * @param x Input data array + * @param n Number of elements in x + * @param output Output structure with items and n + * @param arg Argument to which the items in x are compared + * @param operator Operator for the comparison: + * 0: = + * 1: < + * 2: <= + * 3: > + * 4: >= + * 5: != + */ +void TaWhere (int *x, unsigned int n, struct where_output_t *output, int arg, int operator) +{ + unsigned int i; + + output->n_items = 0; + + for (i=0; i < n; i++) + { + switch (operator) + { + case 0: + + if (x[i] == arg) + { + output->items[output->n_items] = i; + output->n_items++; + } + break; + + case 1: + + if (x[i] < arg) + { + output->items[output->n_items] = i; + output->n_items++; + } + break; + + case 2: + + if (x[i] <= arg) + { + output->items[output->n_items] = i; + output->n_items++; + } + break; + + case 3: + + if (x[i] > arg) + { + output->items[output->n_items] = i; + output->n_items++; + } + break; + + case 4: + + if (x[i] >= arg) + { + output->items[output->n_items] = i; + output->n_items++; + } + break; + + case 5: + + if (x[i] != arg) + { + output->items[output->n_items] = i; + output->n_items++; + } + break; + + default: + #ifdef GROUNDSW + TA_DEBUG("unknown logic for where function."); + #endif + break; + } + } + + return; +} + +/** + * @brief Delete Results is used to delete false positive matches in the + * Tracker arrays in the Find Majority Matches function + * @param results Output structure to store the matching results + * @param match_count_index Index of the reference base from which results + * are deleted + * @param match_results_index Index of the entry to delete within the + * reference base + * @param entry Argument to control whether fingerprints shall be + * deleted based on the matched observed star (0) + * or the observed base (1). + */ +void delete_results (struct match_results_t *results, unsigned int match_count_index, unsigned int match_results_index, unsigned int entry) +{ + unsigned int i, j, current_index; + + /* Iterate over all matched fingerprints of a refernce base0 */ + for (i=0; i < results->base0_match_count[match_count_index]; i++) + { + /* delete entry by comparing matched star */ + if (entry == 0) + { + /* each fingerprint consists of 4 items hence the +4* in the indices */ + if (results->star_tracker[results->base0_index[match_count_index]] != results->match_results[match_results_index + 4*i + entry]) + { + /* Advance to the next fingerprint */ + current_index = match_results_index + 4*i; + for(j=current_index; j<current_index+4; j++) + { + results->match_results[j] = -1; + } + } + } + + /* delete entry by comparing matched base within star */ + else if (entry == 1) + { + /* 4*i advances to the next fingerprint, +entry selects the compared item */ + if (results->base0_tracker[results->base0_index[match_count_index]] != results->match_results[match_results_index + 4*i + entry]) + { + /* Advance to the next fingerprint */ + current_index = match_results_index + 4*i; + for (j=current_index; j < (current_index + 4); j++) + { + results->match_results[j] = -1; + } + } + } + } + + return; +} + +/** + * @brief Selective Counter counts the number of array items that match + * the provided argument. + * @param x Array containing the data to be analysed + * @param n Number of array items + * @param arg Argument that has to be matched to increment counter + * @return Number of array items that matched the argument + */ +int selective_counter (int *x, int n, int arg) +{ + int i, counter; + + counter = 0; + for (i=0; i < n; i++) + { + if (x[i] == arg) + counter++; + } + + return counter; +} + + +/** + * @brief The TaArgmax function finds the index the highest entry of an array. + * @param x Array containing the data to be analysed + * @param n Number of array items + * @return Index of the maximum entry + */ +int TaArgmax (int *x, int n) +{ + int i, tmp_max, max_index; + + /* Initialise the temporary maximum */ + tmp_max = x[0]; + max_index = 0; + + /* Iterate over data array */ + for (i=1; i < n; i++) + { + /* If the current entry is larger than the current maximum use it instead */ + if (x[i] > tmp_max) + { + tmp_max = x[i]; + max_index = i; + } + /* If two entries have the same value and no clear maximum can be found + set the maximum index to an invalid value */ + else if (x[i] == tmp_max) + { + max_index = -1; + } + } + + return max_index; +} + +/** + * @brief The TaArgmin function finds the index the highest entry of an array. + * @param x Array containing the data to be analysed + * @param n Number of array items + * @return Index of the maximum entry + */ +int TaArgmin (float *x, int n) +{ + int i, min_index; + float tmp_min; + + /* Initialise the temporary maximum */ + tmp_min = x[0]; + min_index = 0; + + /* Iterate over data array */ + for (i=1; i < n; i++) + { + /* If the current entry is smaller than the current maximum use it instead */ + if (x[i] < tmp_min) + { + tmp_min = x[i]; + min_index = i; + } + /* If two entries have the same value and no clear maximum can be found + set the maximum index to an invalid value */ + else if (x[i] == tmp_min) + { + min_index = -1; + } + } + + return min_index; +} + +/** + * @brief TaMax returns the highest value of a provided array + * @param x Array containing the data to be analysed + * @param n Number of array items + * @return Maximum value of the array + */ +int TaMax (int *x, int n) +{ + int i, tmp_max; + + /* Initialise temporary maximum */ + tmp_max = x[0]; + + /* Iterate over data array */ + for (i=1; i < n; i++) + { + /* If current item is larger than current maximum use it instead */ + if (x[i] > tmp_max) + { + tmp_max = x[i]; + } + } + + return tmp_max; +} + +/** + * @brief Summarise all entries of the provided data array + * @param x Array containing the data to be analysed + * @param n Number of array items + * @return Sum of array items + */ +int TaSum (int *x, int n) +{ + /* sum sums up all entries in x[] */ + + int i, sum; + + sum = 0; + + for (i=0; i < n; i++) + { + sum += x[i]; + } + + return sum; +} + +/** + * @brief Calculate the average value of the items larger than zero in a + * provided array. Zeros are excluded as the function is designed + * to count the average number of matches for identified reference + * bases. Not identified reference bases will have a zero value. + * @param x Array containing the data to be analysed + * @param n Number of array items + * @return Average value of the provided array items + */ +float TaAverage (int *x, int n) +{ + int i, counter, sum; + float average; + /* Initialise variables */ + sum = 0; + counter = 0; + + /* Iterate over array items */ + for (i=0; i < n; i++) + { + /* Ignore zero valued items in the average */ + if (x[i] > 0) + { + sum += x[i]; + counter++; + } + } + + if (counter == 0) + { + /* no data gets an average of 0 */ + average = 0.0f; + } + else + { + average = sum/counter; + } + + return average; +} + +/** + * @brief Calculate the standard deviation for the average value of the items + * in a data array. + * @param x Array containing the data to be analysed + * @param n Number of array items + * @param average Average value of the provided array items + * @return Standard deviation of the provided array items + */ +float TaStdev (int *x, int n, float average) +{ + int i, sum_squares; + float std_dev, counter; + + /* Initialise variables */ + sum_squares = 0; + counter = 0; + + /* Iterate over array items */ + for (i=0; i < n; i++) + { + if (x[i] > 0) + { + sum_squares += ((x[i] - average)*(x[i] - average)); + counter++; + } + } + + /* Check if sufficient data to calculate a standard deviation is available */ + if (counter <= 1) + return 0.0f; + + std_dev = fsqrts((1.0f/(counter-1)) * sum_squares); + + return std_dev; +} + + +#ifdef GROUNDSW +void print_match_info (struct match_results_t *results) +{ + /* print_match_info prints the star tracker, base0 tracker and + * match histogram structures on screen */ + + unsigned int k; + + TA_DEBUG("\n\nStar Tracker\n"); + TA_DEBUG("["); + + for (k=0; k < results->n_ref_pos-1; k++) + { + TA_DEBUG("%d, ", results->star_tracker[k]); + } + + TA_DEBUG("]\n"); + + TA_DEBUG("-------------------------------\n\n"); + + TA_DEBUG("\n\nBase0 Tracker\n"); + TA_DEBUG("["); + + for (k=0; k < results->n_ref_pos-1; k++) + { + TA_DEBUG("%d, ", results->base0_tracker[k]); + } + + TA_DEBUG("]\n"); + + TA_DEBUG("-------------------------------\n\n"); + + + TA_DEBUG("\n\nMatch Histogram\n"); + TA_DEBUG("["); + + for (k=0; k < results->n_ref_pos-1; k++) + { + TA_DEBUG("%d, ", results->match_histogram[k]); + } + + TA_DEBUG("]\n"); + + TA_DEBUG("-------------------------------\n\n"); + + return; +} + + +void print_obs_DB (struct obs_pos_t *obsPos, struct obs_db_t *obs_DB) +{ + /* print_obs_DB prints the contents of the observed database */ + + unsigned int i, j, k, counter; + + counter = 0; + + for (i=0; i < obsPos->n-1; i++) + { + TA_DEBUG("%d ##################################\n", i); + for (j=0; j < obsPos->n-2; j++) + { + TA_DEBUG("%d ----------------------------------\t %d \n", j, obs_DB->base1_index[i*(obsPos->n-2) + j]); + for (k=0; k < obs_DB->base1_data_count[i*(obsPos->n-2) + j]; k++) + { + TA_DEBUG("%d [%d, %d, %d]\n", obs_DB->base1_data_count[i*(obsPos->n-2) + j], obs_DB->data[counter+0], obs_DB->data[counter+1], obs_DB->data[counter+2]); + counter += 3; + } + } + } + + return; +} + + +void print_ref_DB (struct ref_pos_t *ref_pos, struct ref_db_t *ref_DB) +{ + /* print_ref_DB prints the contents of the reference database */ + + int i, j, counter; + counter = 0; + + for (i=0; i < ref_pos->n-1; i++) + { + TA_DEBUG("%d ##################################\n", i); + for (j=0; j < ref_pos->n-2; j++) + { + TA_DEBUG("[%d, %d, %d]\n", ref_DB->data[counter+0], ref_DB->data[counter+1], ref_DB->data[counter+2]); + counter += 3; + } + } + + return; +} +#endif + + + +/***************************************************************** + * * + * MAGNITUDE VALIDATION * + * * + *****************************************************************/ + +/** + * @brief Target Magnitude Validation Acquisition is the main function of the + * Magnitude Validation Algorithm in its standalone acquisition verison. + * It tries to identify the target by performing photometry on the + * observed positions, that are provided by the Star Extraction routine. + * + * @param mva_results Output structure to store the matching results + * @param obs_pos Observed positions that were extracted by the + * Star Extraction process + * @param target_location Intended Target Location provided by ground support + * @param target_candidate_radius Maximum offset from the intended Target Location + * that the target star can have due to platform + * induced pointing errors + * @param img Full frame image data for the current + * observation + * @param target_signal Expected target signal in ADU provided by + * ground support + * @param signal_tolerance Tolerance of the target signal in percent + * @param bkgd_signal Estimated background signal [ADU] + */ +/* NOTE: Do not break these ultra-long parameter lists. We need them for the performance wrappers */ +void target_magntitude_validation_acquisition (struct mva_results_t *mva_results, struct obs_pos_t *obs_pos, float *target_location, int target_candidate_radius, struct img_t *img, unsigned int target_signal, float signal_tolerance, unsigned short bkgd_signal) +{ + float pos1[2], pos2[2]; + float signal_quality; + unsigned int i, j; + int signal, same_target, signal_difference; + + /* Initialise results counter */ + mva_results->n = 0; + + /* Iterate over all observed positions to find all possible target + candidates for later target identification */ + for (i=0; i < obs_pos->n; i++) + { + /* Copy current star position into temporary array */ + pos1[0] = obs_pos->x[i]; + pos1[1] = obs_pos->y[i]; + + /* Check if the current position is within the maximum offset that the + target star can have = target_candidate_radius */ + if (calculate_distance(pos1, target_location) < target_candidate_radius) + { + /* Calculate the star signal */ + signal = perform_radius_photometry (img, pos1[0], pos1[1], bkgd_signal); + + /* target_signal > 0 is ensured by the caller */ + /* Calculate the difference to the estimated target signal [percent] */ + signal_quality = fabsf( (float)(signal-(int)target_signal)/(float)target_signal ) * 100.; + + /* Check if the signal falls within the target signal's tolerance */ + if (signal_quality < signal_tolerance) + { + /* Only continue if the maximum number of target candidates hasn't + been reached yet */ + if (mva_results->n < NCAND) + { + /* Save the position index, the measured signal and + quality for this star */ + mva_results->obs_pos_index[mva_results->n] = i; + mva_results->signal[mva_results->n] = signal; + mva_results->signal_quality[mva_results->n] = signal_quality; + mva_results->n++; + } + else + { + break; + } + } + } + } +#ifdef GROUNDSW + TA_DEBUG("MVA RESULTS N : %d\n", mva_results->n); +#endif + + /* Flag target identification as failed if no target candidate was identified */ + if (mva_results->n == 0) + { + mva_results->valid_signal = FALSE; + mva_results->valid_index = -1; + } + + /* Target identification is successful if only one candidate matched + the expected target signal */ + else if (mva_results->n == 1) + { + mva_results->valid_signal = TRUE; + mva_results->valid_index = 0; + } + + /* If more than one candidate matches the expected signal it might be due + to multiple detections of the same target due to bad detection thresholds + during the Star Extraction process or a second star of similar magnitude + in the FOV. The latter should not happen for properly set parameters.*/ + else if (mva_results->n <= 5) + { + /* Initialise same_target indicator */ + same_target = TRUE; + + /* Iterate over all target candidates */ + for (i=0; i < mva_results->n; i++) + { + /* For each candidate iterate over all the other candidates */ + for (j=0; j < mva_results->n; j++) + { + /* Prevent self pairing */ + if (i != j) + { + /* Store candidate positions in temporary position arrays */ + pos1[0] = obs_pos->x[mva_results->obs_pos_index[i]]; + pos1[1] = obs_pos->y[mva_results->obs_pos_index[i]]; + + pos2[0] = obs_pos->x[mva_results->obs_pos_index[j]]; + pos2[1] = obs_pos->y[mva_results->obs_pos_index[j]]; + + /* Calculate the signal difference in percent points */ + signal_difference = fabsf(mva_results->signal_quality[i] - mva_results->signal_quality[j]); + + /* Calculate the distance between the target candidates. If it is + below 24px they are considered to belong to the same PSF */ + if (calculate_distance(pos1, pos2) > 24) /* PSF diameter = 24 */ + { + same_target = FALSE; + } + /* Photometry results should be very similar for multiple detections + of a single star. If the signal difference is more than 3 percent + points the candidates are not considered to be from the same source. + This check prevents close stars to be paired as one source which + could happen if only the distance criteron was used. */ + if (signal_difference > 3) + { + same_target = FALSE; + } + } + } + } + + /* Identification process is successful if the candidates are identified + to be the same source. The candidate with the maximum signal is + chosen as the final result as the maximum signal will be measured from + the center of the source */ + if (same_target == TRUE) + { + mva_results->valid_signal = TRUE; + /*mva_results->valid_index = TaArgmax(mva_results->signal, mva_results->n);*/ + mva_results->valid_index = TaArgmin(mva_results->signal_quality, mva_results->n); + } + else + { + mva_results->valid_signal = FALSE; + mva_results->valid_index = -1; + } + } + /* If too many target candidates are found the observation will be considered + as too ambiguous and the acquisition is considered failed. This case should + not happen for nominal observations with valid acqusition algorithm + parameters */ + else + { + mva_results->valid_signal = FALSE; + mva_results->valid_index = -1; + } + + return; +} + +/** + * @brief Target Magnitude Validation is used to perform photometry on the + * target acquisition result of the Angle Method Algorithm. It is meant + * for cases where the target star was too faint to solely rely on + * photometric identification and the Angle Method could not identify + * it with a satisfing result. Therfore the Magntiude Validation is + * used as a second level of identification to confirm the ambiguous + * Angle Method result. + * + * @param img Full frame image data for the current + * observation + * @param obs_pos Observed positions that were extracted by the + * Star Extraction process + * @param results utput structure to store the matching results + * @param bkgd_signal Estimated backround signal [ADU] + * @param target_signal Expected target signal in ADU provided by + * ground support + * @param signal_tolerance Tolerance of the target signal in percent + */ + +void target_magnitude_validation (struct img_t *img, struct obs_pos_t *obs_pos, struct match_results_t *results, unsigned short bkgd_signal, unsigned int target_signal, float signal_tolerance) +{ + unsigned int I; + float x, y; + + /* Copy current star position into temporary variables */ + + /* NOTE: The maximum number of obs_pos->candidate_index members is counted in find_target_candidates and assigned to obs_pos->n_candidates. + The members in obs_pos->n_candidates are then used to construct the entries in the observed star database (obs_DB) and results->target_star + is restricted to its length. Therefore results->target_star cannot exceed the array */ + + x = obs_pos->x[obs_pos->candidate_index[results->target_star]]; + y = obs_pos->y[obs_pos->candidate_index[results->target_star]]; + + /* Calculate the star signal */ + I = perform_radius_photometry (img, x, y, bkgd_signal); + + /* target_signal > 0 is ensured by the caller */ + /* Calculate the difference to the estimated target signal [percent] */ + results->signal_quality = fabsf( (float)(I-target_signal)/(float)target_signal ) * 100; + + /* Check if the signal falls within the target signal's tolerance and + decide if the identification was successful */ + if (results->signal_quality < signal_tolerance) + { +#ifdef GROUNDSW + TA_DEBUG("\n\nMagnitude validation successful.\n"); + TA_DEBUG("Measured signal: %d | Expected signal: %d | %.2f percent detected\n\n", I, target_signal, (float)I/target_signal*100.); +#endif + results->valid_signal = TRUE; + } + else + { +#ifdef GROUNDSW + TA_DEBUG("\n\nMagnitude validation failed.\n"); + TA_DEBUG("Measured signal: %d | Expected signal: %d | %.2f percent detected\n\n", I, target_signal, (float)I/target_signal*100.); +#endif + results->valid_signal = FALSE; + } + + return; +} + + +#define RPRANGE 25 +#define RPRADSQ 625 + +/** + * @brief Perform Raidus Photometry extracts the star signal on a radius of + * RPRANGE around the provided position.The signal is corrected + * for the estimated background signal and returned as ADU + * @param img Full frame image data for the current +* observation + * @param cenx X coordinate of the star [CCD pixel] + * @param ceny Y coordinate of the star [CCD pixel] + * @param bkgd_signal Estimated background signal [ADU] + * @return Measured signal [ADU] + */ +int perform_radius_photometry (struct img_t* img, float cenx, float ceny, int bkgd_signal) +{ + int I; + int x, y, n, p, distSq; + int cx, cy; + + cx = roundf(cenx); + cy = roundf(ceny); + + /* Check if the photometry radius is on the image */ + if ((cx - RPRANGE) < 0) + return 0; + if ((cx + RPRANGE) >= TA_XDIM) + return 0; + if ((cy - RPRANGE) < 0) + return 0; + if ((cy + RPRANGE) >= TA_YDIM) + return 0; + + I = 0; + n = 0; + for (y=-RPRANGE; y <= RPRANGE; y++) + { + p = (y+cy) * img->xdim; + for (x=-RPRANGE; x <= RPRANGE; x++) + { + distSq = x*x + y*y; + if (distSq < RPRADSQ) + { + I += img->data[p + x + cx]; + n++; + } + } + } + I -= n*bkgd_signal; + + return I; +} + + + +/** + * @brief Uses the target star position obtained from the Magnitude validation + * Algorithm to calculate the pixel offset to the intended Target Location + * in centipixel [cpx]. The offset is returned by the pointer to the shift + * array. + * @param obs_pos Observed positions that were extracted by the + * Star Extraction process +* @param results Output structure to store the matching results + * @param shift Calculated offset from the Target Location [cpx] + * @param target_location Intended Target Location provided by ground support + */ +void calculate_target_shift_MVA (struct obs_pos_t *obs_pos, struct mva_results_t *results, int *shift, float *target_location) +{ + float x, y, dx, dy; + + /* retrieve x/y coordinates from the observed positions and results */ + + /* NOTE: The maximum number of obs_pos_index members is counted in target_magnitude_validation_acquisition and cannot exceed obs_pos->n. + results->valid_index is guaranteed to be <= obs_pos->n. + The values contained in obs_pos_index are also guaranteed to be <= obs_pos->n and finally obs_pos->x has obs_pos->n members. Same for y. */ + + x = obs_pos->x[results->obs_pos_index[results->valid_index]]; + y = obs_pos->y[results->obs_pos_index[results->valid_index]]; + + /* calculate offset */ + dx = target_location[0] - x; + dy = target_location[1] - y; + + /* conversion to centi-pixel */ + shift[0] = (int)(dx * 100); + shift[1] = (int)(dy * 100); + +#ifdef GROUNDSW + /* Redudant information. Displayed by TargetAcquisitionMain.c */ + /* printf("\nMove satellite by dx: %.2f, dy: %.2f pixel to center it.\n", dx, dy);*/ +#endif + + return; +} diff --git a/TargetAcquisition/src/AngleMethod.h b/TargetAcquisition/src/AngleMethod.h new file mode 100644 index 0000000000000000000000000000000000000000..f7632303e1e4f0a172ef2fe545a745ce7fb358b9 --- /dev/null +++ b/TargetAcquisition/src/AngleMethod.h @@ -0,0 +1,82 @@ +/* + * LiebeMethod.h + * + * Created on: Jul 27, 2015 + * Author: Philipp Löschl, University of Vienna + */ + +#ifndef ANGLEMETHOD_H_ +#define ANGLEMETHOD_H_ + +#include "TaDatatypes.h" + + +void create_obs_DB (struct obs_pos_t *pos, struct obs_db_t *obs_DB, float *target_location, int target_candidate_radius, unsigned short dr); + +void create_ref_DB (struct ref_pos_t *pos, int target_index, struct ref_db_t *ref_DB, unsigned short dr); + +float calculate_dAng (float *x, float *y, unsigned short dr, float theta); + +void stretch_fingerprint (float *x, unsigned short dr); + +void find_target_candidates (struct obs_pos_t *pos, float *target_location, int target_candidate_radius); + +float TaNorm (float x, float y); + +void match_databases (struct ref_db_t *ref_DB, struct obs_db_t *obs_DB, struct match_results_t *results); + +void find_base0 (unsigned int ref_base0, struct match_candidates_t *candidates, struct obs_db_t *obs_DB); + +void find_base1 (unsigned int ref_base1, struct match_candidates_t *candidates, struct obs_db_t *obs_DB); + +void find_matches (unsigned int ref_base0, unsigned int ref_base1, unsigned int ref_angle, struct match_candidates_t *candidates, struct match_results_t *results, struct obs_db_t *obs_DB); + +void find_unique_matches (struct match_results_t *results, struct unique_output_t *output, int match_count_index, int match_results_index, int entry); + +void find_majority_matches (struct match_results_t *results); + +void find_unique_tracker_items (int *tracker, unsigned int n, struct unique_output_t *output, unsigned int n_skip, unsigned int *skip_entries); + +void correct_multiple_base_matches (struct match_results_t *results); + +void find_valid_star_candidate (struct match_results_t *results); + +void determine_match_quality (struct match_results_t *results, struct obs_pos_t *obs_pos); + +void calculate_target_shift_AMA (struct obs_pos_t *obs_pos, struct match_results_t *results, int *shift, float *target_location); + +void TaUnique (struct unique_output_t *output, int item); + +void TaWhere (int *x, unsigned int n, struct where_output_t *output, int arg, int operator); + +void delete_results (struct match_results_t *results, unsigned int match_count_index, unsigned int match_results_index, unsigned int entry); + +int selective_counter (int *x, int n, int arg); + +int TaArgmax (int *x, int n); + +int TaArgmin (float *x, int n); + +int TaMax (int *x, int n); + +int TaSum (int *x, int n); + +float TaAverage (int *x, int n); + +float TaStdev (int *x, int n, float average); + +void print_match_info (struct match_results_t *results); + +void print_obs_DB (struct obs_pos_t *obsPos, struct obs_db_t *obs_DB); + +void print_ref_DB (struct ref_pos_t *ref_pos, struct ref_db_t *ref_DB); + +void target_magntitude_validation_acquisition (struct mva_results_t *mva_results, struct obs_pos_t *obs_pos, float *target_location, int target_candidate_radius, struct img_t *img, unsigned int target_signal, float signal_tolerance, unsigned short bkgd_signal); + +void target_magnitude_validation (struct img_t *img, struct obs_pos_t *obs_pos, struct match_results_t *results, unsigned short bkgd_signal, unsigned int target_signal, float signal_tolerance); + +int perform_radius_photometry (struct img_t *img, float cenx, float ceny, int bkgd_signal); + +void calculate_target_shift_MVA (struct obs_pos_t *obs_pos, struct mva_results_t *results, int *shift, float *target_location); + +#endif /* ANGLEMETHOD_H_ */ diff --git a/TargetAcquisition/src/CrIaDataPool.c b/TargetAcquisition/src/CrIaDataPool.c new file mode 120000 index 0000000000000000000000000000000000000000..2a5e2301749c3de063ffc660476ec625c17e33a4 --- /dev/null +++ b/TargetAcquisition/src/CrIaDataPool.c @@ -0,0 +1 @@ +../../CrIa/src/CrIaDataPool.c \ No newline at end of file diff --git a/TargetAcquisition/src/CrIaDataPool.h b/TargetAcquisition/src/CrIaDataPool.h new file mode 120000 index 0000000000000000000000000000000000000000..59f98e9ce51738b6c6927f07551d03186d0360a8 --- /dev/null +++ b/TargetAcquisition/src/CrIaDataPool.h @@ -0,0 +1 @@ +../../CrIa/src/CrIaDataPool.h \ No newline at end of file diff --git a/TargetAcquisition/src/CrIaDataPoolId.h b/TargetAcquisition/src/CrIaDataPoolId.h new file mode 120000 index 0000000000000000000000000000000000000000..2d0c8070bf1f9ce951520883b7748337970f0569 --- /dev/null +++ b/TargetAcquisition/src/CrIaDataPoolId.h @@ -0,0 +1 @@ +../../CrIa/src/CrIaDataPoolId.h \ No newline at end of file diff --git a/TargetAcquisition/src/IfswConversions.c b/TargetAcquisition/src/IfswConversions.c new file mode 120000 index 0000000000000000000000000000000000000000..b61b15f15dacbf2d12fa035977840b6ceb4ca08c --- /dev/null +++ b/TargetAcquisition/src/IfswConversions.c @@ -0,0 +1 @@ +../../CrIa/src/IfswConversions.c \ No newline at end of file diff --git a/TargetAcquisition/src/IfswConversions.h b/TargetAcquisition/src/IfswConversions.h new file mode 120000 index 0000000000000000000000000000000000000000..a2674b8bb1759871048b6c7458b5a46875777abe --- /dev/null +++ b/TargetAcquisition/src/IfswConversions.h @@ -0,0 +1 @@ +../../CrIa/src/IfswConversions.h \ No newline at end of file diff --git a/TargetAcquisition/src/StarExtractor.c b/TargetAcquisition/src/StarExtractor.c new file mode 100644 index 0000000000000000000000000000000000000000..c9ebb79802fe0030d10b6c5218b7994a30eab640 --- /dev/null +++ b/TargetAcquisition/src/StarExtractor.c @@ -0,0 +1,822 @@ +/** +* @file StarExtractor.c +* @author Philipp Löschl (roland.ottensamer@univie.ac.at) +* @date July, 2017 +* +* @defgroup StarExtraction Star Extraction +* @ingroup TargetAcquisition +* +* @brief The Star Extraction algorithm detects star positions on the full frame image and is the preceding step for any kind of @ref TargetAcquisition algorithm. +* +* ## Overview +* The Star Extraction is the first step for every algorithm in the +* @ref TargetAcquisition "Target Acquisition" routine. Its main task is to +* detect stars and measure their positions on the full frame images in CCD +* pixel coordinates. These positions are a crucial prerequisite for every +* subsequent type of target identification algorithm. +* +* ## Mode of Operation +* To achieve the above described task the Star Extraction is not only provided +* with the full frame image data but also uses observation specific information +* such a detection threshold for individual pixels, a detection threshold for +* the full signal in the PSF and an +* @ref calculate_background_signal "estimated background signal". +* The detailed process is outlined below. +* +* ### Image Rebinning +* Due to constraints in processing power and runtime the full frame image is +* rebinned by a factor 8 on both axis for further use by the Star Extraction. +* This reduces overall memory usage and increases the speed of any iteration +* over all image pixels in the following work steps by a factor of 64. In +* addition it concentrates the spread out PSF of the stars to a more compact +* signal distribution within approximately 3 x 3 pixel.\n +* (@ref rebin_image "Rebin Image Source Code") +* +* ### Find Pixel of Interest +* The rebinned image is then scanned for pixels that exceed the +* pixel detection threshold. This threshold is determined by the minimal fraction +* of the star signal that can be contained in a rebinned pixel. +* The coordinates of all eligible pixels are stored as pixel of interest (POI) +* for further processing.\n +* +* Additional functionality to reduce the scanned area to a circular subframe of +* predefined radius around the expected target location is also available in +* form of the __reduced extraction radius__. Although it is not used for nominal +* observation conditions, it can become necessary for very crowded or highly +* rotating FOV.\n Observations of very faint targets often come with higher +* star densities and hence an increased number of detected star positions. Since +* the reserved memory is designed to only hold 60 positions, the maximum number +* of star detections has to be limited. While this can usually be done with +* increased detection thresholds, it is not always possible for observations of +* very faint stars. Therefore the area on which the Star Extraction operates is +* decreased instead.\n +* +* For highly rotated FOV with long exposure times the outer stars will be +* smeared over extended areas of the image. Since this can introduce large +* position errors that interfere with the identification algorithms, it is +* recommended to also use the reduced extraction radius for such cases.\n +* (@ref find_pixel_of_interest "Find Pixel of Interest Source Code") +* +* ### Group Pixel of Interest I +* +* The detection threshold per pixel is defined such that multiple pixels will be +* detected for many of the brighter stars' signal distribution. This behaviour +* is a result of the threshold definition, which is based on the faintest +* detectable magnitude to trigger at least one pixel of interest in a specific +* observation. To avoid multiple detections of single stars it is +* necessary to reduce the pixel of interest to one per object. Therefore +* closeby pixel within a region of the typical rebinned PSF are grouped together. +* Assuming a 3 x 3 pixel PSF with all 9 pixel identified as POI, a distance +* threshold of two pixel separation for the x and y direction is required to +* group pixels starting at the corners of a 3 x 3 square PSF.\n +* +* Due to the row wise scanning process in the previous step all POI are already +* sorted after their coordinates, which minimizes memory access during for the +* grouping algorithm. Initially all POI are assigned to group -1, which indicates +* that they are not grouped yet. Then starting with the first, each POI position +* is compared to all following ungrouped positions in the POI list. If their +* separation is below the distance threshold they are assigned to the same group. +* This process repeats until each POI has been assigned to a group and conserves +* the order of the POI list. \n +* (@ref group_pixel_of_interest "Group Pixel of Interest Source Code") +* +* ### Reduce Group to Average Pixel of Interest +* With every POI assigned to a group and therefore a specific star, each group of +* POI can now be reduced to a single pixel per object. Iterating over all +* available groups, the POI list is scanned for the pixels associated with the +* respective group. Each group's pixel coordinates are then averaged to a single +* and central POI. As a result of this operation most star locations are now +* described by a single POI.\n +* (@ref reduce_to_average_pixel_of_interest "Reduce to Average Pixel of Interest Source Code") +* +* ### Group Pixel of Interest II +* Long exposure times for bright stars can trigger the POI on larger areas than +* the expected 3 x 3 pixel field. This can causes multiple groups of POI to +* describe a single star even after the reduction in the previous step. To avoid +* multiple detections of a single star and the associated degradation of the +* identification algorithm results, the grouping process is repeated. Considering +* that every uniquely identified star should have its POI centered at this stage, +* a more rigorous separation criteria of four pixels is used. Other than that the +* grouping process is identical to its first iteration.\n +* (@ref group_pixel_of_interest "Group Pixel of Interest Source Code") +* +* ### Reduce Group to Brightest Pixel of Interest +* The second POI reduction process is slightly different to the first one. Instead +* of averaging the POI positions for each group, the pixel signals are considered +* now. This is superior to geometric averaging due to the changed nature of the +* remaining pixels. While the first grouping process is meant to work with POI that +* are spread all over the PSF, the distribution after the first reduction is +* different. If a star is described by multiple groups at this point, it most +* likely has one group with a POI in its centre and a second group with POI on +* the outer edge. Since the signal is concentrated in the central region of the +* rebinned PSF it is the better indicator to find the best POI. Averaging the +* position instead would introduce a systematic positional offset for such cases. +* \n +* The algorithm iterates over all available groups and sorts the available POI +* by their signal. Before the brightest POI is chosen the signal of the pixel located +* between the two brightest ranked pixels is also considered. The overall brightest +* pixel in this comparison is used as the new POI while the rest is discarded. +* \n +* The whole second iteration of the grouping and reduction process provides a +* single POI per star for nominal cases. The remaining cases include saturated +* field stars and overlapping bright stars in situations of high star density. +* Even though those scenarios are rare, they might occur once or twice per image. +* Therefore the subsequent target identifcation algorithms are designed to be +* robust against small numbers of multiple detections per object.\n +* (@ref reduce_to_brightest_pixel_of_interest +* "Reduce to Brightest Pixel of Interest Source Code") +* +* ### Calculate Center of Gravity +* The final step of the Star Extraction routine uses the previously selected +* pixels of interest (POI) to determine star positions by calculating the centres of +* gravity in a region of interest (ROI) around them.\n +* Therefore the signal barycentre on a square region around the POI +* [x-2:x+2, y-2:y+2] is calculated on a subpixel scale. Before the calculated +* position can be converted back to full frame coordinates the total signal in the +* region of interest is checked against the detection threshold for the full PSF. +* This is meant to prevent false postive detections of intense cosmic rays, +* as well as detections of stars below the desired magnitude on which the +* threshold was based. The latter is possible when the combined signals of +* overlapping faint stars or cosmic rays and faint stars satisfy the signal +* criteria to be considered a pixel of interest. Even though the results might +* be valid star positions, they must not be considered in the target identification +* algorithm input data as they could degrade the identification results. +* Positions of all stars that pass the signal check are converted back to full +* resolution positions and are made available outside Star Extraction through the +* @ref obs_pos_t "observed positions structure".\n +* (@ref calculate_center_of_gravity "Calculate Center of Gravity Source Code") +* +* ### Visualisation +* A step wise visualisation of the Star Extraction process for a single star +* is provided below (top left to bottom right): +* - Starting with the full resolution image (top left), the image data is +* rebinned and scanned for pixels of interest (top centre). +* - Two groups of POI are formed. One contains the yellow bottom left 3x3 pixels +* from [62,62] to [64,64] and the other the remaining blue pixels +* around the corner from [63, 65] left to [65,65] down to [65, 63] +* (top centre). +* - The two groups are reduced to two pixel of interest. Note that the +* average position of the corner group moved into the area of the +* square group. This behaviour favours group reduction for multiply +* detected single objects. (top right) +* - After the second grouping and reduction process only one POI (red dot) +* remains at [64, 64]. It is used to span the region of interest (red square) +* for the centre of gravity calculation (bottom left). +* - The centre of gravity on the rebinned frame is located at +* [63.57, 63.57] (bottom centre). +* - Transformation to full resolution coordinates gives [512.55, 512.54] +* (bottom right). +* +* Test data: Target Star, 9mag 10s medium crowded field, CHEOPSim Job 4223 +* @image html star_extraction_process.png "Star Extraction Process" +*/ + + +#include <stdlib.h> +#include <stdio.h> + +#include "TaDatatypes.h" +#include "StarExtractor.h" +#include "AngleMethod.h" +#include "TargetAcquisition.h" +#include "IfswMath.h" +#include "EngineeringAlgorithms.h" + +extern struct where_output_t *g_glitch_filter; + + +/***************************************************************** + * * + * STAR EXTRACTION * + * * + *****************************************************************/ + +/** + * @brief Star Extraction main function + * @param img contains 1024x1024 px full frame image data + * @param pos initialised structure to store detected star positions + * @param rebin_factor to resize the image + * @param target_location expected target star position + * @param reduced_extraction toggles use of extraction_radius + * @param extraction_radius a reduced extraction_radius to run Star Extraction on a circular subframe of the image + * @param detection_thld detection threshold in ADU/s per pixel + * @param signal_thld detection threshold in ADU/s for the full PSF + * @param bkgd_signal calculated background signal in ADU/s + * @param POI initialised structure to store pixel of interest + * @note + */ + +/* NOTE: Do not break the long parameter list. It is needed for the performance wrappers */ + +void star_extraction (struct img_t *img, struct obs_pos_t *pos, unsigned short rebin_factor, float *target_location, unsigned short reduced_extraction, unsigned short extraction_radius, unsigned int detection_thld, unsigned int signal_thld, unsigned int bkgd_signal, struct ROI_t *POI) +{ + /* This function bins the passed image and extracts positions of found stars. + * The center of gravity calculation for the star positions are done with a + * background noise calculated locally over the ROI adjacent pixels. + * It is meant for the position extraction in the space segment + * The term Region Of Interest (ROI) is commonly used for the central ROI pixel + */ + int step, ROI_radius; + float target_location_bin[2]; + + target_location_bin[0] = target_location[0] / rebin_factor; /* REBIN_FACTOR = 8 */ + target_location_bin[1] = target_location[1] / rebin_factor; /* REBIN_FACTOR = 8 */ + + extraction_radius = extraction_radius / rebin_factor; /* REBIN_FACTOR = 8 */ + + /* imgBin is only used in this function. Hence no memory allocation outside of it */ + g_imgBin->xdim = img->xdim / rebin_factor; /* REBIN_FACTOR = 8 */ + g_imgBin->ydim = img->ydim / rebin_factor; /* REBIN_FACTOR = 8 */ + + bkgd_signal = bkgd_signal * rebin_factor * rebin_factor; + + detection_thld += bkgd_signal; + step = 1; + ROI_radius = 2; /* NOTE: with rebin_factor fixed to 8 this = 2 */ + POI->counter = 0; /* counts the number of possible ROIs */ + + rebin_image(img, g_imgBin, rebin_factor); + + find_pixel_of_interest (g_imgBin, POI, reduced_extraction, extraction_radius, target_location_bin, detection_thld, step); + + if (POI->counter == 0) + { + pos->n = 0; + return; + } + /* + If e.g. the exposure time is wrong, then it may happen that too many point sources are found + and the acquisition takes too long. Here we protect against that case. 100 stars, 4*4 POIs per star. + */ + if (POI->counter > 1600) + { + pos->n = 0; + return; + } + + group_pixel_of_interest (POI, ROI_radius); + + reduce_to_average_pixel_of_interest (POI); + + group_pixel_of_interest (POI, 2*ROI_radius); + + reduce_to_brightest_pixel_of_interest (POI, g_imgBin); + + calculate_center_of_gravity (pos, POI, g_imgBin, bkgd_signal, signal_thld, ROI_radius, rebin_factor); + + return; +} + +/** + * @brief Calculates the background signal in dependance on exposure time, bias, dark and mean sky background + * @param exposure_time exposure time in seconds + * @param bias bias signal in ADU + * @param dark_mean mean dark signal in ADU/s + * @param sky_bkgd mean sky background signal in aDU + + * @note + */ +int calculate_background_signal (float exposure_time, float bias, float dark_mean, float sky_bkgd) +{ + /* sky_bkgd in ADU: photons/s * gain * flat */ + + return (int) (bias + exposure_time * (sky_bkgd + dark_mean)); +} + + +/** + * Due to constraints in processing power and runtime the full frame image is + * rebinned by a factor 8 on both axis for further use by the Star Extraction. + * This reduces overall memory usage and increases the speed of any iteration + * over all image pixels in the following work steps by a factor of 64. In + * addition it concentrates the spread out PSF of the stars to a more compact + * signal distribution within approximately 3 x 3 pixel. + * + * @brief Resizes an image by a provided factor + * @param img stores full sized image prior to rebinning + * @param imgBin stores rebinned image + * @param rebin_factor factor by which the image is rebinned + + * @note + */ +void rebin_image (struct img_t* img, struct imgBin_t* imgBin, unsigned short rebin_factor) +{ + /* This functions bins the passed image by the the also passed rebin_factor */ + unsigned int i, j, k, l; + unsigned int tmpADU; + + /* Check if the rebin_factor is a multiple for the image dimensions */ + if (img->xdim % rebin_factor || img->ydim % rebin_factor) + { + rebin_factor = 1; + } + + /* Place a grid with reduced dimensions over the full sized data + * array and iterate over its super cells. Sum up all data points + * of the original full sized grid within each of those super cells. + */ + + for (k=0; k < imgBin->ydim; k++) + { + for (l=0; l < imgBin->xdim; l++) + { + tmpADU = 0; + for (i=0; i<rebin_factor; i++) + { + for (j=0; j<rebin_factor; j++) + { + tmpADU += img->data[(i + k*rebin_factor) * img->xdim + (j + l*rebin_factor)]; + } + } + imgBin->data[k * imgBin->xdim + l] = tmpADU; + } + } + + return; +} + +/** + * The rebinned image is then scanned for pixels that exceed the + * pixel detection threshold. This threshold is determined by the minimal fraction + * of the star signal that can be contained in a rebinned pixel. + * The coordinates of all eligible pixels are stored as pixel of interest (POI) + * for further processing.\n + * + * Additional functionality to reduce the scanned area to a circular subframe of + * predefined radius around the expected target location is also available in + * form of the __reduced extraction radius__. Although it is not used for nominal + * observation conditions, it can become necessary for very crowded or highly + * rotating FOV. + * + * @brief Attempts to find pixel over a certain detection threshold to be used as pixel of interest by subsequent functions + * @param imgBin rebinned image + * @param POI structure to store pixel of interest (POI) + * @param reduced_extraction toggles reduced extraction mode + * @param extraction_radius defines search radius for reduced extraction mode + * @param target_location_bin expected target location in rebinned coordinates + * @param detection_thld detection threshold in ADU/s per pixel + * @param step step size for POI search + + * @note + */ +void find_pixel_of_interest (struct imgBin_t *imgBin, struct ROI_t *POI, int reduced_extraction, int extraction_radius, float *target_location_bin, unsigned int detection_thld, int step) +{ + /* Scan the rebinned image in imgBin for pixels with a + * signal above the detection threshold and store them as + * a first selection of region of interest centre in POI. + */ + + unsigned int i, j; + float tmp_pos[2]; + + /* Only scan reduced extraction area defined by the extraction radius for POI */ + if (reduced_extraction == TRUE) + { + for (i=0; i < imgBin->ydim; i+=step) + { + for (j=0; j < imgBin->xdim;j+=step) + { + if (imgBin->data[i * imgBin->xdim + j] > detection_thld) + { + tmp_pos[1] = i; /* y */ + tmp_pos[0] = j; /* x */ + + if (calculate_distance(tmp_pos, target_location_bin) < extraction_radius) + { + if (POI->counter < NROI) + { + POI->y[POI->counter] = i; + POI->x[POI->counter] = j; + POI->counter++; + } + else + { + /* Don't add more positions than defined by NROI */ + return; + } + } + } + } + } + } + else + /* Scan the whole area for POI */ + { + for (i=0; i < imgBin->ydim; i+=step) + { + for (j=0; j < imgBin->xdim; j+=step) + { + if (imgBin->data[i * imgBin->xdim + j] > detection_thld) + { + if (POI->counter < NROI) + { + POI->y[POI->counter] = i; + POI->x[POI->counter] = j; + POI->counter++; + } + else + { + /* Don't add more positions than defined by NROI */ + return; + } + } + } + } + + } + + return; +} + +/** + * @brief Calculates the distance between two positions in pixel + * @param pos1 first position, 2D array + * @param pos2 second position, 2D array + + * @note + */ +float calculate_distance (float *pos1, float *pos2) +{ + float distance; +#if (__sparc__) + distance = fsqrts ((pos1[0] - pos2[0]) * (pos1[0] - pos2[0]) + (pos1[1] - pos2[1]) * (pos1[1] - pos2[1])); +#else + distance = (float) sqrt ((pos1[0] - pos2[0]) * (pos1[0] - pos2[0]) + (pos1[1] - pos2[1]) * (pos1[1] - pos2[1])); +#endif + + return distance; +} + +/** + * Due to the row wise scanning process in the previous step all POI are already + * sorted after their coordinates, which minimizes memory access during for the + * grouping algorithm. Initially all POI are assigned to group -1, which indicates + * that they are not grouped yet. Then starting with the first, each POI position + * is compared to all following ungrouped positions in the POI list. If their + * separation is below the distance threshold they are assigned to the same group. + * This process repeats until each POI has been assigned to a group and conserves + * the order of the POI list. + * + * @brief Groups previously identified adjacent and spacially close pixel of interest together + * @param POI structe to store pixel of interest + * @param ROI_radius distance limit from which pixel are grouped separatly + + * @note + */ +void group_pixel_of_interest (struct ROI_t* POI, int ROI_radius) +{ + unsigned int i, j, k, skip_index; + int dx, dy; + + POI->group_counter = 0; /* Index for the multiple hit ROI grouping */ + POI->skip_counter = 0; + + for(i=0; i < POI->counter; i++) /* Initialise group indices */ + POI->group[i] = -1; /* Stores the ROI group index for each entry */ + + for (i=0; i < POI->counter; i++) /* Loops over all possible ROI centres previously found */ + { + skip_index = FALSE; + + for (k=0; k < POI->skip_counter; k++) + { + if (i == POI->skip_index[k]) + { + skip_index = TRUE; + break; + } + } + + if (skip_index == TRUE) + continue; + + if (POI->group[i] < 0) /* Assign new index if it doesn't have one yet */ + { + POI->group[i] = POI->group_counter; + POI->group_counter++; + } + + for (j=i+1; j < POI->counter; j++) /* Check remaining ROI are adjacent */ + { + dy = POI->y[i] - POI->y[j]; + if (abs(dy) <= ROI_radius) + { + dx = POI->x[i] - POI->x[j]; + if (abs(dx) <= ROI_radius) + { + if (POI->group[j] < 0) + { + /* If distance criteria is met, assign the same index */ + POI->group[j] = POI->group[i]; + POI->skip_index[POI->skip_counter] = j; + POI->skip_counter++; + } + } + } + else + /* if the entry isn't adjacent in the y + * direction no further will be either */ + break; + } + } + + return; +} + + +/** + * With every POI assigned to a group and therefore a specific star, each group of + * POI can now be reduced to a single pixel per object. Iterating over all + * available groups, the POI list is scanned for the pixels associated with the + * respective group. Each group's pixel coordinates are then averaged to a single + * and central POI. As a result of this operation most star locations are now + * described by a single POI.\n + * + * @brief Reduces spacially close and grouped pixel of interest to a center of gravity weighed single pixel + * @param POI structure that stores pixel of interest + + * @note + */ +void reduce_to_average_pixel_of_interest (struct ROI_t* POI) +{ + unsigned int i, j, group_member_counter; + float group_x, group_y; + + for (j=0; j < POI->group_counter; j++) /* scan through all groups */ + { + group_member_counter = 0; + group_x = 0; + group_y = 0; + + for (i=0; i < POI->counter; i++) /* look for all POIs within current group j */ + { + if (POI->group[i] == (int)j) + { + group_member_counter++; /* count the amount of temporarily stored members*/ + group_x += POI->x[i]; + group_y += POI->y[i]; + } + } + + if (group_member_counter > 0) /* Mantis 2267, even though gmc > 0 is ensured indirectly in the caller */ + { + temp_POI->x[j] = (int) roundf(group_x / group_member_counter); + temp_POI->y[j] = (int) roundf(group_y / group_member_counter); + } + } + + temp_POI->counter = POI->group_counter; /* number of groups stays the same */ + + *POI = *temp_POI; /* Mantis 2268: shallow copy is sufficient, because the structure's arrays reside in a global RAM */ + + + return; +} + +/** + * The algorithm iterates over all available groups and sorts the available POI + * by their signal. Before the brightest POI is chosen the signal of the pixel located + * inbetween the two brightest ranked pixels is also considered. The overall brightest + * pixel in this comparison is used as the new POI while the rest is discarded. + * + * @brief Reduces spacially close and grouped pixel of interest to their brightest group member + * @param POI structure that stores pixel of interest + * @param imgBin rebinned version of the image data + + * @note + */ +void reduce_to_brightest_pixel_of_interest (struct ROI_t *POI, struct imgBin_t *imgBin) +{ + /* Scan each indexed temporary POI group to look for the brightest pixel. + * This is done by creating a sorting the group members after their signal + * so the brightest pixel can be chosen. Before doing so, the pixel between + * the two brightest group members is also checked for a possible higher + * signal and then used instead if that's the case. + */ + + unsigned int i, j; + int k, x, y, dx, dy; + int group_member[NROI], group_member_counter; + unsigned int brightness[NROI]; + + for (j=0; j < POI->group_counter; j++) /* scan through all groups */ + { + group_member_counter = 0; + + for(i=0; i < POI->counter; i++) /* look for all POIs within current group j */ + { + if (POI->group[i] == (int)j) + { + group_member[group_member_counter] = i; /* temporarily store all group members */ + brightness[group_member_counter] = imgBin->data[POI->y[i] * imgBin->xdim + POI->x[i]]; + group_member_counter++; /* count the amount of temporarily stored members */ + } + } + + sort_group_after_brightest_pixel (group_member, brightness, group_member_counter); + + if (group_member_counter > 1) + { + /* the first member now is the brightest */ + dy = POI->y[group_member[0]] - POI->y[group_member[1]]; + dx = POI->x[group_member[0]] - POI->x[group_member[1]]; + y = POI->y[group_member[0]]; + x = POI->x[group_member[0]]; + + if ((imgBin->data[((y - dy/2) * imgBin->xdim ) + (x - dx/2)]) > (imgBin->data[(y * imgBin->xdim ) + x])) + { + temp_POI->y[j] = y - dy/2; /* add this member to the new POI structure */ + temp_POI->x[j] = x - dx/2; + } + else + { + /* Brightest pixel in candidate list is brighter than intermediate pixel */ + k = group_member[0]; + temp_POI->x[j] = POI->x[k]; /* add this member to the new POI structure */ + temp_POI->y[j] = POI->y[k]; + } + } + else + { + /* Only one entry available? -> just use it */ + + /* NOTE: there are POI->group_counter members to group_member[], so if the array has no member, then + this loop will not be entered. Consequently, at least the first group member is initialized here. */ + k = group_member[0]; + temp_POI->x[j] = POI->x[k]; /* add this member to the new POI structure */ + temp_POI->y[j] = POI->y[k]; + } + } + + temp_POI->counter = POI->group_counter; /* number of groups stays the same */ + + *POI = *temp_POI; /* Mantis 2268: shallow copy is sufficient, because the structure's arrays reside in a global RAM */ + + + return; +} + +/** + * @brief Sorts a group of pixel of interest by their brightness (descending) + * @param group_member countains the indices of all POI belonging to the currently analysed group + * @param brightness contains the pixel signal for each POI in the currently analysed group + * @param group_member_counter number of POI for the currently analysed group + + * @note + */ +void sort_group_after_brightest_pixel (int *group_member, unsigned int *brightness, int group_member_counter) +{ + int i, j, tmp_brightness, tmp_group_member; + + for(i=0; i < group_member_counter-1; i++) + { + for(j=i+1; j < group_member_counter; j++) + { + if (brightness[i] < brightness[j]) + { + /* swap elements */ + tmp_brightness = brightness[i]; + brightness[i] = brightness[j]; + brightness[j] = tmp_brightness; + + tmp_group_member = group_member[i]; + group_member[i] = group_member[j]; + group_member[j] = tmp_group_member; + } + } + } + + return; +} + +/** + * The final step of the Star Extraction routine uses the previously selected + * pixels of interest (POI) to determine star positions by calculating the centres of + * gravity in a region of interest (ROI) around them.\n + * Therefore the signal barycentre on a square region around the POI + * [x-2:x+2, y-2:y+2] is calculated on a subpixel scale. Before the calculated + * position can be converted back to full frame coordinates the total signal in the + * region of interest is checked against the detection threshold for the full PSF. + * This is meant to prevent false postive detections of intense cosmic rays, + * as well as detections of stars below the desired magnitude on which the + * threshold was based. Positions of all stars that pass the signal check are converted back to full + * resolution positions and are made available outside Star Extraction through the + * @ref obs_pos_t "observed positions structure".\n + * + * @brief Calculates the center of gravity in a region of interest (ROI) around a pixel of interest (POI) and stores the result as detected star position + * @param pos structure to store the star positions calculated from the ROI around each POI + * @param POI structure to store the pixel of interest + * @param imgBin contains the rebinned + * @param bkgd_signal calculated background signal in ADU/s per pixel + * @param signal_thld detection threshold in ADU/s for the full PSF + * @param ROI_radius region of interest (ROI) radius to calculate the center of gravity around a pixel of interest (POI) + * @param rebin_factor rebinning factor by which the full frame image was resized + + * @note + */ +void calculate_center_of_gravity (struct obs_pos_t *pos, struct ROI_t *POI, struct imgBin_t *imgBin, unsigned int bkgd_signal, unsigned int signal_thld, int ROI_radius, unsigned short rebin_factor) +{ + /* Use the found ROI in ROI.ROI to calculate their centers of gravity. + * Once done transform the results back to the full scale image. + * Note that the pixels have to be shifted by half the scale factor + * due to how the rebinning process shifted pixels in the beginning. + */ + + unsigned int i; + int I, Ipx; + int x, y, xu, xl, yu, yl, X, Y; + double x_bin, y_bin; + + pos->n = 0; + + for (i=0; i < POI->counter; i++) + { + /* Define dimensions of the ROI */ + yu = POI->y[i] + ROI_radius; + yl = POI->y[i] - ROI_radius; + xu = POI->x[i] + ROI_radius; + xl = POI->x[i] - ROI_radius; + + /* Initialize CoG variables */ + X = 0; + Y = 0; + I = 0; + + /* Check if ROI is within the image, adjust if necessary */ + if (yl < 0) + yl = 0; + if ((unsigned int)yu > (imgBin->ydim-1)) + yu = imgBin->ydim-1; + if (xl < 0) + xl = 0; + if ((unsigned int)xu > (imgBin->xdim-1)) + xu = imgBin->xdim-1; + + /* Loop over all pixels within the ROI to sum up the signal */ + for (y=yl; y <= yu; y++) + { + for(x=xl; x <= xu; x++) + { + Ipx = (int)(imgBin->data[y* imgBin->xdim + x]) - (int)bkgd_signal; + + if (Ipx < 0) + Ipx = 0; + + X += Ipx * x; /* weigh pixels with their position */ + Y += Ipx * y; + I += Ipx; /* sum of total intensity in ROI */ + } + } + + /* Calculate Center of Gravity */ + if (I > 0) + { + y_bin = (double)Y/I; + x_bin = (double)X/I; + + /* Check if the star signal is above the signal threshold */ + + /* Define dimensions of the signal ROI */ + yu = (int)y_bin + ROI_radius; + yl = (int)y_bin - ROI_radius; + xu = (int)x_bin + ROI_radius; + xl = (int)x_bin - ROI_radius; + + if (yl < 0) + yl = 0; + if ((unsigned int)yu > (imgBin->ydim-1)) + yu = imgBin->ydim-1; + if (xl < 0) + xl = 0; + if ((unsigned int)xu > (imgBin->xdim-1)) + xu = imgBin->xdim-1; + + /* Initialize CoG variables */ + I = 0; + for (y=yl; y <= yu; y++) + { + for(x=xl; x <= xu; x++) + { + I += ((int)imgBin->data[y * imgBin->xdim + x] - (int)bkgd_signal); /* sum of total intensity in ROI */ + } + } + + if (I > (int)signal_thld) + { + if (pos->n < NPOS) + { + pos->y[pos->n] = y_bin * rebin_factor + rebin_factor/2; + pos->x[pos->n] = x_bin * rebin_factor + rebin_factor/2; + pos->n++; + } + else + { + /* Don't add more positions than defined by NPOS */ + return; + } + } + } + } + + return; +} diff --git a/TargetAcquisition/src/StarExtractor.h b/TargetAcquisition/src/StarExtractor.h new file mode 100644 index 0000000000000000000000000000000000000000..279beb929c02b513eb437e06c72068071e7ed40a --- /dev/null +++ b/TargetAcquisition/src/StarExtractor.h @@ -0,0 +1,40 @@ +/* + * StarExtractor.h + * + * Created on: Jul 24, 2015 + * Author: Philipp Löschl, University of Vienna + */ + +#ifndef STAREXTRACTOR_H_ +#define STAREXTRACTOR_H_ + + +#include "TaDatatypes.h" + +void calculate_center_of_gravity (struct obs_pos_t *pos, struct ROI_t *POI, struct imgBin_t *imgBin, unsigned int bkgd_signal, unsigned int signal_thld, int ROI_radius, unsigned short rebin_factor); + +float calculate_distance (float *pos1, float *pos2); + +void find_pixel_of_interest (struct imgBin_t *imgBin, struct ROI_t *POI, int reduced_extraction, int extraction_radius, float *target_location_bin, unsigned int detection_thld, int step); + +void group_pixel_of_interest (struct ROI_t *POI, int ROI_radius); + +void readImgFromTxt (struct img_t *img); + +void readRefPosFromTxt (struct ref_pos_t *pos); + +void rebin_image (struct img_t *img, struct imgBin_t *imgBin, unsigned short rebin_factor); + +void reduce_to_brightest_pixel_of_interest (struct ROI_t *POI, struct imgBin_t *imgBin); + +void reduce_to_central_pixel_of_interest (struct ROI_t *POI); + +void reduce_to_average_pixel_of_interest (struct ROI_t *POI); + +void sort_group_after_brightest_pixel (int *group_member, unsigned int *brightness, int group_member_counter); + +void star_extraction (struct img_t *img, struct obs_pos_t *pos, unsigned short rebin_factor, float *target_location, unsigned short reduced_extraction, unsigned short extraction_radius, unsigned int detection_thld, unsigned int signal_thld, unsigned int bkgd_signal, struct ROI_t *POI); + +int calculate_background_signal (float exposure_time, float bias, float dark_mean, float sky_bkgd); + +#endif /* STAREXTRACTOR_H_ */ diff --git a/TargetAcquisition/src/StarPosDistortCorr.c b/TargetAcquisition/src/StarPosDistortCorr.c new file mode 100644 index 0000000000000000000000000000000000000000..bb6736d1862e77fa5f5ec7c3b1f2a2de069e8f62 --- /dev/null +++ b/TargetAcquisition/src/StarPosDistortCorr.c @@ -0,0 +1,145 @@ +/** + * @file StarPosDistortCorr.c + * @author Matthias Weiss, University of Vienna + * @date 2 Dec 2016 + * @brief implementation for CHEOPS image distortion correction routine. + */ + +#include "StarPosDistortCorr.h" + +#include <CrIaDataPool.h> +#include <CrIaDataPoolId.h> + +void remove_star_from_candidate_list(int star_index, struct obs_pos_t * obs_pos) +{ + int k, l; + + /* Find out if star with index star_index is in the candidate list, and if yes, remove it + from the list */ + for (k = 0, l = 0; k < obs_pos->n_candidates; k++) + { + if (obs_pos->candidate_index[k] == star_index) + { + k++; + } + if (k != l) + { + obs_pos->candidate_index[l] = obs_pos->candidate_index[k]; + obs_pos->n_candidates--; + } + l++; + } +} + +/** + * @brief C routine for distortion correction of star coordinates in CHEOPS + * + * It takes a list of previously extracted star coordinates and changes + * them by applying radial distortion correction. + * As the star coordinates are measured from the image corner, and not + * relative to the optical axis, the star coordinates have to be + * transformed in order to calculate their radial distance from the axis. + * @param obs_pos Pointer to an obs_pos_t structure that includes a list of + observed star coordinates obs_pos->x[i] and obs_pos->x[i]. + The coordinates must be in pixels with the origin in the + lower left corner of the sensor. Pixel values must not + exceed the sensor dimension give in img_xdim and img_ydim. + The number of stars with coordinates must match ops_pos->n. + The number of candidate stars ops_pos->n_candidates must be + smaller or equal to the number of stars ops_pos->n. + The indexes in the list of candidate stars + ops_pos->candidate_index must exist in ops_pos->x and + ops_pos->y. The number of candidate stars in + ops_pos->candidate_index must match ops_pos->n_candidates. + * @param optical_axis_x x coordinate in pixels of the optical axis (relative to + lower left sensor corner) + * @param optical_axis_y y coordinate in pixels of the optical axis (relative to + lower left sensor corner) + * @param img_xdim Sensor dimension in pixels in x direction + * @param img_ydim Sensor dimension in pixels in y direction + * @return Number of stars where distortion correction was applied to + * their coordinates. -1 is returned when the function parameters + * don't meet the specification. + */ + +int star_pos_distort_corr (struct obs_pos_t *obs_pos, const double optical_axis_x, const double optical_axis_y, const double img_xdim, const double img_ydim) +{ + double dist_coeff1, dist_coeff2, dist_coeff4; + double distortion_factor, x_orig, y_orig, x_corr, y_corr, rsquare; + unsigned int i, j; + float fval; + + /* Check the function parameters. */ + if (img_xdim < 0.0) + return -1; + if (img_ydim < 0.0) + return -1; + if (optical_axis_x < 0.0 || optical_axis_x > img_xdim) + return -1; + if (optical_axis_y < 0.0 || optical_axis_y > img_ydim) + return -1; + + CrIaCopy(DISTC1_ID, &fval); /* 1.0 */ + dist_coeff1 = (double) fval; + + CrIaCopy(DISTC2_ID, &fval); /* 3.69355E-8 */ + dist_coeff2 = (double) fval; + + CrIaCopy(DISTC3_ID, &fval); /* 7.03436E-15 */ + dist_coeff4 = (double) fval; + + /* Apply distorion correction to the star coordinates. */ + for (i=0, j=0; i < obs_pos->n; i++) + { + /* For radial optical distortion we need to transform the star coordinates + to a coordinate system with the optical axis in the origin. */ + x_orig = obs_pos->x[i] - optical_axis_x; + y_orig = obs_pos->y[i] - optical_axis_y; + + /* Calculate the square of the radial distance of the star from the optical axis. */ + rsquare = x_orig * x_orig + y_orig * y_orig; + + /* Optical distortion is fitted as a 4th order polynomial with only even powers. */ + distortion_factor = dist_coeff1 + dist_coeff2 * rsquare + dist_coeff4 * rsquare * rsquare; + + /* Apply distortion correction and transform back to the original coordinate system.*/ + x_corr = x_orig * distortion_factor + optical_axis_x; + y_corr = y_orig * distortion_factor + optical_axis_y; + + /* Distortion correction moves stars radially outwards from the optical axis, + hence stars that were on the image edge before, would be moved outside the image. + Don't increase counter j for these so that with the next valid star they get overwritten. */ + if (x_corr < 0.0) + { + remove_star_from_candidate_list(i, obs_pos); + continue; + } + if (y_corr < 0.0) + { + remove_star_from_candidate_list(i, obs_pos); + continue; + } + if (x_corr > (img_xdim - 1.0)) + { + remove_star_from_candidate_list(i, obs_pos); + continue; + } + if (y_corr > (img_ydim - 1.0)) + { + remove_star_from_candidate_list(i, obs_pos); + continue; + } + + /* only corrected coordinates inside the image area will be + entered, overwriting the input values */ + obs_pos->x[j] = x_corr; + obs_pos->y[j] = y_corr; + + j++; + } + + obs_pos->n = j; + + return j; +} + diff --git a/TargetAcquisition/src/StarPosDistortCorr.h b/TargetAcquisition/src/StarPosDistortCorr.h new file mode 100644 index 0000000000000000000000000000000000000000..b285f580056a7381ee00d7a49305c82aa2082342 --- /dev/null +++ b/TargetAcquisition/src/StarPosDistortCorr.h @@ -0,0 +1,16 @@ +/** + * @file StarPosDistortCorr.h + * @author Matthias Weiss, University of Vienna + * @date 2 Dec 2016 + * @brief declaration for CHEOPS image distortion correction routine. + */ + +#ifndef STARPOSDISTORTCORR_H_ +#define STARPOSDISTORTCORR_H_ + +#include "TaDatatypes.h" + + +int star_pos_distort_corr(struct obs_pos_t *obs_pos, const double optical_axis_x, const double optical_axis_y, const double img_xdim, const double img_ydim); + +#endif /* STARPOSDISTORTCORR_H_ */ diff --git a/TargetAcquisition/src/TaDatatypes.h b/TargetAcquisition/src/TaDatatypes.h new file mode 100644 index 0000000000000000000000000000000000000000..c4c068bc7f79a13ac2ef9dc2badcdd3ee50ecda8 --- /dev/null +++ b/TargetAcquisition/src/TaDatatypes.h @@ -0,0 +1,441 @@ + /** + * @file TaDatatypes.h + * @ingroup EngineeringAlgorithms + * @author Philipp Löschl (roland.ottensamer@univie.ac.at) + * @date July, 2017 + * + * @ingroup EngineeringAlgorithms + * + * @brief Data type and structure definitions for @TargetAcquisition algorithms. + */ + + +#ifndef TADATATYPES_H_ +#define TADATATYPES_H_ + +#ifdef GROUNDSW +#define TA_DEBUG printf +#else +#include "IfswDebug.h" +#define TA_DEBUG DEBUGP +#endif + +#define TRUE 1 +#define FALSE 0 + +#define TA_XDIM 1024 /* Image dimension */ +#define TA_YDIM 1024 +#define BINFACT 8 +#define BXDIM 128 +#define BYDIM 128 +#define LXDIM 41 /* PSF logic mask dimension */ +#define LYDIM 41 + +#define NROI 16384 /* theoretical maximum for 8x rebin */ +#define NPOS 60 +#define NCAND 10 +#define N_OBS_FP NCAND*(NPOS-1)*(NPOS-2)*8*3 +#define N_REF_FP (NPOS-1)*(NPOS-2)*3 + +#define PI 3.14159265f + +/** + * @brief Structure to store image data + * @param data image data, 1D array + * @param xdim image x-dimension + * @param ydim image y-dimension + + * @note + */ +struct img_t { + unsigned int *data; /* 1D array holding the 2D image data. will point to the cib */ + unsigned int xdim; /* cols of image data */ + unsigned int ydim; /* rows of image data */ +}; + +/** + * @brief Structure to store rebinned image data + * @param data rebinned image data, 1D array + * @param xdim rebinned image x-dimension + * @param ydim rebinned image y-dimension + + * @note + */ +struct imgBin_t { + unsigned int data[BXDIM*BYDIM]; /* 1D array holding the 2D image data */ + unsigned int xdim; /* cols of image data */ + unsigned int ydim; /* rows of image data */ +}; + +/** + * @brief References position for @AngleMethod patterns + * @param x x component of reference position, 1D array + * @param y y component of reference position, 1D array + * @param n number of stored reference positions + + * @note NPOS = 60 reserves space for a maximum of 60 reference positions + */ +struct ref_pos_t { + float x[NPOS]; + float y[NPOS]; + int n; +}; + + /** + * @brief Observed position for @AngleMethod patterns + * @param x x component of observed position, 1D array + * @param y y component of observed position, 1D array + * @param n number of stored observed positions + + * @param candidate_index Observed positions around the target location will be indexed as possible candidates + * @param n_candidates number of indexed candidate positions + + * @note NPOS = 60 reserves space for a maximum of 60 observed positions + */ +struct obs_pos_t { + float x[NPOS]; + float y[NPOS]; + unsigned int n; + + int candidate_index[NPOS]; + int n_candidates; +}; + +/** + * @brief Structure to store pixel of interest that are used to obtain star + positions by calculating the barycenter in a region of interest + around them. + * @param x x-coordinate of the Pixel of Interest (POI), 1D array + * @param y y-coordinate of the Pixel of Interest (POI), 1D array + * @param counter number of stored Pixel of Interest (POI) + + * @param group stores an index to group adjacent POI, 1D array + * @param group_counter number of formed POI groups + + * @param skip_index indices of already grouped POI + * @param skip_counter stores the number of already grouped indices + + * @note Pixel of Interest (POI) where formerely referred to as + Region of Interest (ROI) and the structure name wasn't changed + in the transition. + * @note NROI is the maximum number of possible POI + 1024/8 = 128 -> 128 * 128 = 16384 + */ +struct ROI_t { + short x[NROI]; + short y[NROI]; + unsigned short counter; + + short group[NROI]; + unsigned short group_counter; + + unsigned short skip_index[NROI]; + unsigned short skip_counter; +}; + +/** + * @brief Structure for the reference database that contians the geometric + features of the patterns created from the reference positions to + identify the target star. + + * @param data Stores distances and angles between groups of 3 stars + A combination of 2 distances and 1 angle is referred to + as the __fingerprint__ of the star, 1D array + + * @param n_stars number of reference stars that were used for the patterns + + * @note Maxium number of fingerprints is given by(n_stars-1)*(n_stars-2) + which results in a total possible (NPOS-1)*(NPOS-2) * 3 shorts for + the data field. It can also be used for orientation and accessing + fingerprints for a certain combination of stars. + + * @note Example: a system of 4 stars [A B C D] can form the following + fingerprints for star A:\n\n + B - A - C \t\twith the distances BA and AC and an angle between them\n + B - A - D\n\n + + C - A - B\n + C - A - D\n\n + + D - A - B\n + D - A - C\n\n + + Hence N = 4 gives (N-1)*(N-2) = 6 triplets of distance/distance/angle + + * @note The above example shows how the database for star A is ordered such + that all combinations with the next database star B are grouped + together. The combination between a star and its first neighbour + like B - A in this example is called base0. The combination of A + with its second neighbour A - C is called base1. + + */ +struct ref_db_t { + unsigned short data [N_REF_FP]; + unsigned int n_stars; +} __attribute__((packed)) ; + +/** + * @brief Structure for the observed database that contians the geometric + features of the patterns created from the observed positions to + identify the target star. + + * @param data Stores distances and angles between groups of 3 stars. + A combination of 2 distances and 1 angle is referred to + as the __fingerprint__ of the star, 1D array + + * @param counter total number of stored fingerprints + + * @param base0_counter total number of stored base0. This is exactly one + less than the observed number of positions + + * @param candidate_counter counts the number of observed stars that + were considered a candidate to be the target + star due to their proximity to the expected + target location. + + * @param base0_index __data__ index for each __base0__ + * @param base1_index __data__ index for each __base1__ + * @param base1_data_count stores the number of fingerprints for each __base1__ + + * @param value_index stores the numerical value for each __base0__ + and __base1__ to be used as search index in the + matching process. Therefore the matching + algorithm does not have to perform search + operations in the significantly larger __data__ + array. + + * @note Example: a system of 4 stars [A B C D] can form the following + fingerprints for star A:\n\n + B - A - C \t\twith the distances BA and AC and an angle a(BA, AC) between them\n + B - A - D\n\n + + C - A - B\n + C - A - D\n\n + + D - A - B\n + D - A - C\n\n + + Hence N = 4 gives (N-1)*(N-2) = 6 triplets of distance/distance/angle + +* @note In form of fingerprints this would be stored as: \n\n + [BA, AC, a(BA, AC)]\n + [BA, AD, a(BA, AD)]\n + [CA, AB, a(CA, AB)]\n + .\n + .\n + .\n + + * @note The above example shows how the database for star A is ordered such + that all combinations with the next database star B are grouped + together. The combination between a star and its first neighbour + like B - A in this example is called base0. The combination of A + with its second neighbour A - C is called base1. + +* @note In addition to the basic structure that the observed database shares + with the reference database the positional uncertainties of + the positions that were returned by the @StarExtraction have to be + considered. This extends the above schema to\n\n + + B1 - A - C1\n + B2 - A - C1\n + B1 - A - C2\n + B2 - A - C2\n\n + + and likewise for the other combinations. The distances AB1 and AB2 + are measurements for the separation of the same two stars but with + different estimation of the positional error. The algorithm is such + that there can be up to 3 entries for one distance measurement.\n\n + + Since it is not priorly known whether the calculation will result + in one, two or three values for the distance between two stars, + the observed database is not as well structured as the + reference database. Therefore variables to keep track of the different + base0 and base1 locations are necessary. + */ +struct obs_db_t { + unsigned short data[N_OBS_FP]; /* all finger prints */ + unsigned int counter; /* total amount of finger prints */ + unsigned int base0_counter; + + unsigned short candidate_counter; + + unsigned int base0_index[NCAND*(NPOS-1)]; /* first index of each base 0 */ + unsigned int base1_index[NCAND*(NPOS-1)*(NPOS-2)]; /* first index of each base 1 */ + unsigned int base1_data_count[NCAND*(NPOS-1)*(NPOS-2)]; /* number of finger prints for each base 1 */ + + unsigned int value_index[NCAND*(2*(NPOS-1) + 2*(NPOS-1)*(NPOS-2))]; /* saves base 0 and base 1 values */ +}; + +/** + * @brief This structure stores locations of possibly matching fingerprints in __obs_db.data__ + * @param base0_match_index stores doublets of candidate and base0 index, 1D array + * @param base0_match_counter counts the number of stored doublets. Therefore + base0_match_index has 2 * base0_match_counter integers + + * @param base1_match_index stores triplets of candidate, base0 and base1 index + for matching entries. 1D-array + + * @param base1_match_counter counts the number of stored triplets. Therefore + base1_match_index has 3 * base1_match_counter integers + + * @note This is used in the first step of the matching process where a __base0__ + (the distance between the star and its first neighbour) from the reference + database is taken and looked for in the observed database. All __base0__ + locations of matching fingerprints in the observed database are stored in + __base0_match_index__. These locations are then checked for matching + __base1__ entries in a further step. Positive identifications for both + bases are then stored in __base1_match_index___. + */ +struct match_candidates_t { + /* entries in most unsigned shorts will be within [0:NPOS] */ + /* so one could actually use bytes instead */ + + unsigned int base0_match_index[2*NCAND*(NPOS-1)]; + unsigned int base0_match_counter; /* [0:NCAND*(NPOS-1)) */ + + unsigned int base1_match_index[3*NCAND*(NPOS-1)*(NPOS-2)]; + unsigned int base1_match_counter; /* [0:NCAND*(NPOS-1)(NPOS-2)) */ +}; + +/** + * @brief This structure stores all information as well as the final match result + from the evaluation process of the previously found match candidates (@match_candidates_t) + + * @param match_results stores match result quadruplets consisting of\n + Candidate Star\n + Base0\n + Base1\n + Index of fingerprint with this base0/base1 combination \n + 1D array + + * @param base0_match_count Tracks how many base1 are matched for specific base0 combinations (1D array) + * @param base0_match_count_index Tracks the number of __base0_match_count__ entries. + * @param base0_index Stores the index of the reference star with with the base0 was formed (1D array) + + * @param counter Tracks the total amount of __match_results__ entries + (one quadruplet increments by 4) + + * @param n_ref_pos Stores the number of reference positions + * @param n_obs_pos Stores the number of observed positions + + * @param match_histogram Array to track __base0_match_count__ during the match result reduction + during the matching process. Each dimension resembles a __base0__ in the + order of the reference positions and holds the number of __base1__ matches + for each. These might be reduced at a later stage of the process to + remove false positive matches. + + * @param star_tracker Stores the majorily matched candidate star index for base0 matches. + Deviating results for this base0 will be discarded. + + * @param base0_tracker Stores the majorily matched base0 index. + Deviating results for this base0 will be discarded. + + * @param target_star stores the index of the identified target star within the observed positions\n + -1 if identification fails + + * @param n_matched_items Total number of matched fingerprints over all bases + * @param n_matched_bases Number of matched base0 in the reference database + * @param match_quality Percentage of matched database items + * @param valid_quality Indicator if the __match_quality__ result is good enough to + justify positive target identification + + * @param signal_quality Percentage of measured target star signal compared to + the expected signal + * @param valid_signal Indicator if the __signal_quality__ result is good enough to + justify positive target identification + + * @note __star_tracker__ and __base0_tracker__ both work with the indices for candidate stars + and bases which can deviate since two different base0 (combinations of the target + star paired with one of its neighbours) can have the same numerical distance. + This leads to multiple base0 from the observed database to match with a + single base0 from the reference database. + */ +struct match_results_t { + int match_results[4*NCAND*(NPOS-1)*(NPOS-2)]; + unsigned int base0_match_count[NCAND*(NPOS-1)]; + unsigned int base0_match_count_index; + unsigned int base0_index[NCAND*(NPOS-1)]; + + unsigned int counter; /* [0:4*NCAND*(NPOS-1)*(NPOS-2)) */ + + unsigned int n_ref_pos; + unsigned int n_obs_pos; + + int match_histogram[NPOS-1]; + int star_tracker[NPOS-1]; + int base0_tracker[NPOS-1]; + + short target_star; + + short n_matched_items; + short n_matched_bases; + float match_quality; + short valid_quality; + + float signal_quality; + short valid_signal; +}; + +/** + * @brief This structure stores match results for the photometric standalone + matching process called Magnitude Validation Algorithm. + + * @param obs_pos_index index of observed position for each star candidate for + which the signal is measured (1D array) + + * @param signal measured signal for each candidate (1D array) + * @param signal_quality Percentage compared to expected signal + * @param n number of canddidates as counter for the arrays above + + * @param valid_signal Indicator if photometric matching was successful + * @param valid_index Index of target match in __obs_pos_index__ + + * @note + */ +struct mva_results_t { + int obs_pos_index[NCAND]; + int signal[NCAND]; + float signal_quality[NCAND]; + unsigned int n; + + int valid_signal; + int valid_index; +}; + +/** + * @brief Output structure for the TaUnique function. TaUnique finds unique + array entries and counts how often they are present in the provided + data set + + * @param items Stores all unique items (1D array) + * @param counts Number of times a unique item was found in the data (1D array) + + * @param n_items Total number of items in the data set + * @param index_max_count Index of the item with the maximum number of counts + + * @note This funciton offers similar functionality as numpy.unique in python. + */ +struct unique_output_t { + int items[NPOS-1]; + int counts[NPOS-1]; + + unsigned int n_items; + int index_max_count; +}; + +/** + * @brief Output structure for the TaWhere function. TaWhere finds array items + according to provided criteria + + * @param items returned items that satisfy the where criteria + * @param n_items number of returned items + + * @note This funciton offers similar functionality as numpy.where in python. + */ +struct where_output_t { + unsigned int items[NPOS-1]; + unsigned int n_items; +}; + + +#endif /* TADATATYPES_H_ */ diff --git a/TargetAcquisition/src/TargetAcquisition.c b/TargetAcquisition/src/TargetAcquisition.c new file mode 100644 index 0000000000000000000000000000000000000000..bba5cb46fcac08e3ded7de321d13c3f82e8b164f --- /dev/null +++ b/TargetAcquisition/src/TargetAcquisition.c @@ -0,0 +1,575 @@ +/** +* @file TargetAcquisition.c +* @author Philipp Löschl & Roland Ottensamer (roland.ottensamer@univie.ac.at) +* @date July, 2017 +* +* @defgroup TargetAcquisition Target Acquisition +* @ingroup EngineeringAlgorithms +* +* @brief Target Acquisition serves as the control center for the @StarExtraction +* and the identification algorithms @AngleMethod, @MagnitudeValidation. +* +* ## Introduction +* The Target Acquisition is the entirety of the @StarExtraction "Star Extraction", +* @AngleMethod "Angle Method Algorithm" and +* @MagnitudeValidation "Magnitude Validation Algorithms" and is mainly responsible +* for their configuration and execution. It is controlled by an operator in +* the ground segment via the Star Map Command, which is an observation specific +* information package that provides all the necessary parameters for an +* autonomous and successful target identification. In addition, it also serves +* as the connection to the rest of the Instrument Application Software (IASW) +* and therefore also handles the incoming image data and outgoing centroiding +* reports. +* +* The acquisition process starts with the memory allocation for all +* acquisition algorithm specific variables. Once they are in place it receives +* the image data of the current observation and the respective acquisition +* algorithm parameters from the Star Map Command. This information is then used +* to scale the time dependant quantities such as the __reference target signal__, +* __background signal__ and __detection thresholds__ to the respective +* exposure time of the current situation. +* +* After this preparation, each acquisition process continues as follows: +* +* - Star Extraction +* - Distortion Correction +* - Identification Algorithm +* +* The @Star Extraction "Star Extraction" is the first step for each acquisition +* and is independent of which target identification method is used in succession. +* Since the optical system distorts the star positions on the CCD enough so +* that they can become unrecogniseable by the @AngleMethod "Angle Method" a +* distortion correction (see section below (REF) for all extracted positions +* is necessary. Given a successful star extraction and the acquisition process +* is concluded with the execution of one of the identification algorithms. +* Their selection is observation specific and described in more detail in +* section Algorithm Selection (REF) below. +* \n +* \n +* ## Star Map Command +* All the required input parameters for the acquisition algorithms are provided +* by the Star Map Command telemetry packages. They are created and tested +* for every observation by an operator of the Science Operations Center (SOC) +* with the StarMap Generator Tool. Their content can be seen in Tab.: (REF) +* below: +* <table> +* <tr> <td colspan="4" align="center"> __Star Map Telecommand__ +* <tr> <th> Size [Bit] <th> Data Type <th> Parameter <th> Description +* <tr> <td> 32 <td> UINT <td> OBSID <td> Unique identifier for the observation +* <tr> <td> 16 <td> USHORT <td> AcqAlgoId <td> +* <tr> <td> 32 <td> UINT <td> SPARE <td> Former parameter “TargetStar†has been deleted +* <tr> <td> 2208 <td> <td> SkyPattern <td> Algorithm Data – details following below +* <tr> <th colspan="4" align="center"> The SkyPattern is made up of the following data structure +* <tr> <td> 24 <td> UINT24 <td> Target_Location_X <td> "Position on the CCD (in centipixels where the target is intended to be located. Origin = bottom left pixel corner (centre of bottom left pixel is thus [50/50]), counting in Cartesian coordinates." +* <tr> <td> 24 <td> UINT24 <td> Target_Location_Y <td> same for Y axis +* <tr> <td> 8 <td> UCHAR <td> Algorithm ID <td> which algorithm is to be selected for the Target Acquisition 0… None, 1… MVA, 2… AMA, 3...AMA + MVA +* <tr> <td> 16 <td> USHORT <td> SPARE <td> former execution time (moved) +* <tr> <td> 16 <td> USHORT <td> SPARE <td> former delay time (moved) +* <tr> <td> 16 <td> USHORT <td> Distance Threshold <td> Absolute distance between measured position and Target_Location under which we switch from acquisition to centroiding. +* <tr> <td> 8 <td> UCHAR <td> Iterations <td> Maximum number of iterations. 0 = inf +* <tr> <td> <td> <th> Algorithm Paramters <th> Parameters needed for the tuning of the algorithm – these are generated by the StarMap Generator +* <tr> <td> 16 <td> USHORT <td> SPARE <td> former Rebinning Factor. Now hard coded. +* <tr> <td> 16 <td> USHORT <td> Detection Threshold <td> Sets the detection threshold for the Star Extraction. Default: 5200 [10 ADU] +* <tr> <td> 16 <td> USHORT <td> SE_Reduced_Extraction <td> Limits the Star Extraction to a radius around the expeced Target Location. Default: False +* <tr> <td> 16 <td> USHORT <td> SE_Reduced_Radius <td> Sets the reduced extraction radius for the Star Extraction. Default: 392 pix +* <tr> <td> 16 <td> USHORT <td> SE_Tolerance <td> Maximum positional error in Star Extraction results. Default: 5 pix +* <tr> <td> 16 <td> USHORT <td> MVA_Tolerance <td> Maximum photometric error for the Magnitude Validation Method. Default: 15 percent +* <tr> <td> 16 <td> USHORT <td> AMA_Tolerance <td> Maximum error for distance vectors. Default: 3 pix +* <tr> <td> 16 <td> USHORT <td> Pointing_Uncertainty <td> Maximum expected pointing error from the Target Location. Default: 150 pix +* <tr> <td> 32 <td> UINT <td> Target Signal <td> Signal of the target in ADU/s +* <tr> <td> 16 <td> USHORT <td> Number of Stars <td> Number of stars included in the sky pattern +* <tr> <td> 1920 <td> BINARY <td> Pattern <td> Data field („Sky Pattern“) with star entries according to algorithm 920 bits = 120 shorts +* </Table> +* \n +* \n +* ## Distortion Correction +* The optical system of CHEOPS introduces significant distortion effects in the +* outer regions of the FOV. As they are strong enough to affect the intra-star +* distances that are required by the Angle Method a distortion correction is used +* to transform the Star Extraction provided positions into undistorted positions +* that match the reference stars. More information is provided by (REF). +* \n +* \n +* ## Algorithm Selection +* The acquisition algorithm is selected by the operator during the parameter +* setup for the Star Map Command. Depending on the star density and distribution +* in a specific FOV there are three possible options: +* +* - Magnitude Validation Acquisition Algorithm (MVAA) +* - Angle Method Algorithm (AMA) +* - Angle Method Algorithm + Magnitude Validation Algorithm (AMA + MVA) +* +* Magnitude Validation Acquisition is meant for bright objects that can easily +* be distinguished from the other stars in an observation. The Star Map Generator +* Tool is currently configured to prefer this algorithm for targets of up to +* 10mag. Fainter stars might have another, similarly bright object in the FOV +* and could therefore be misidentified. +* +* For this reason the two Angle Method Algorithm variations are used for +* target identifications of >10mag stars. The third method is prefered and will +* be used for every case that has available brightness data of the target star. +* Here the Magnitude Validation Algorithm is used to as a backup identification +* method to verify observations with poor AMA results. Observations without this +* data will solely use the Angle Method Algorithm. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "CrIaDataPool.h" +#include "CrIaDataPoolId.h" + +#include "AngleMethod.h" +#include "TaDatatypes.h" +#include "StarExtractor.h" +#include "TargetAcquisition.h" +#include "StarPosDistortCorr.h" +#include "EngineeringAlgorithms.h" + +#include "SdpBuffers.h" +#include "SdpAlgorithmsImplementation.h" + +struct match_candidates_t *g_candidates; +struct unique_output_t *g_output; +struct unique_output_t *g_unique_base0; +struct unique_output_t *g_unique_stars; +struct unique_output_t *g_unique_duplicate_entry; +struct where_output_t *g_multi_base_skip_index; +struct where_output_t *g_multi_base_index; +struct where_output_t *g_duplicate_base0; +struct where_output_t *g_duplicate_base1; +struct unique_output_t *g_unique_stars; +struct where_output_t *g_base0_count; +struct img_t *g_img; +struct obs_pos_t *obs_pos; +struct ref_pos_t *ref_pos; +struct ref_db_t *ref_DB; +struct obs_db_t *obs_DB; +struct match_results_t *amaresults; +struct mva_results_t *mvaresults; +struct ROI_t *g_POI; +struct ROI_t *temp_POI; + +struct imgBin_t *g_imgBin; + +#ifdef GROUNDSW + # define ADVGROUNDSW 1 +#endif + +#define MAX_TASTARS MAXNROFSTARS + +#define ALIGNSIZE(s) ((s+7) & 0xFFFFFFF8) + +void initMatchingBuffers (unsigned int *data) +{ + g_img = (struct img_t *)SWAPALLOC(ALIGNSIZE(sizeof(struct img_t)), SWAP); /* shall point to the unpacked full frame of 1024x1024 32 bit in CIB */ + ref_pos = (struct ref_pos_t *)SWAPALLOC(ALIGNSIZE(sizeof(struct ref_pos_t)), SWAP); /* < 1 kiB */ + obs_pos = (struct obs_pos_t *)SWAPALLOC(ALIGNSIZE(sizeof(struct obs_pos_t)), SWAP); /* < 1.5 kiB*/ + ref_DB = (struct ref_db_t *)SWAPALLOC(ALIGNSIZE(sizeof(struct ref_db_t)), SWAP); /* < 40 kiB */ + obs_DB = (struct obs_db_t *)SWAPALLOC(ALIGNSIZE(sizeof(struct obs_db_t)), SWAP); /* ca 3.2 MiB */ + amaresults = (struct match_results_t *)SWAPALLOC(ALIGNSIZE(sizeof(struct match_results_t)), SWAP); /* ca 600 kiB */ + mvaresults = (struct mva_results_t *)SWAPALLOC(ALIGNSIZE(sizeof(struct mva_results_t)), SWAP); /* ca 132 bytes */ + + g_candidates = (struct match_candidates_t *)AUXALLOC(ALIGNSIZE(sizeof(struct match_candidates_t)), AUX); /* ca 416 kB */ + g_output = (struct unique_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct unique_output_t)), AUX); /* 480 B */ + g_unique_base0 = (struct unique_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct unique_output_t)), AUX); /* 480 B */ + g_unique_duplicate_entry = (struct unique_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct unique_output_t)), AUX); /* 480 B */ + g_multi_base_skip_index = (struct where_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct where_output_t)), AUX); /* 240 B */ + g_multi_base_index = (struct where_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct where_output_t)), AUX); /* 240 B */ + g_duplicate_base0 = (struct where_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct where_output_t)), AUX); /* 240 B */ + g_duplicate_base1 = (struct where_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct where_output_t)), AUX); /* 240 B */ + g_unique_stars = (struct unique_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct unique_output_t)), AUX); /* 480 B */ + g_base0_count = (struct where_output_t *)AUXALLOC(ALIGNSIZE(sizeof(struct where_output_t)), AUX); /* 240 B */ + + g_imgBin = (struct imgBin_t *) AUXALLOC(ALIGNSIZE(sizeof(struct imgBin_t)), AUX); /* 65538 B */ + g_POI = (struct ROI_t *) AUXALLOC(ALIGNSIZE(sizeof(struct ROI_t)), AUX); /* 131078 B */ + temp_POI = (struct ROI_t *) AUXALLOC(ALIGNSIZE(sizeof(struct ROI_t)), AUX); /* 131078 B */ /* Mantis 2268 */ + + g_img->data = data; + g_img->xdim = TA_XDIM; + g_img->ydim = TA_YDIM; + + return; +} + + +void free_matching_buffers (void) +{ +#if (__sparc__) + release(AUX); + release(SWAP); +#else + swapalloc(0,1); + auxalloc(0,1); +#endif + + return; +} + + +void TargetAcquisition (struct CrIaSib *Sib) +{ + float TargetLocation[2]; + float ExposureTime; + + int SignalThrd, CandidateRadius, Shift[2]; + unsigned int i, u32temp, TargetSignal, DetectionThld; + unsigned char u8temp, TaAlgorithmId; + + unsigned short u16temp, RebinFactor, DetTh; + unsigned short ReducedExtraction, ExtractionRadius, ExtractionTolerance; + unsigned short MvaTolerance, AmaTolerance; + unsigned short PointUncert, BgSignal, NrOfStars; + + int xstart; + + unsigned short cibIn; + unsigned int *cibAddress; + + unsigned char distCorr; + float optAxisX, optAxisY; + + float TaMaxSigFract, TaBias, TaDark, TaSkyBg; + + struct SibHeader *sibHeader; + + /* + copy the image from expos to CIB and crop to 1024 x 1024 + */ + + /* determine nominal or redundant side to find the proper image offset in X */ + sibHeader = (struct SibHeader *) Sib->Header; + + xstart = LSM_XDIM; /* NOM: 28 */ + + if (GetFpmSide(sibHeader->CcdTimingScriptId) == FPM_SIDE_B) + { + xstart = RSM_XDIM; /* RED: 24 */ + } + + CrIaCopy (CIBIN_ID, &cibIn); + cibAddress = (unsigned int *)GET_ADDR_FROM_SDB_OFFSET(cibIn); + + CropCopyFromSibAndUnpack (Sib->Expos, FULL_SIZE_X, FULL_SIZE_Y, 1024, 1024, xstart, 0, cibAddress); + + /* first we release the necessary heaps */ + free_matching_buffers(); + + initMatchingBuffers(cibAddress); + + /* TA_DEBUG("first pixels are: %u %u %u\n", g_img->data[0], g_img->data[1], g_img->data[2]); */ + + /* + assign DP variables + */ + + /* obsid is not needed here */ + + /* acqalgoid is used one level up */ + + /* spare u32 is not used */ + + /* tglocx 24 */ + CrIaCopy(TARGETLOCATIONX_ID, &u32temp); + TargetLocation[0] = (float) ((u32temp - 50) / 100.f); /* comes in centipixel */ /* was: .. - 2850 .., but changed upon request by platform */ + /* TA_DEBUG("TARGETLOCX: %f\n", TargetLocation[0]); */ + + /* tglocy 24 */ + CrIaCopy(TARGETLOCATIONY_ID, &u32temp); + TargetLocation[1] = (float) ((u32temp - 50) / 100.f); /* comes in centipixel */ + /* TA_DEBUG("TARGETLOCY: %f\n", TargetLocation[1]); */ + + /* algoid is 16 in DP but 8 in command */ + CrIaCopy(TAALGOID_ID, &u16temp); + TaAlgorithmId = (unsigned char)u16temp; + /* TA_DEBUG("TAALGOID: %u\n", TaAlgorithmId); */ + + /* TATIMINGPAR1 is used one level up */ + + /* TATIMINGPAR2 is used one level up */ + + /* TADISTANCETHRD is used one level up */ + + /* TAITERATIONS is used one level up */ + + /* rebinfact ushort */ + CrIaCopy(TAREBINNINGFACT_ID, &RebinFactor); + RebinFactor = 8; /* NOTE: must be 8! */ + + /* detthrd ushort */ + CrIaCopy(TADETECTIONTHRD_ID, &DetTh); + DetectionThld = DetTh * 10; + /* TA_DEBUG("TADETECTIONTHRD: %u\n", DetectionThrd); */ + + /* se_reduced_extr ushort */ + CrIaCopy(TASEREDUCEDEXTR_ID, &ReducedExtraction); + /* TA_DEBUG("TASEREDUCEEXTR: %u\n", ReducedExtraction); */ + + /* se reduced radius 16 */ + CrIaCopy(TASEREDUCEDRADIUS_ID, &ExtractionRadius); + /* TA_DEBUG("TASEREDUCEDRADIUS: %u\n", ExtractionRadius); */ + + /* se tolerance 16 */ + CrIaCopy(TASETOLERANCE_ID, &ExtractionTolerance); + /* TA_DEBUG("TASETOLERANCE: %u\n", ExtractionTolerance); */ + + /* mva tolerance 16 */ + CrIaCopy(TAMVATOLERANCE_ID, &MvaTolerance); + /* TA_DEBUG("TAMVATOLERANCE: %u\n", MvaTolerance); */ + + /* ama tolerance 16 */ + CrIaCopy(TAAMATOLERANCE_ID, &AmaTolerance); + /* TA_DEBUG("TAAMATOLERANCE: %u\n", AmaTolerance); */ + + /* pointing uncertainty 16 */ + CrIaCopy(TAPOINTUNCERT_ID, &PointUncert); + /* TA_DEBUG("TAPOINTUNCERT: %u\n", PointUncert); */ + CandidateRadius = PointUncert + ExtractionTolerance; + + /* + copy data pattern parameters + */ + + /* targetsig 32 */ + CrIaCopy(TATARGETSIG_ID, &TargetSignal); + + /* nrofstars 16 */ + CrIaCopy(TANROFSTARS_ID, &NrOfStars); + /* TA_DEBUG("TANROFSTARS: %u\n", NrOfStars); */ + + /* + copy stars pattern + */ + + + /* now read the stars */ + for (i=0; (i < NrOfStars) && (i < MAX_TASTARS); i++) + { + CrIaCopyArrayItem (STARMAP_ID, &u8temp, 4*i); + u16temp = ((unsigned short)u8temp) << 8; + CrIaCopyArrayItem (STARMAP_ID, &u8temp, 4*i+1); + u16temp |= (unsigned short)u8temp; + ref_pos->x[i] = (float) u16temp / 10.0f; + + CrIaCopyArrayItem (STARMAP_ID, &u8temp, 4*i+2); + u16temp = ((unsigned short)u8temp) << 8; + CrIaCopyArrayItem (STARMAP_ID, &u8temp, 4*i+3); + u16temp |= (unsigned short)u8temp; + ref_pos->y[i] = (float) u16temp / 10.0f; + } + + ref_pos->n = i; + + /* + calculate the background + */ + + /* get exposure time from SIB */ + ExposureTime = sibHeader->ExposureTime / 1000.0f; + + CrIaCopy(TABIAS_ID, &TaBias); + CrIaCopy(TADARK_ID, &TaDark); + CrIaCopy(TASKYBG_ID, &TaSkyBg); /* 8.35 ph/s (zody) + 2 ph/s (straylight) = 10.35 photons/s; 0.65 e/ph is the QE; 0.439 is the gain in e/ADU; see Master thesis Ferstl p 111 */ + + BgSignal = calculate_background_signal (ExposureTime, TaBias, TaDark, TaSkyBg); + + TargetSignal = TargetSignal * ExposureTime; + SignalThrd = (int)(DetectionThld * ExposureTime); + + CrIaCopy (TAMAXSIGFRACT_ID, &TaMaxSigFract); + DetectionThld = (int)(SignalThrd * TaMaxSigFract); + + +#ifdef GROUNDSW + TA_DEBUG("Exptime : %f\n", ExposureTime); + TA_DEBUG("BgSignal : %u\n", BgSignal); + TA_DEBUG("TargetSignal : %u\n", TargetSignal); + TA_DEBUG("SignalThrd : %d\n", SignalThrd); + TA_DEBUG("DetectionThld : %u\n", DetectionThld); +#endif + + star_extraction (g_img, obs_pos, RebinFactor, TargetLocation, ReducedExtraction, ExtractionRadius, DetectionThld, SignalThrd, BgSignal, g_POI); + + /* carry out distortion correction */ + CrIaCopy (DIST_CORR_ID, &distCorr); + + if (distCorr != 0) + { + CrIaCopy(OPT_AXIS_X_ID, &optAxisX); + CrIaCopy(OPT_AXIS_Y_ID, &optAxisY); + + (void) star_pos_distort_corr (obs_pos, optAxisX, optAxisY, TA_XDIM, TA_YDIM); + } + + Shift[0] = 0; + Shift[1] = 0; + + /* start with a dummy report */ + PrepareSibCentroid (Sib, CEN_INV_TARGET, 0.0f, 0.0f); + + /* NOTE: Depending on the application either the distortion corrected obs_pos + or the original uncorrected obs_pos have to be used */ + switch (TaAlgorithmId) + { + case TA_ALGO_NONE : + + /* no matching, use dummy report */ + + break; + + case TA_ALGO_MVA : + + if ((obs_pos->n > 0) && (TargetSignal > 0)) + { + /* use uncorrected obs_pos to measure the signal on the right coordinates */ + target_magntitude_validation_acquisition (mvaresults, obs_pos, TargetLocation, CandidateRadius, g_img, TargetSignal, MvaTolerance, BgSignal); + + if (mvaresults->valid_signal != 0) + { + /* use uncorrected obs_pos to measure the correct offset on the CCD*/ + calculate_target_shift_MVA (obs_pos, mvaresults, Shift, TargetLocation); +#ifdef GROUNDSW + TA_DEBUG("MVA says: %d, %d centi-pixel\n", Shift[0], Shift[1]); +#endif + PrepareSibCentroid (Sib, CEN_VAL_FULL, Shift[0]/100.0f, Shift[1]/100.0f); + } +#ifdef ADVGROUNDSW + else + printf("MVA: %f ", 0.0); +#endif + } + + break; + + case TA_ALGO_AMA : + + if ((obs_pos->n > 3) && (ref_pos->n > 3)) + { + create_ref_DB (ref_pos, 0, ref_DB, AmaTolerance); /* NOTE: target index is always 0 */ + + /* use corrected obs_pos to match the reference fingerprints */ + create_obs_DB (obs_pos, obs_DB, TargetLocation, CandidateRadius, AmaTolerance); + + match_databases (ref_DB, obs_DB, amaresults); + + /* both obs_pos possible, since only used GROUNDSW outputs */ + determine_match_quality (amaresults, obs_pos); + + if (amaresults->valid_quality != 0) + { + /* use uncorrected obs_pos to measure the correct offset on the CCD*/ + calculate_target_shift_AMA (obs_pos, amaresults, Shift, TargetLocation); +#ifdef GROUNDSW + TA_DEBUG("AMA says: %d, %d centi-pixel\n", Shift[0], Shift[1]); +#endif + PrepareSibCentroid (Sib, CEN_VAL_FULL, Shift[0]/100.0f, Shift[1]/100.0f); + } + else + { +#ifdef ADVGROUNDSW + /* printf("AMA: %f ", amaresults->match_quality); */ + /*printf("TACQ: FAILED ");*/ +#endif + /* ERROR: MATCH QUALITY < 50% of DB -> TACQ FAIL */ + PrepareSibCentroid (Sib, CEN_INV_TARGET, 0.0f, 0.0f); + } + } + else + { +#ifdef ADVGROUNDSW + /*printf("TACQ: FAILED ");*/ + /* printf("AMA: %f ", 0.0); */ +#endif + /* ERROR: NOT ENOUGH STARS FOR AMA */ + PrepareSibCentroid (Sib, CEN_INV_INPUT, 0.0f, 0.0f); + } + break; + + case TA_ALGO_AMAMVA : + + if ((obs_pos->n > 3) && (ref_pos->n > 3)) + { + create_ref_DB (ref_pos, 0, ref_DB, AmaTolerance); /* NOTE: target index is always 0 */ + + /* use corrected obs_pos to match the reference fingerprints */ + create_obs_DB (obs_pos, obs_DB, TargetLocation, CandidateRadius, AmaTolerance); + + match_databases (ref_DB, obs_DB, amaresults); + + /* both obs_pos possible, since only used GROUNDSW outputs */ + determine_match_quality (amaresults, obs_pos); + + if (amaresults->valid_quality != 0) + { + /* use uncorrected obs_pos to measure the correct offset on the CCD*/ + calculate_target_shift_AMA (obs_pos, amaresults, Shift, TargetLocation); +#ifdef ADVGROUNDSW + /* printf("AMA: %f ", amaresults->match_quality); */ +#endif + PrepareSibCentroid (Sib, CEN_VAL_FULL, Shift[0]/100.0f, Shift[1]/100.0f); + } + else if ((amaresults->match_quality > 40) && (TargetSignal > 0)) /* 40% of DB */ + { + /* use uncorrected obs_pos to measure the signal on the right coordinates */ + target_magnitude_validation (g_img, obs_pos, amaresults, BgSignal, TargetSignal, MvaTolerance); + if (amaresults->valid_signal != 0) + { + /* insuff matches but MVA rescue*/ + /* use uncorrected obs_pos to measure the correct offset on the CCD*/ + calculate_target_shift_AMA (obs_pos, amaresults, Shift, TargetLocation); +#ifdef ADVGROUNDSW + /* printf("AMA: %f ", amaresults->match_quality); */ +#endif + PrepareSibCentroid (Sib, CEN_VAL_FULL, Shift[0]/100.0f, Shift[1]/100.0f); + } + else + { + /* negative insuff matches and no MVA rescue */ +#ifdef ADVGROUNDSW + /* printf("AMA: %f ", amaresults->match_quality); */ + /*printf("TACQ: FAILED ");*/ +#endif + PrepareSibCentroid (Sib, CEN_INV_SMEAR, 0.0f, 0.0f); + } + } + else + { +#ifdef ADVGROUNDSW + /* printf("AMA: %f ", amaresults->match_quality); */ + /*printf("TACQ: FAILED ");*/ +#endif + /* negative insuff matches */ + PrepareSibCentroid (Sib, CEN_INV_SMEAR, 0.0f, 0.0f); + } + } + else + { +#ifdef ADVGROUNDSW + /*printf("TACQ: FAILED ");*/ + /* printf("AMA: %f ", 0.0); */ +#endif + /* ERROR: NOT ENOUGH STARS FOR AMA */ + PrepareSibCentroid (Sib, CEN_INV_INPUT, 0.0f, 0.0f); + } + + break; + + default: + +#ifdef ADVGROUNDSW + /*printf("TACQ: FAILED ");*/ + /* printf("AMA: %f ", 0.0); */ +#endif + /* invalid algorithm id */ + PrepareSibCentroid (Sib, CEN_INV_ALGO, 0.0f, 0.0f); + + break; + + } + + free_matching_buffers(); + + return; +} diff --git a/TargetAcquisition/src/TargetAcquisition.h b/TargetAcquisition/src/TargetAcquisition.h new file mode 100644 index 0000000000000000000000000000000000000000..4dc4cc1225d59be74aa06ecdc9fb8e286e8c0fdf --- /dev/null +++ b/TargetAcquisition/src/TargetAcquisition.h @@ -0,0 +1,41 @@ +#ifndef TARGETACQUISITION_H +#define TARGETACQUISITION_H + +#include "SdpBuffers.h" +#include "TaDatatypes.h" + +extern struct match_candidates_t *g_candidates; +extern struct unique_output_t *g_output; +extern struct unique_output_t *g_unique_base0; +extern struct unique_output_t *g_unique_stars; +extern struct unique_output_t *g_unique_duplicate_entry; +extern struct where_output_t *g_multi_base_skip_index; +extern struct where_output_t *g_multi_base_index; +extern struct where_output_t *g_duplicate_base0; +extern struct where_output_t *g_duplicate_base1; +extern struct unique_output_t *g_unique_stars; +extern struct where_output_t *g_base0_count; +extern struct img_t *g_img; +extern struct obs_pos_t *obs_pos; +extern struct ref_pos_t *ref_pos; +extern struct ref_db_t* ref_DB; +extern struct obs_db_t* obs_DB; +extern struct match_results_t* amaresults; +extern struct mva_results_t* mvaresults; +extern struct ROI_t *g_POI; +extern struct ROI_t *temp_POI; + +extern struct imgBin_t* g_imgBin; + +extern unsigned char maskdata[LXDIM * LYDIM]; + +#define TA_ALGO_NONE 0 +#define TA_ALGO_MVA 1 +#define TA_ALGO_AMA 2 +#define TA_ALGO_AMAMVA 3 + +void initMatchingBuffers (unsigned int *data); + +void TargetAcquisition (struct CrIaSib *Sib); + +#endif diff --git a/include/CrFramework b/include/CrFramework new file mode 120000 index 0000000000000000000000000000000000000000..28fba336b43861fbfa3631acdb64707fe36196c1 --- /dev/null +++ b/include/CrFramework @@ -0,0 +1 @@ +../CrFramework/src \ No newline at end of file diff --git a/include/FwProfile b/include/FwProfile new file mode 120000 index 0000000000000000000000000000000000000000..2c61e67390e8e259705419948f618f2722429eb9 --- /dev/null +++ b/include/FwProfile @@ -0,0 +1 @@ +../FwProfile/src \ No newline at end of file