/************************************************************************* $Archive: /PACS/OnBoard/hk.c $ $Revision: 1.13 $ $Date: 2009/04/23 13:51:12 $ $Author: amazy $ $Log: hk.c,v $ Revision 1.13 2009/04/23 13:51:12 amazy 6.029 * * 11 2/07/07 11:30a Amazy * - The open loop code for the grating has been updated and validated on * DMC FM with QM grating * - The position limit error is now signaled in the chopper controller * (error code 0x0b15). The position limit * is stored in the field 'scaling' of the chopper pid controller. Its * default value is 0x7FFFFFFF. * * 10 12/13/06 2:27p Amazy * Updated the checksum computation to be compatible with DPU computation * * 9 12/11/06 3:34p Amazy * corrected checksum computation * * 8 12/11/06 11:49a Amazy * introduced checksum in DMC HK * * 7 11/12/06 11:04 Amazy * * 87 3/14/06 4:31p Pacs Egse * Version 6.001 * Cleaned and commented *************************************************************************/ #ifdef SIMULATOR #include "virtuosoSim.h" #include "stdio.h" #else // SIMULATOR #include "v_macro.h" #include "node1.h" #include "k_struct.h" __asm("#include ;"); #endif #include "params.h" #include "error.h" #include "u_bits.h" #include "u_res.h" #include "crc.h" #ifndef SIMULATOR #include "m_smcsge.h" #include "l_memory.h" #endif //SIMULATOR extern int gaLinkStatus[]; // array containing the status of each of the 1355 link extern int gSmcs2IsrCount; extern int gSmcs2IsrHandledCount; extern int gLastSmcs2ISR; extern int gLastSmcs2IMR; extern int gaBlueDecPixelsInHkDiag[]; extern int gaRedDecPixelsInHkDiag[]; extern int gCalSrc500msPeriodCounter; //**************************************************************** // MACRO //**************************************************************** //macro to signal an error in HK Controller Task #define SetError(newError) \ {\ SetGlobalError(newError);\ LOCK_WRITE_RES_PARAMS;\ SET_BITS(gpHkController->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;\ } //macro to clear an error that has been signaled #define CLEAR_SIGNALED_ERROR(taskStatus) \ {\ if (IS(taskStatus, K_BMASK_TASK_STATUS_ERROR_STATUS, K_BMASK_TASK_STATUS_ERROR_SIGNALED))\ {\ CLEAR_BIT(taskStatus, K_BMASK_TASK_STATUS_ERROR_STATUS | K_BMASK_TASK_STATUS_ERROR_CODE); \ }\ } //macro to signal an error in the task status #define SIGNAL_ERROR(taskStatus) \ {\ if (IS(taskStatus, K_BMASK_TASK_STATUS_ERROR_STATUS, K_BMASK_TASK_STATUS_ERROR_NOT_SIGNALED))\ {\ SET_BITS(taskStatus, K_BMASK_TASK_STATUS_ERROR_STATUS, K_BMASK_TASK_STATUS_ERROR_SIGNALED); \ }\ } //**************************************************************** // FUNCTION DECLARATION //**************************************************************** void InitializeHkController(); void Hk(); void PerformHkAcquisitions(HkMode mode, int* p_taskStatus, int* p_hkList, int* p_hkBuffer, int* p_currentPosInBuffer, int maxSizeOfHkBuffer); void GetSizeOfSample(int* p_hkList, int* p_sizeOfSample, int* p_nbMeasureBySample); void MemoryScrubbing(); extern void pmpsc_isr(); // commands functions BOOL CommandStartHk(CommandParameter param); // hk acquisitions functions void HkGetCpuWorkload(); void HkGetGlobalStatus(); void HkGetChopperControllerStatus(); void HkGetGratingControllerStatus(); void HkGetFWSpecControllerStatus(); void HkGetFWPhotoControllerStatus(); void HkGetCS1ControllerStatus(); void HkGetCS2ControllerStatus(); //**************************************************************** // LOCAL PARAMETERS //**************************************************************** static DpuSenderMsg DpuSendMsg; // used to send messages to DpuSender K_TIMER* gpHkGeneralTimer = NULL; #undef HK_MEASURE #define HK_MEASURE(HkMode, HkId, Variable, SizeWords, SizeBytes, Function, Display, ValidityAtStartup) {(int*)&(Variable), SizeWords, SizeBytes, Function, ValidityAtStartup}, HkMeasureDescription gaHkMeasure[NB_HK_MEASURES] = { #include "hkList.h" }; // gaNominalHkList contains the IDs of all the nominal HKmeasures #undef HK_MEASURE #define HK_MEASURE(HkMode, HkId, Variable, SizeWords, SizeBytes, Function, Display, ValidityAtStartup) HkId, static int gaNominalHkList[NB_HK_MEASURES+1] = { #include "HkList.h" END_OF_HK_LIST }; #undef HK_MEASURE #define HK_MEASURE(HkMode, HkId, Variable, SizeWords, SizeBytes, Function, Display, ValidityAtStartup) HkMode, static HkMode gaHkMode[NB_HK_MEASURES] = { #include "HkList.h" }; //**************************************************************** // GLOBAL VARIABLES //**************************************************************** int gHkPacketBuffer[MAXIMUM_SIZE_OF_HK_PACKET_IN_WORDS]; // this buffer is shared between HkController and DpuSender (it is protected by EVENT_HK_PACKET_BUFFER_AVAILABLE) int gDummyVariable = 0; // this variable is only used to be referenced by the spare entries of the Hk Measure table. int gaCustomHkEntry[10]; // array in which the custom Hk entries will be copied. //**************************************************************** // FUNCTION IMPLEMENTATION //**************************************************************** /* FUNCTION : void InitializeHkController() **************************************** AUTHOR : AMazy USE : initializes the Housekeeping Controller */ void InitializeHkController() { int i=0; // initialize task status LOCK_WRITE_RES_PARAMS; gpHkController->TaskStatus = K_BMASK_TASK_STATUS_ALIVE | K_BMASK_TASK_STATUS_NO_ERROR_IN_TASK; UNLOCK_WRITE_RES_PARAMS; // initialize the message to be sent to the DpuSender // this message is always the same so we initialize it only once DpuSendMsg.Header = HK_PACKET; // note : Field1 is not used #ifndef SIMULATOR KS_WorkloadSetPeriod(TICKFREQ); // measure CPU Workload every second #endif //SIMULATOR // finalize the initialization of the static array containing all nominal values gaNominalHkList[LAST_NOMINAL_HK_VALUE] = END_OF_HK_LIST; //initialize MemoryScrubbing gpMemoryScrubbing->dmAddress = 0; gpMemoryScrubbing->pmAddress = 0; gpMemoryScrubbing->indexNextSfDmCorruptedAddress = 0; gpMemoryScrubbing->indexNextSfPmCorruptedAddress = 0; gpMemoryScrubbing->indexNextDfDmCorruptedAddress = 0; gpMemoryScrubbing->indexNextDfPmCorruptedAddress = 0; for (i = 0; i < MEMORY_SCRUBBING_BUFFER_SIZE; i++) { gpMemoryScrubbing->lastSfDmCorruptedAddresses[i] = 0; gpMemoryScrubbing->lastSfPmCorruptedAddresses[i] = 0; gpMemoryScrubbing->lastDfDmCorruptedAddresses[i] = 0; gpMemoryScrubbing->lastDfPmCorruptedAddresses[i] = 0; } #ifndef SIMULATOR //enable DM EDAC interrupts *((int*)K_DMADD_DMPSC_INTMASK) &= 0xFFFFBFFE; //enable PM EDAC interrupts *((int*)K_PMADD_PMPSC_INTMASK) &= 0xFFFFBFFE; // enable PMPSC interrupt (IRQ0) KS_IRQSetHandler(8, pmpsc_isr); // 7 is the bit number of IRQ1 in IMASK // IRQ0 must be level sensitive interrupt __asm(" bit clr MODE2 IRQ0E;"); // must be level sensitive interrupt __asm(" nop;"); KS_ISREnable(8); #endif //SIMULATOR } /* TASK_FUNCTION : void Hk() ************************* AUTHOR : AMazy This function implements the nominal houskeeping task. It is awaken every 2 seconds by a Virtuoso Timer. Perform a nominal hk acquisition and sends the packet to DPU Sender task. */ void Hk() { static int CurrentSizeOfPacket = 0; static uint LastIsrCount = 0; uint crc = 0; uint i = 0; InitializeHkController(); while (1) { // wait the right time to perform the housekeeping measurement KS_SemaTestW(SEMA_TIMER_HOUSEKEEPING_GENERAL); KS_SemaReset(SEMA_TIMER_HOUSEKEEPING_GENERAL); //this is to avoid to receive lots of packets if there has been a long time between the previous packet and this one // wait that the gHkPacketBuffer has been sent to the DPU by the DpuSender KS_EventTestW(EVENT_HK_PACKET_BUFFER_AVAILABLE); // read a small part of the memory every 2 seconds to detect errors MemoryScrubbing(); //mark all the errors in tasks as signaled (they will be included in this HK packet) LOCK_WRITE_RES_PARAMS; SIGNAL_ERROR(gpDpuRec->TaskStatus); SIGNAL_ERROR(gpDpuSend->TaskStatus); SIGNAL_ERROR(gpBlueDecController->TaskStatus); SIGNAL_ERROR(gpBlueDecRec->TaskStatus); SIGNAL_ERROR(gpBluePacketEncoder->TaskStatus); SIGNAL_ERROR(gpRedDecController->TaskStatus); SIGNAL_ERROR(gpRedDecRec->TaskStatus); SIGNAL_ERROR(gpRedPacketEncoder->TaskStatus); SIGNAL_ERROR(gpChopperPidController->TaskStatus); SIGNAL_ERROR(gpGratingPidController->TaskStatus); SIGNAL_ERROR(gpCS1Controller->TaskStatus); SIGNAL_ERROR(gpCS2Controller->TaskStatus); SIGNAL_ERROR(gpFWSpecController->TaskStatus); SIGNAL_ERROR(gpFWPhotoController->TaskStatus); SIGNAL_ERROR(gpHkController->TaskStatus); SIGNAL_ERROR(gpHkDiagnosticController->TaskStatus); SIGNAL_ERROR(gpSequencer->TaskStatus); SIGNAL_ERROR(gpBolRec->TaskStatus); SIGNAL_ERROR(gpBolController->TaskStatus); SIGNAL_ERROR(gParameters.GlobalStatus); UNLOCK_WRITE_RES_PARAMS; PerformHkAcquisitions(HK_NOM, &(gpHkController->TaskStatus), gaNominalHkList, gHkPacketBuffer, &CurrentSizeOfPacket, 510); //the Global Status might have been modified during the HK acquisition so, we copy it again here gHkPacketBuffer[DMC_SW_GLOBAL_ST] = gParameters.GlobalStatus; DpuSendMsg.Field1.Length = CurrentSizeOfPacket; CurrentSizeOfPacket = 0; //reset the error status of each of the task LOCK_WRITE_RES_PARAMS; CLEAR_SIGNALED_ERROR(gpDpuRec->TaskStatus); CLEAR_SIGNALED_ERROR(gpDpuSend->TaskStatus); CLEAR_SIGNALED_ERROR(gpBlueDecController->TaskStatus); CLEAR_SIGNALED_ERROR(gpBlueDecRec->TaskStatus); CLEAR_SIGNALED_ERROR(gpBluePacketEncoder->TaskStatus); CLEAR_SIGNALED_ERROR(gpRedDecController->TaskStatus); CLEAR_SIGNALED_ERROR(gpRedDecRec->TaskStatus); CLEAR_SIGNALED_ERROR(gpRedPacketEncoder->TaskStatus); CLEAR_SIGNALED_ERROR(gpChopperPidController->TaskStatus); CLEAR_SIGNALED_ERROR(gpGratingPidController->TaskStatus); CLEAR_SIGNALED_ERROR(gpCS1Controller->TaskStatus); CLEAR_SIGNALED_ERROR(gpCS2Controller->TaskStatus); CLEAR_SIGNALED_ERROR(gpFWSpecController->TaskStatus); CLEAR_SIGNALED_ERROR(gpFWPhotoController->TaskStatus); CLEAR_SIGNALED_ERROR(gpHkController->TaskStatus); CLEAR_SIGNALED_ERROR(gpHkDiagnosticController->TaskStatus); CLEAR_SIGNALED_ERROR(gpSequencer->TaskStatus); CLEAR_SIGNALED_ERROR(gpBolRec->TaskStatus); CLEAR_SIGNALED_ERROR(gpBolController->TaskStatus); CLEAR_SIGNALED_ERROR(gParameters.GlobalStatus); UNLOCK_WRITE_RES_PARAMS; //compute and update the value of the frequency that is used by the PID loops if (gpMim->IsrCount > LastIsrCount) { gpMim->Freq = (gpMim->IsrCount - LastIsrCount)/2; } LastIsrCount = gpMim->IsrCount; //reset the 'receiving synchro' bit in IsrStat (If this bit is not set to one by the ISR, it means that //no sync is received). CLEAR_BIT(gpMim->IsrStat, K_BMASK_MIM_SYNC_FLAG); //compute the checksum crc=0xFFFFFFFF; for (i = 0; i < DMC_CHECKSUM; i++) { crc = Crc32(gHkPacketBuffer[i], crc); } for (i = DMC_CHECKSUM+1; i < LAST_NOMINAL_HK_VALUE; i++) { crc=Crc32(gHkPacketBuffer[i], crc); } gHkPacketBuffer[DMC_CHECKSUM] = crc; //signal DPU Sender that a new HkPacket is available KS_FIFOPut(DPUSENDER_FIFO, &DpuSendMsg); } }; /* CMD_FUNCTION : BOOL CommandStartHk(CommandParameter paramNotUsed) ***************************************************************** AUTHOR : Amazy USE : Internal function used to test that the on board software is working properly. This message is sent from the DPU Receiver to the Sequencer, then to the HkController. If everything works fine, the HkController will start the acquisition of the default parameters. PARAMS : Not used. */ BOOL CommandStartHk(CommandParameter paramNotUsed) { gpHkGeneralTimer = KS_LowTimerGet(); if (gpHkGeneralTimer == NULL) { SetError(ERR_HK_COULD_NOT_CREATE_HK_TIMER); } else { // timer has been allocated, we can initialize it KS_LowTimerStart(gpHkGeneralTimer, TICKFREQ*2, TICKFREQ*2, SEMA_TIMER_HOUSEKEEPING_GENERAL); } return FALSE; } /* FUNCTION : void PerformHkAcquisitions(HkMode mode, int* p_taskStatus, int* p_hkList, int* p_hkBuffer, int* p_currentPosInBuffer, int sizeOfHkBuffer) **************************************************************************************************************************************************** AUTHOR : Amazy USE : This function is used by both the HkController and the HkDiagController to perform the acquisition. For each of the measures included in the pHkList, this function will either copy the current value or call a given function to perform the acquisition. RETURN VALUE : the number of words that have been filled in p_hkBuffer PARAMS : mode : specifies if we are in HK_NOM or in HK_DIAG p_taskStatus : a pointer to the status of the task that is calling the function (to store the error code if there is one) p_hkList : An array containing the IDs of the measure to include in the HkPacket (terminated by END_OF_HK_LIST) p_hkBuffer : The Hk Packet Buffer to fill p_currentPosInBuffer : The current position in p_hkBuffer (unit is words when we are in HK_NOM and bytes in HK_DIAG) maxSizeOfHkBuffer : the size of pHkBuffer (unit is words when we are in HK_NOM and bytes in HK_DIAG) */ void PerformHkAcquisitions(HkMode mode, int* p_taskStatus, int* p_hkList, int* p_hkBuffer, int* p_currentPosInBuffer, int maxSizeOfHkBuffer) { int i = 0; int j = 0; int value = 0; while ((p_hkList[i] != END_OF_HK_LIST) && (*p_currentPosInBuffer < maxSizeOfHkBuffer)) { // test if the id is valid if (p_hkList[i] >= NB_HK_MEASURES) { // Raise an error in the concerned task int error = ERR_HK_INVALID_MEASURE_ID; KS_CriticalSection(AddErrorInBuffer, (void*)&error); SET_BITS(*p_taskStatus, K_BMASK_TASK_STATUS_ERROR_STATUS | K_BMASK_TASK_STATUS_ERROR_CODE, K_BMASK_TASK_STATUS_TASK_IN_ERROR + ERR_HK_INVALID_MEASURE_ID); return; } else { value = GetHkValue(p_hkList[i]); //then, copy the value in the buffer. //Note : alignement is different if we are in Hk Nominal or Hk Diagnostic switch (mode) { case HK_NOM : { // if the measure is available in nominal mode if (TEST_ONE_BIT(gaHkMode[p_hkList[i]], HK_NOM)) { p_hkBuffer[*p_currentPosInBuffer] = value; // increments index (*p_currentPosInBuffer)++; } };break; case HK_DIAG : { //if the measure is available in diagnostic mode if (TEST_ONE_BIT(gaHkMode[p_hkList[i]], HK_DIAG)) { // copy each byte of the measure in the buffer separately for (j=gaHkMeasure[p_hkList[i]].SizeInBytes-1; j >=0 ; j--) { // sets the 8 concerned bits of destination to zero. p_hkBuffer[(*p_currentPosInBuffer)/4] &= ~(0x000000FF << (3 - (*p_currentPosInBuffer)%4)*8); // extract the 8 concerned bits of source, shift them to LSB, put zero // in the 24 MSB, shift them to the right place and the result to the buffer p_hkBuffer[(*p_currentPosInBuffer)/4] += (((value) >> j*8) & 0x000000FF) << ((3 - (*p_currentPosInBuffer)%4)*8); (*p_currentPosInBuffer)++; } } else { SetError(ERR_HK_MEASURE_NOT_AVAILABLE_IN_DIAG_MODE); } };break; default: break; } } i++; } } /* FUNCTION : void GetSizeOfSample(int* p_hkList, int* p_sizeOfSample, int* p_nbMeasureBySample) ********************************************************************************************* AUTHOR : Amazy USE : This function is used by the HkDiagController to compute the size of a diagnostic sample. RETURN VALUE (by reference on parameters) : int* p_sizeOfSample : the size (in bytes) of a sample int* p_nbMeasureBySample : the number of measure in a sample PARAMS : mode : specifies if we are in HK_NOM or in HK_DIAG p_hkList : An array containing the IDs of the measure to include in the HkDiagPacket (terminated by END_OF_HK_LIST) */ void GetSizeOfSample(int* p_hkList, int* p_sizeOfSample, int* p_nbMeasureBySample) { *p_sizeOfSample = 0; *p_nbMeasureBySample = 0; while (p_hkList[*p_nbMeasureBySample] != END_OF_HK_LIST) { *p_sizeOfSample += gaHkMeasure[gpHkDiagnosticController->HkDiagList[*p_nbMeasureBySample]].SizeInBytes; (*p_nbMeasureBySample)++; } } /* FUNCTION : int GetHkValue(int hkId) *********************************** AUTHOR : Amazy USE : This function is used by the PerformHkAcquisitions and any other functions that needs a HK value (i.e. to build a header). It first check the validity of the measure and if it is valid, acquire this value. It is mandatory to use this function each time you want to copy a variable that can be invalid. RETURN VALUE : the value of the measure requested PARAMS : hkId : the ID of the measure requested */ int GetHkValue(int hkId) { int value; if (gaHkMeasure[hkId].Valid) { // if this measure needs to call a special function to be measured, if (gaHkMeasure[hkId].AcquisitionFunction != NULL) { // call the function to perform the acquisition gaHkMeasure[hkId].AcquisitionFunction(); } value = *((int*)(gaHkMeasure[hkId].pVariable)); } else { value = 0xFFFFFFFF; } return value; } /* FUNCTION : void MemoryScrubbing() ********************************* AUTHOR : Amazy USE : This function is used to cycle through all the memory area to make EDAC correct all errors. It is called by the HK task (once every 2 seconds) and check a few words in DM, PM and EEPROM at each cycle. */ void MemoryScrubbing() { #ifndef SIMULATOR int i=0; const unsigned int nbChecks = 32; // read DM for (i = gpMemoryScrubbing->dmAddress; i < (gpMemoryScrubbing->dmAddress + nbChecks); i++) { MEM_ReadDMWord(i); } gpMemoryScrubbing->dmAddress += nbChecks; if (gpMemoryScrubbing->dmAddress >= 0x0007FFFF) { gpMemoryScrubbing->dmAddress = 0; } // read PM and EEPROM for (i = gpMemoryScrubbing->pmAddress; i < (gpMemoryScrubbing->pmAddress + nbChecks); i++) { MEM_ReadPM32bitMSWord(i); } gpMemoryScrubbing->pmAddress += nbChecks; if (gpMemoryScrubbing->pmAddress >= 0x0007FFFF) { if (gpMemoryScrubbing->pmAddress < 0x000E0000) { gpMemoryScrubbing->pmAddress = 0x000E0000; } else if (gpMemoryScrubbing->pmAddress > 0x0011FFFF) { gpMemoryScrubbing->pmAddress = 0; } } #endif //SIMULATOR } /* HK_FUNCTION : void HkGetCpuWorkload() ************************************* AUTHOR : AMazy USE : used by the PerformHkAcquisitions function to store the current CPU workload in the parameters buffer */ void HkGetCpuWorkload() { #ifndef SIMULATOR gParameters.CpuWorkload = KS_WorkloadRead(); #endif //SIMULATOR } /* HK_FUNCTION : void HkGetGlobalStatus() ************************************** AUTHOR : AMazy USE : used by the PerformHkAcquisitions function to compute the current GlobalStatus of the onboard software. This status indicates whether the application is still alive or not. */ void HkGetGlobalStatus() { LOCK_WRITE_RES_PARAMS; SET_BITS(gParameters.GlobalStatus, K_BMASK_OBS_STATUS, K_BMASK_TASK_STATUS_ALIVE); if (gParameters.CopyInEepromInProgress) { SET_BIT(gParameters.GlobalStatus, K_BMASK_OBS_STATUS_COPY_IN_EEPROM); } else { CLEAR_BIT(gParameters.GlobalStatus, K_BMASK_OBS_STATUS_COPY_IN_EEPROM); } UNLOCK_WRITE_RES_PARAMS; } /* HK_FUNCTION : void CheckPidController(PidControllerParams* pid, int pidErrorBit) ******************************************************************************** AUTHOR : AMazy USE : used by the PerformHkAcquisitions function to compute the status of pid controllers */ void CheckPidController(PidControllerParams* pid, int pidErrorBit) { //clear the error status bits SET_BITS(pid->TaskStatus, K_BMASK_TASK_STATUS_ERROR_CODE | K_BMASK_TASK_STATUS_ERROR_STATUS, NONE | K_BMASK_TASK_STATUS_NO_ERROR_IN_TASK); // copy status and results bits from Pid Status SET_BITS(pid->TaskStatus, K_BMASK_PID_CTRL_STATUS_TO_COPY_IN_TASK, pid->PidStatus) // check the following error and if present, include the error code in the task status if (TEST_ONE_BIT(pid->PidStatus, K_BMASK_PID_CTRL_STATUS_FOLLOWING_ERROR)) { SetErrorIn(pid->TaskStatus, ERR_MEC_CONTROLLER_FOLLOWING_ERROR + pidErrorBit); CLEAR_BIT(pid->PidStatus, K_BMASK_PID_CTRL_STATUS_FOLLOWING_ERROR); } else if (TEST_ONE_BIT(pid->PidStatus, K_BMASK_PID_CTRL_STATUS_POWER_LIMIT_ERROR)) { SetErrorIn(pid->TaskStatus, ERR_MEC_CONTROLLER_POWER_LIMIT_ERROR + pidErrorBit); CLEAR_BIT(pid->PidStatus, K_BMASK_PID_CTRL_STATUS_POWER_LIMIT_ERROR); } else if (TEST_ONE_BIT(pid->PidStatus, K_BMASK_PID_CTRL_STATUS_POSITION_ERROR)) { SetErrorIn(pid->TaskStatus, ERR_MEC_CONTROLLER_POSITION_ERROR + pidErrorBit); CLEAR_BIT(pid->PidStatus, K_BMASK_PID_CTRL_STATUS_POSITION_ERROR); } } /* HK_FUNCTION : void HkGetChopperControllerStatus() ************************************************* AUTHOR : AMazy USE : used by the PerformHkAcquisitions function to compute the current TaskStatus of the chopper controller. */ void HkGetChopperControllerStatus() { //check limits (error, accumulator, ...) and generate error if needed CheckPidController(&(gParameters.ChopperController.PidController), ERR_CHOPPER_CONTROLLER_ERROR_BIT); } /* HK_FUNCTION : void HkGetGratingControllerStatus() ************************************************* AUTHOR : AMazy USE : used by the PerformHkAcquisitions function to compute the current TaskStatus of the grating controller. */ void HkGetGratingControllerStatus() { if (TEST_ONE_BIT(gpGratingPidController->PidStatus, K_BMASK_GRAT_CTRL_STATUS_DEGRADED_MODE)) { CLEAR_BIT(gpGratingPidController->PidStatus, K_BMASK_PID_CTRL_STATUS_MOVING_UP | K_BMASK_PID_CTRL_STATUS_MOVING_DOWN); if (gpGratingController->DegModeIsMoving != 0) { if (gpGratingController->DegModeCurrentInc > 0) { SET_BIT(gpGratingPidController->PidStatus, K_BMASK_PID_CTRL_STATUS_MOVING_UP); } else { SET_BIT(gpGratingPidController->PidStatus, K_BMASK_PID_CTRL_STATUS_MOVING_DOWN); } } } //check limits (error, accumulator, ...) and generate error if needed CheckPidController(&(gParameters.GratingController.PidController), ERR_GRATING_CONTROLLER_ERROR_BIT); }