/************************************************************************* $Archive: /pacs/OnBoard/BolRec.c $ $Revision: 1.11 $ $Date: 2009/04/23 13:51:12 $ $Author: amazy $ $Log: BolRec.c,v $ Revision 1.11 2009/04/23 13:51:12 amazy 6.029 * * 7 4/23/09 3:46p Pacs1 * 6.029 * * 5 30/09/08 15:19 Amazy * - increased grating power limit to 150mA and made it commandable * - added a synchro counter in HK * - new parameters value for DMC_SYNCHRONIZE_ON_DET to avoid using the * synchro to trigger the mechanisms move * - In photo, the RedSpuTransmission mode was not copied into red science * headers. It is now corrected * * 40 3/14/06 4:31p 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" //**************************************************************** // MACRO //**************************************************************** //macro to signal an error in BOL ReceiverTask #define SetError(newError) \ {\ SetGlobalError(newError);\ LOCK_WRITE_RES_PARAMS;\ SET_BITS(gpBolRec->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;\ }\ //**************************************************************** // LOCAL TYPES DEFINITION //**************************************************************** //**************************************************************** // GLOBAL VARIABLES //**************************************************************** //values used when generating pixel values int gaSimulatedValue[5] = {(100 << 16) + 100, (250 << 16) + 250, (270 << 16) + 270, (280 << 16) + 280, (295 << 16) + 295}; //**************************************************************** // FUNCTION DECLARATION //**************************************************************** void InitializeBolRec(); void BolRec(); //**************************************************************** // FUNCTION IMPLEMENTATION //**************************************************************** /* FUNCTION : void InitializeBolRec() ********************************** AUTHOR : AMazy USE : Initialize Bol Receiver task. */ void InitializeBolRec() { LOCK_WRITE_RES_PARAMS; gpBolRec->Options = K_BMASK_DET_REC_OPTIONS_DELETE_DATA; //BOLC does not forward data to SPU by default gpBolRec->PacketCounter = 0; gpBolRec->ReadoutCounter = 0; gpBolRec->BlueBufferToFill = 0; gpBolRec->RedBufferToFill = 0; // initialize task status gpBolRec->TaskStatus = K_BMASK_TASK_STATUS_ALIVE | K_BMASK_TASK_STATUS_NO_ERROR_IN_TASK | K_BMASK_TASK_STATUS_LINK_NOT_CONNECTED; UNLOCK_WRITE_RES_PARAMS; LOCK_READ_RES_PARAMS; // wait that the BOL initializes the connection on the other side // or that a detector simulator is started while (!IS(gpBolRec->TaskStatus, K_BMASK_TASK_STATUS_LINK_STATUS, K_BMASK_TASK_STATUS_LINK_CONNECTED) && IS(gpBolRec->TaskStatus, K_BMASK_SIMULATION, K_BMASK_REAL_TIMING)) { UNLOCK_READ_RES_PARAMS; KS_TaskSleep(1000); LOCK_READ_RES_PARAMS; } UNLOCK_READ_RES_PARAMS; } /* TASK_FUNCTION : BolRec() ************************ AUTHOR : AMazy This function implements the BOL Receiver task. It listen to the 1335 link. Each time a packet is received from BOLC, the science data and hk are extracted. The information is then forwarded to the packet encoders. */ void BolRec() { SequencerMsg msgSequencer; // used to send messages to the Sequencer PacketEncoderMessage msgPacketEncoder; // used to send messages to the PacketEncoder int receptionBuffer[SIZE_OF_PHOTO_PACKET_IN_WORDS]; int simulationBlockNum = 0; int simulationFormatNum = 0; BOOL bSimulateReadouts = FALSE; BOOL bSendDataToPacketEncoder = FALSE; InitializeBolRec(); while (1) { // wait for the next readout #ifdef SIMULATOR KS_SemaTestW(9); #else //SIMULATOR Link1355Read(CHANNEL_BOL, SIZE_OF_PHOTO_PACKET_IN_WORDS, receptionBuffer); #endif //SIMULATOR //centralizes all access to the param structure here to avoid some expensive LOCK/UNLOCK LOCK_READ_RES_PARAMS; bSimulateReadouts = IS(gpBolRec->TaskStatus, K_BMASK_SIMULATION_DATA, K_BMASK_SIMULATED_READOUTS); bSendDataToPacketEncoder = IS(gpBolRec->Options, K_BMASK_DET_REC_OPTIONS_DATA_OPERATION, K_BMASK_DET_REC_OPTIONS_FORWARD_DATA); UNLOCK_READ_RES_PARAMS; if (bSimulateReadouts) { receptionBuffer[0] = 0x00008400; receptionBuffer[0] |= simulationBlockNum << 12; receptionBuffer[0] |= simulationFormatNum & 0x0000003F; simulationBlockNum++; if (simulationBlockNum == 5) { simulationBlockNum = 0; simulationFormatNum++; if (simulationFormatNum == 0x3F) { simulationFormatNum = 0; } } } //increments packet counter gpBolRec->PacketCounter++; if (receptionBuffer[0] & 0x00008000) //it is a data packet { int blockNum = (receptionBuffer[0] & 0x00007000) >> 12; gpBolRec->BolcStatusWord = receptionBuffer[0] & 0x0000FFFF; if (blockNum == 0) // generate the headers { // first check if we need to swap the buffers if (KS_EventTest(EVENT_BLUE_DET_RECEIVER_TOGGLE_BUFFER) == RC_OK) { gpBolRec->BlueBufferToFill = (gpBolRec->BlueBufferToFill+1) %2; } if (KS_EventTest(EVENT_RED_DET_RECEIVER_TOGGLE_BUFFER) == RC_OK) { gpBolRec->RedBufferToFill = (gpBolRec->RedBufferToFill+1) %2; } // generate all the headers now GeneratePhotoPacketHeader(&(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][0]), BLUE_SPU_APID); gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][0].DataBlockId = 1; MEMCPY(&(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][1]), &(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][0]), 16); gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][1].DataBlockId = 2; MEMCPY(&(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][2]), &(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][0]), 16); gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][2].DataBlockId = 3; MEMCPY(&(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][3]), &(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][0]), 16); gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][3].DataBlockId = 4; //do the same for red MEMCPY(&(gaRedPhotoPacketBuffer[gpBolRec->RedBufferToFill]), &(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][0]), 16); gaRedPhotoPacketBuffer[gpBolRec->RedBufferToFill].DataBlockId = 5; gaRedPhotoPacketBuffer[gpBolRec->RedBufferToFill].APID = RED_SPU_APID; gaRedPhotoPacketBuffer[gpBolRec->RedBufferToFill].Validity = gpBolController->ReadoutValidityRed; gaRedPhotoPacketBuffer[gpBolRec->RedBufferToFill].CompressionParameters = gParameters.RedSpuTransmissionMode; } if (blockNum < 4) // if the packet contains data from the blue detector { // copy the data into the blue buffer MEMCPY(&(gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][blockNum].ScienceData[0]), &(receptionBuffer[1]), 256); } else { //copy the data into the red buffer MEMCPY(&(gaRedPhotoPacketBuffer[gpBolRec->RedBufferToFill].ScienceData[0]), &(receptionBuffer[1]), 256); } if (blockNum == 0) { gpBolRec->ReadoutCounter++; // if Diagnostic Hk is being acquired now and if it is synchronized with this detector, if (gpHkDiagnosticController->HkDiagnosticPeriodCommanded == BOL) { // ask the HkDiagController to perform its measurements KS_SemaSignal(SEMA_TIMER_HOUSEKEEPING_DIAGNOSTIC); } // send synchronization signal to the Sequencer if (IS(gpSequencer->Options, DETECTOR_MASK, BOL)) { msgSequencer.Type = SEQUENCE_SYNCHRO; KS_FIFOPut(SEQUENCER_FIFO, &msgSequencer); } } else if (blockNum == 4) // if this is the last packet for this readout { if (bSendDataToPacketEncoder) { // if we want to send simulated readouts if (IS(gpBolRec->TaskStatus, K_BMASK_SIMULATION_DATA, K_BMASK_SIMULATED_READOUTS)) { static int simulatedImageCounter = 0; int i=0, j=0; // copy the simulated data in the buffer // generate the simulated data in the buffer // Mail from Helmut : //- Store 5 complete images with the following values: //100, 250, 270, 280, 295 //- In the test mode you should then send always one image after the //other and after image 5 you start again with image 1. if (simulatedImageCounter == 5) { simulatedImageCounter = 0; } for (j=0; j < 4; ++j) { for (i=0; i < 256; ++i) { gaBluePhotoPacketBuffer[gpBolRec->BlueBufferToFill][j].ScienceData[i] = gaSimulatedValue[simulatedImageCounter]; } } for (i=0; i < 256; ++i) { gaRedPhotoPacketBuffer[gpBolRec->RedBufferToFill].ScienceData[i] = gaSimulatedValue[simulatedImageCounter]; } simulatedImageCounter++; } //send them to the packet encoder msgPacketEncoder.Type = BOL_BLUE; msgPacketEncoder.BufferId = gpBolRec->BlueBufferToFill; if (gParameters.BluePacketEncoderLink == CHANNEL_BLUE_SPU) { KS_FIFOPut(BLUE_PACKET_ENCODER_FIFO, &msgPacketEncoder); } else { KS_FIFOPut(RED_PACKET_ENCODER_FIFO, &msgPacketEncoder); } msgPacketEncoder.Type = BOL_RED; msgPacketEncoder.BufferId = gpBolRec->RedBufferToFill; if (gParameters.RedPacketEncoderLink == CHANNEL_RED_SPU) { KS_FIFOPut(RED_PACKET_ENCODER_FIFO, &msgPacketEncoder); } else { KS_FIFOPut(BLUE_PACKET_ENCODER_FIFO, &msgPacketEncoder); } } } } else // we have received a Hk packet { int i=0; // note : each 16bits word is copied into a 32bits word. for (i=0; i < NB_BOLC_HK_ENTRIES; ++i) { gpBolRec->HkArray[i] = (((i%2) == 0) ? ((receptionBuffer[1 + i/2] >> 16) & 0x0000FFFF) : (receptionBuffer[1 + i/2] & 0x0000FFFF)); } } } }