/************************************************************************* $Archive: /PACS/OnBoard/RDecRec.c $ $Revision: 1.11 $ $Date: 2009/04/23 13:51:12 $ $Author: amazy $ $Log: RDecRec.c,v $ Revision 1.11 2009/04/23 13:51:12 amazy 6.029 * * 6 27/11/06 9:39 Amazy * All error from packet encoders (blue and red) were signaled in the blue * packet encoder status. This is now solved (the * GenereSpectroPacketHeader function now takes an additional parameter * that is a pointer to the packet encoder were the error must be * signaled). * * 5 27/11/06 9:30 Amazy * Additionnal cleaning due to the change of master reset philosophy. A * semaphore was still signaled while no tasks were listening to it. It * has been removed. (Everything related to * SignalWhenReceivingSecondToLastReadout has been removed) * * 41 3/14/06 4:32p Pacs Egse * Version 6.001 * Cleaned and commented *************************************************************************/ #ifdef SIMULATOR #include "virtuosoSim.h" #else // SIMULATOR #include "v_macro.h" #include "node1.h" #include "k_struct.h" #endif #include "seq_msg.h" #include "params.h" #include "links.h" #include "error.h" #include "det.h" #include "u_res.h" #include //**************************************************************** // MACRO //**************************************************************** //macro to signal an error in Red Dec Receiver Task #define SetError(newError) \ {\ SetGlobalError(newError);\ LOCK_WRITE_RES_PARAMS;\ SET_BITS(gpRedDecRec->TaskStatus, K_BMASK_TASK_STATUS_ERROR_STATUS | K_BMASK_TASK_STATUS_ERROR_CODE, K_BMASK_TASK_STATUS_TASK_IN_ERROR + newError); \ UNLOCK_WRITE_RES_PARAMS;\ }\ //**************************************************************** // GLOBAL VARIABLES //**************************************************************** int gaRedDecPixelsInHkDiag[16]; extern int gaLinkStatus[]; //**************************************************************** // FUNCTION DECLARATION //**************************************************************** void InitializeRedDecRec(); void RedDecRec(); extern void StoreGroupHk(int hkBase, int hkSupply, int hkInfo, DecGroupHk* p_groupHk); //**************************************************************** // FUNCTION IMPLEMENTATION //**************************************************************** /* FUNCTION : void InitializeRedDecRec() ************************************* AUTHOR : AMazy USE : Initialize Dec Receiver task. */ void InitializeRedDecRec() { LOCK_WRITE_RES_PARAMS; // initialize task status gpRedDecRec->TaskStatus = K_BMASK_TASK_STATUS_ALIVE | K_BMASK_TASK_STATUS_NO_ERROR_IN_TASK | K_BMASK_TASK_STATUS_LINK_NOT_CONNECTED; gpRedDecRec->Options = K_BMASK_DET_REC_OPTIONS_DEFAULT; gpRedDecRec->PacketCounter = 0; gpRedDecRec->ReadoutCounter = 0; gpRedDecRec->BufferToFill = 0; UNLOCK_WRITE_RES_PARAMS; LOCK_READ_RES_PARAMS; // wait that the DEC initializes the connection on the other side // or that a detector simulator is started while (IS(gpRedDecRec->TaskStatus, K_BMASK_TASK_STATUS_LINK_STATUS, K_BMASK_TASK_STATUS_LINK_NOT_CONNECTED) && IS(gpRedDecRec->TaskStatus, K_BMASK_SIMULATION_TIMING, K_BMASK_REAL_TIMING)) { UNLOCK_READ_RES_PARAMS; KS_TaskSleep(1000); LOCK_READ_RES_PARAMS; } UNLOCK_READ_RES_PARAMS; } /* TASK_FUNCTION : RedDecRec() *************************** AUTHOR : AMazy This function implements the Red Dec Receiver task. It listens on the link 1335 connected to Red DEC, receives the packet, extracts the hk and science data and forward the data to the packet encoder */ void RedDecRec() { SequencerMsg msgSequencer; // used to send messages to the Sequencer PacketEncoderMessage msgPacketEncoder; // used to send messages to the PacketEncoder int i=0; int* pHkDec = (int*)&(gpRedDecRec->DecHk); //for ease of use, consider the Hk structure as an array of int int hkCounter = 0; int receptionBuffer[SIZE_OF_SPECTRO_PACKET_IN_WORDS]; int simulatedPixelValue; BOOL bSimulateReadouts = FALSE; BOOL bSendDataToPacketEncoder = FALSE; int hkInfo = 0; int hkBase = 0; int hkSupply = 0; InitializeRedDecRec(); while(1) { // wait for the next readout #ifdef SIMULATOR KS_SemaTestW(8); #else //SIMULATOR Link1355Read(CHANNEL_RED_DEC, SIZE_OF_SPECTRO_PACKET_IN_WORDS, receptionBuffer); #endif //SIMULATOR gpRedDecRec->PacketCounter++; gpRedDecRec->ReadoutCounter++; // check if we need to swap buffers if (KS_EventTest(EVENT_RED_DET_RECEIVER_TOGGLE_BUFFER) == RC_OK) { gpRedDecRec->BufferToFill = (gpRedDecRec->BufferToFill+1) %2; } //centralizes all access to the param structure here to avoid some expensive LOCK/UNLOCK LOCK_READ_RES_PARAMS; bSimulateReadouts = IS(gpRedDecRec->TaskStatus, K_BMASK_SIMULATION_DATA, K_BMASK_SIMULATED_READOUTS); bSendDataToPacketEncoder = IS(gpRedDecRec->Options, K_BMASK_DET_REC_OPTIONS_DATA_OPERATION, K_BMASK_DET_REC_OPTIONS_FORWARD_DATA); UNLOCK_READ_RES_PARAMS; // if we want to send simulated readouts if (bSimulateReadouts) { static int readoutInRampCount = -1; static int rampCount = 0; int i = 0; int nbReadoutsPerRamp = gpRedDecController->DetectorParams.ReadoutsPerRamp; // generate the simulated data in the buffer // Mail from Helmut : //In order to generate an integration ramp I thought of the following //strategy: //Signal = 60000 - t * 40 + 10 * SQRT(t) // //where t is the sample number (0 ...1024) of the 256 Hz ramp. //Since the ramp is always decreasing I thought I start with a rather //high value within the 16 bit range, therefore the 60000. To get in //some non-linearity I thought of adding a small t^0.5 term to the //otherwise perfectly linear ramp. if (readoutInRampCount < 0) { readoutInRampCount = nbReadoutsPerRamp - 1; rampCount++; } // fill the Simulation DecHk (only the variables that are used in the science packet header) gpRedDecRec->SimDecHk.ReadoutCounterFirst = readoutInRampCount; gpRedDecRec->SimDecHk.RampCounterHighFirst = (rampCount >> 16) & 0x0000FFFF; gpRedDecRec->SimDecHk.RampCounterLowFirst = rampCount & 0x0000FFFF; gpRedDecRec->SimDecHk.ReadoutsPerRampFirst = nbReadoutsPerRamp; gpRedDecRec->SimDecHk.CreStatusRegFirst = 0; simulatedPixelValue = 60000 - (nbReadoutsPerRamp - readoutInRampCount)*40 + 10 * (int)(sqrt(nbReadoutsPerRamp - readoutInRampCount)); for (i = 0; i < SIZE_OF_SPECTRO_SCIENCE_DATA_IN_WORDS; i++) { // copy the simulated value gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[i] = (simulatedPixelValue << 16) | simulatedPixelValue; } readoutInRampCount--; } else // we use the readouts we have received from the DEC { // step through each line of the readout hkCounter = 0; for (i = 0; i < 17; ++i) { // the first 13 words contains the science data MEMCPY(&(gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[i*13]), &(receptionBuffer[i*16]), 13); // the last word contains the digital hk (2 16bits words) pHkDec[hkCounter++] = (receptionBuffer[i*16+15] >> 16) & 0x0000FFFF; pHkDec[hkCounter++] = receptionBuffer[i*16+15] & 0x0000FFFF; } //the last line MEMCPY(&(gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[17*13]), &(receptionBuffer[17*16]), 13); //the analog hk is stored in the last 6 words (6 16bits words) of the line //first group hkBase = (receptionBuffer[17*16+13] & 0xFFFF0000) >> 16; hkSupply = (receptionBuffer[17*16+14] & 0xFFFF0000) >> 16; hkInfo = (receptionBuffer[17*16+15] & 0xFFFF0000) >> 16; StoreGroupHk(hkBase, hkSupply, hkInfo, &(gpRedDecRec->DecHk.Group1)); //second group hkBase = receptionBuffer[17*16+13] & 0x0000FFFF; hkSupply = receptionBuffer[17*16+14] & 0x0000FFFF; hkInfo = receptionBuffer[17*16+15] & 0x0000FFFF; StoreGroupHk(hkBase, hkSupply, hkInfo, &(gpRedDecRec->DecHk.Group2)); // some Hk Values need some computation gpRedDecRec->DecHk.RampCounterFirst = (gpRedDecRec->DecHk.RampCounterHighFirst << 16) | (gpRedDecRec->DecHk.RampCounterLowFirst & 0x0000FFFF); gpRedDecRec->DecHk.RampCounterSecond = (gpRedDecRec->DecHk.RampCounterHighSecond << 16) | (gpRedDecRec->DecHk.RampCounterLowSecond & 0x0000FFFF); } /* currently, we do not store any pixel value in diagnostic hk but we leave the code here in case we need it gaRedDecPixelsInHkDiag[0] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[13*9+12] & 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[1] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[195] & 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[2] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[208] & 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[3] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[221]& 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[4] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[186] & 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[5] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[187] & 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[6] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[188] & 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[7] = (gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[189] & 0xFFFF0000) >> 16; gaRedDecPixelsInHkDiag[8] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[4] & 0x0000FFFF; gaRedDecPixelsInHkDiag[9] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[17] & 0x0000FFFF; gaRedDecPixelsInHkDiag[10] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[30] & 0x0000FFFF; gaRedDecPixelsInHkDiag[11] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[43] & 0x0000FFFF; gaRedDecPixelsInHkDiag[12] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[186] & 0x0000FFFF; gaRedDecPixelsInHkDiag[13] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[199] & 0x0000FFFF; gaRedDecPixelsInHkDiag[14] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[212] & 0x0000FFFF; gaRedDecPixelsInHkDiag[15] = gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill].ScienceData[225] & 0x0000FFFF; */ // if Diagnostic Hk is being acquired now and if it is synchronized with this detector, if (gpHkDiagnosticController->HkDiagnosticPeriodCommanded == RED_SPEC) { // ask the HkDiagController to perform its measurements KS_SemaSignal(SEMA_TIMER_HOUSEKEEPING_DIAGNOSTIC); } // if the task is configured to send the data to the PacketEncoder (Nominal behaviour) if (bSendDataToPacketEncoder) { // send the data to the PacketEncoder msgPacketEncoder.Type = RED_SPEC; msgPacketEncoder.BufferId = gpRedDecRec->BufferToFill; // send message to PacketEncoder if (gParameters.RedPacketEncoderLink == CHANNEL_RED_SPU) { //generate the header GenerateSpectroPacketHeader(gpRedPacketEncoder, &(gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill]), RED_SPU_APID, gpRedDecRec, gpRedDecController, bSimulateReadouts); KS_FIFOPut(RED_PACKET_ENCODER_FIFO, &msgPacketEncoder); } else { //generate the header GenerateSpectroPacketHeader(gpRedPacketEncoder, &(gaRedSpectroPacketBuffer[gpRedDecRec->BufferToFill]), RED_SPU_APID, gpRedDecRec, gpRedDecController, bSimulateReadouts); KS_FIFOPut(BLUE_PACKET_ENCODER_FIFO, &msgPacketEncoder); } } else { if (gParameters.RedPacketEncoderLink == CHANNEL_RED_SPU) { KS_FIFOPurge(RED_PACKET_ENCODER_FIFO); } else { KS_FIFOPurge(BLUE_PACKET_ENCODER_FIFO); } } // send synchronization signal to DPU if (IS(gpSequencer->Options, DETECTOR_MASK, RED_SPEC) && ( (!IS(gpRedDecRec->TaskStatus, K_BMASK_SIMULATION_DATA, K_BMASK_SIMULATED_READOUTS) && (gpRedDecRec->DecHk.ReadoutCounterFirst == 0)) || (IS(gpRedDecRec->TaskStatus, K_BMASK_SIMULATION_DATA, K_BMASK_SIMULATED_READOUTS) && (gpRedDecRec->SimDecHk.ReadoutCounterFirst == 0)))) { msgSequencer.Type = SEQUENCE_SYNCHRO; KS_FIFOPut(SEQUENCER_FIFO, &msgSequencer); } } }