LCOV - code coverage report
Current view: top level - src/tc_tm - tc_handler.c (source / functions) Hit Total Coverage
Test: trace.info Lines: 349 501 69.7 %
Date: 2023-02-20 11:47:17 Functions: 29 40 72.5 %

          Line data    Source code
       1             : /*------------------------------------------------------------------------------
       2             : --  Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
       3             : --  This file is a part of the LFR FSW
       4             : --  Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
       5             : --
       6             : --  This program is free software; you can redistribute it and/or modify
       7             : --  it under the terms of the GNU General Public License as published by
       8             : --  the Free Software Foundation; either version 2 of the License, or
       9             : --  (at your option) any later version.
      10             : --
      11             : --  This program is distributed in the hope that it will be useful,
      12             : --  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : --  GNU General Public License for more details.
      15             : --
      16             : --  You should have received a copy of the GNU General Public License
      17             : --  along with this program; if not, write to the Free Software
      18             : --  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      19             : -------------------------------------------------------------------------------*/
      20             : /*--                  Author : Paul Leroy
      21             : --                   Contact : Alexis Jeandet
      22             : --                      Mail : alexis.jeandet@lpp.polytechnique.fr
      23             : ----------------------------------------------------------------------------*/
      24             : /** Functions and tasks related to TeleCommand handling.
      25             :  *
      26             :  * @file
      27             :  * @author P. LEROY
      28             :  *
      29             :  * A group of functions to handle TeleCommands:\n
      30             :  * action launching\n
      31             :  * TC parsing\n
      32             :  * ...
      33             :  *
      34             :  */
      35             : 
      36             : #include <math.h>
      37             : #include <string.h>
      38             : 
      39             : #include "fsw_compile_warnings.h"
      40             : #include "fsw_debug.h"
      41             : #include "fsw_housekeeping.h"
      42             : #include "hw/lfr_regs.h"
      43             : #include "tc_tm/tc_handler.h"
      44             : 
      45             : //***********
      46             : // RTEMS TASK
      47             : 
      48           1 : LFR_NO_RETURN rtems_task actn_task(rtems_task_argument unused)
      49             : {
      50             :     /** This RTEMS task is responsible for launching actions upton the reception of valid
      51             :      * TeleCommands.
      52             :      *
      53             :      * @param unused is the starting argument of the RTEMS task
      54             :      *
      55             :      * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it
      56             :      * launches specific actions depending on the incoming TeleCommand.
      57             :      *
      58             :      */
      59             : 
      60             :     IGNORE_UNUSED_PARAMETER(unused);
      61           1 :     int result = LFR_SUCCESSFUL;
      62             :     rtems_status_code status; // RTEMS status code
      63             :     ccsdsTelecommandPacket_t __attribute__((aligned(4))) TC; // TC sent to the ACTN task
      64           1 :     size_t size = 0; // size of the incoming TC packet
      65           1 :     unsigned char subtype = 0; // subtype of the current TC packet
      66             :     unsigned char time[BYTES_PER_TIME];
      67           1 :     rtems_id queue_rcv_id = RTEMS_ID_NONE;
      68           1 :     rtems_id queue_snd_id = RTEMS_ID_NONE;
      69             : 
      70           1 :     memset(&TC, 0, sizeof(ccsdsTelecommandPacket_t));
      71             : 
      72           1 :     DEBUG_CHECK_STATUS(get_message_queue_id_recv(&queue_rcv_id));
      73           1 :     DEBUG_CHECK_STATUS(get_message_queue_id_send(&queue_snd_id));
      74             : 
      75             :     BOOT_PRINTF("in ACTN *** \n");
      76             : 
      77             :     while (1)
      78             :     {
      79          28 :         status = rtems_message_queue_receive(
      80             :             queue_rcv_id, (char*)&TC, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
      81             :         DEBUG_CHECK_STATUS(status);
      82          28 :         getTime(time); // set time to the current time
      83          28 :         if (status == RTEMS_SUCCESSFUL)
      84             :         {
      85          28 :             subtype = TC.serviceSubType;
      86          28 :             switch (subtype)
      87             :             {
      88             :                 case TC_SUBTYPE_RESET:
      89           1 :                     result = action_reset();
      90           0 :                     close_action(&TC, result, queue_snd_id);
      91           0 :                     break;
      92             :                 case TC_SUBTYPE_LOAD_COMM:
      93           0 :                     result = action_load_common_par(&TC);
      94           0 :                     close_action(&TC, result, queue_snd_id);
      95           0 :                     break;
      96             :                 case TC_SUBTYPE_LOAD_NORM:
      97           0 :                     result = action_load_normal_par(&TC, queue_snd_id, time);
      98           0 :                     close_action(&TC, result, queue_snd_id);
      99           0 :                     break;
     100             :                 case TC_SUBTYPE_LOAD_BURST:
     101           0 :                     result = action_load_burst_par(&TC, queue_snd_id, time);
     102           0 :                     close_action(&TC, result, queue_snd_id);
     103           0 :                     break;
     104             :                 case TC_SUBTYPE_LOAD_SBM1:
     105           0 :                     result = action_load_sbm1_par(&TC, queue_snd_id, time);
     106           0 :                     close_action(&TC, result, queue_snd_id);
     107           0 :                     break;
     108             :                 case TC_SUBTYPE_LOAD_SBM2:
     109           0 :                     result = action_load_sbm2_par(&TC, queue_snd_id, time);
     110           0 :                     close_action(&TC, result, queue_snd_id);
     111           0 :                     break;
     112             :                 case TC_SUBTYPE_DUMP:
     113          11 :                     result = action_dump_par(&TC, queue_snd_id);
     114          11 :                     close_action(&TC, result, queue_snd_id);
     115          11 :                     break;
     116             :                 case TC_SUBTYPE_ENTER:
     117           6 :                     result = action_enter_mode(&TC, queue_snd_id);
     118           6 :                     close_action(&TC, result, queue_snd_id);
     119           6 :                     break;
     120             :                 case TC_SUBTYPE_UPDT_INFO:
     121           0 :                     result = action_update_info(&TC);
     122           0 :                     close_action(&TC, result, queue_snd_id);
     123           0 :                     break;
     124             :                 case TC_SUBTYPE_EN_CAL:
     125           0 :                     result = action_enable_calibration();
     126           0 :                     close_action(&TC, result, queue_snd_id);
     127           0 :                     break;
     128             :                 case TC_SUBTYPE_DIS_CAL:
     129           0 :                     result = action_disable_calibration();
     130           0 :                     close_action(&TC, result, queue_snd_id);
     131           0 :                     break;
     132             :                 case TC_SUBTYPE_LOAD_K:
     133           0 :                     result = action_load_kcoefficients(&TC, queue_snd_id, time);
     134           0 :                     close_action(&TC, result, queue_snd_id);
     135           0 :                     break;
     136             :                 case TC_SUBTYPE_DUMP_K:
     137           0 :                     result = action_dump_kcoefficients(&TC, queue_snd_id, time);
     138           0 :                     close_action(&TC, result, queue_snd_id);
     139           0 :                     break;
     140             :                 case TC_SUBTYPE_LOAD_FBINS:
     141          10 :                     result = action_load_fbins_mask(&TC, queue_snd_id, time);
     142          10 :                     close_action(&TC, result, queue_snd_id);
     143          10 :                     break;
     144             :                 case TC_SUBTYPE_LOAD_FILTER_PAR:
     145           0 :                     result = action_load_filter_par(&TC, queue_snd_id);
     146           0 :                     close_action(&TC, result, queue_snd_id);
     147           0 :                     break;
     148             :                 case TC_SUBTYPE_UPDT_TIME:
     149           0 :                     result = action_update_time(&TC);
     150           0 :                     close_action(&TC, result, queue_snd_id);
     151             :                     break;
     152             :                 default:
     153             :                     break;
     154             :             }
     155             :         }
     156             :     }
     157             : }
     158             : 
     159             : //***********
     160             : // TC ACTIONS
     161             : 
     162           1 : int action_reset()
     163             : {
     164             :     /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
     165             :      *
     166             :      * @param TC points to the TeleCommand packet that is being processed
     167             :      * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
     168             :      *
     169             :      */
     170             : 
     171             :     LFR_PRINTF("this is the end!!!\n");
     172             : #ifdef GCOV_ENABLED
     173             :     #ifndef GCOV_USE_EXIT
     174             :     extern void gcov_exit(void);
     175             :     gcov_exit();
     176             :     #endif
     177             : #endif
     178           1 :     exit(0);
     179             : 
     180             : #ifdef ENABLE_DEAD_CODE
     181             :     send_tm_lfr_tc_exe_not_implemented(TC, queue_id, time);
     182             : #endif
     183             : 
     184             :     return LFR_DEFAULT;
     185             : }
     186             : 
     187           6 : int action_enter_mode(const ccsdsTelecommandPacket_t* const TC, rtems_id queue_id)
     188             : {
     189             :     /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been
     190             :      * received.
     191             :      *
     192             :      * @param TC points to the TeleCommand packet that is being processed
     193             :      * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
     194             :      *
     195             :      */
     196             : 
     197             :     rtems_status_code status;
     198             :     unsigned char requestedMode;
     199             :     unsigned int transitionCoarseTime;
     200           6 :     const unsigned char* const bytePosPtr = (const unsigned char*)&TC->packetID;
     201           6 :     requestedMode = bytePosPtr[BYTE_POS_CP_MODE_LFR_SET];
     202           6 :     copyInt32ByChar(
     203             :         (unsigned char*)&transitionCoarseTime, &bytePosPtr[BYTE_POS_CP_LFR_ENTER_MODE_TIME]);
     204           6 :     transitionCoarseTime = transitionCoarseTime & COARSE_TIME_MASK;
     205          12 :     status = check_mode_value(requestedMode);
     206             :     DEBUG_CHECK_STATUS(status);
     207             : 
     208           6 :     if (status != LFR_SUCCESSFUL) // the mode value is inconsistent
     209             :     {
     210           0 :         DEBUG_CHECK_STATUS(send_tm_lfr_tc_exe_inconsistent(
     211             :                                TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode));
     212             :     }
     213             : 
     214             :     else // the mode value is valid, check the transition
     215             :     {
     216           6 :         status = check_mode_transition(requestedMode);
     217             :         DEBUG_CHECK_STATUS(status);
     218           6 :         if (status != LFR_SUCCESSFUL)
     219             :         {
     220             :             LFR_PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n");
     221           1 :             DEBUG_CHECK_STATUS(send_tm_lfr_tc_exe_not_executable(TC, queue_id));
     222             :         }
     223             :     }
     224             : 
     225           6 :     if (status == LFR_SUCCESSFUL) // the transition is valid, check the date
     226             :     {
     227           5 :         status = check_transition_date(transitionCoarseTime);
     228             :         DEBUG_CHECK_STATUS(status);
     229           5 :         if (status != LFR_SUCCESSFUL)
     230             :         {
     231             :             LFR_PRINTF("ERR *** in action_enter_mode *** check_transition_date\n");
     232           0 :             DEBUG_CHECK_STATUS(send_tm_lfr_tc_exe_not_executable(TC, queue_id));
     233             :         }
     234             :     }
     235             : 
     236           6 :     if (status == LFR_SUCCESSFUL) // the date is valid, enter the mode
     237             :     {
     238             :         LFR_PRINTF("OK  *** in action_enter_mode *** enter mode %d\n", requestedMode);
     239             : 
     240           5 :         switch (requestedMode)
     241             :         {
     242             :             case LFR_MODE_STANDBY:
     243           1 :                 status = enter_mode_standby();
     244           1 :                 break;
     245             :             case LFR_MODE_NORMAL:
     246           1 :                 status = enter_mode_normal(transitionCoarseTime);
     247           1 :                 break;
     248             :             case LFR_MODE_BURST:
     249           1 :                 status = enter_mode_burst(transitionCoarseTime);
     250           1 :                 break;
     251             :             case LFR_MODE_SBM1:
     252           1 :                 status = enter_mode_sbm1(transitionCoarseTime);
     253           1 :                 break;
     254             :             case LFR_MODE_SBM2:
     255           1 :                 status = enter_mode_sbm2(transitionCoarseTime);
     256             :                 break;
     257             :             default:
     258             :                 break;
     259             :         }
     260             :         DEBUG_CHECK_STATUS(status);
     261           5 :         if (status != RTEMS_SUCCESSFUL)
     262             :         {
     263           0 :             status = LFR_EXE_ERROR;
     264             :         }
     265             :     }
     266             : 
     267           6 :     return status;
     268             : }
     269             : 
     270           0 : int action_update_info(const ccsdsTelecommandPacket_t* const TC)
     271             : {
     272             :     /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been
     273             :      * received.
     274             :      *
     275             :      * @param TC points to the TeleCommand packet that is being processed
     276             :      * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
     277             :      *
     278             :      * @return LFR directive status code:
     279             :      * - LFR_DEFAULT
     280             :      * - LFR_SUCCESSFUL
     281             :      *
     282             :      */
     283             : 
     284             :     unsigned int val;
     285           0 :     unsigned int status = LFR_DEFAULT;
     286             :     unsigned char mode;
     287           0 :     const unsigned char* const bytePosPtr = (const unsigned char*)&TC->packetID;
     288           0 :     int pos = 0;
     289           0 :     float value = 0.;
     290             : 
     291             :     // check LFR mode
     292           0 :     mode = (bytePosPtr[BYTE_POS_UPDATE_INFO_PARAMETERS_SET5] & BITS_LFR_MODE) >> SHIFT_LFR_MODE;
     293           0 :     status = check_update_info_hk_lfr_mode(mode);
     294             :     DEBUG_CHECK_STATUS(status);
     295           0 :     if (status == LFR_SUCCESSFUL) // check TDS mode
     296             :     {
     297           0 :         mode = (bytePosPtr[BYTE_POS_UPDATE_INFO_PARAMETERS_SET6] & BITS_TDS_MODE) >> SHIFT_TDS_MODE;
     298           0 :         status = check_update_info_hk_tds_mode(mode);
     299             :         DEBUG_CHECK_STATUS(status);
     300             :     }
     301           0 :     if (status == LFR_SUCCESSFUL) // check THR mode
     302             :     {
     303           0 :         mode = (bytePosPtr[BYTE_POS_UPDATE_INFO_PARAMETERS_SET6] & BITS_THR_MODE);
     304           0 :         status = check_update_info_hk_thr_mode(mode);
     305             :         DEBUG_CHECK_STATUS(status);
     306             :     }
     307           0 :     if (status == LFR_SUCCESSFUL) // check reaction wheels frequencies
     308             :     {
     309           0 :         status = check_all_sy_lfr_rw_f(TC, &pos, &value);
     310             :         DEBUG_CHECK_STATUS(status);
     311             :     }
     312             : 
     313             :     // if the parameters checking succeeds, udpate all parameters
     314           0 :     if (status == LFR_SUCCESSFUL)
     315             :     {
     316             :         // pa_bia_status_info
     317             :         // => pa_bia_mode_mux_set       3 bits
     318             :         // => pa_bia_mode_hv_enabled    1 bit
     319             :         // => pa_bia_mode_bias1_enabled 1 bit
     320             :         // => pa_bia_mode_bias2_enabled 1 bit
     321             :         // => pa_bia_mode_bias3_enabled 1 bit
     322             :         // => pa_bia_on_off (cp_dpu_bias_on_off)
     323           0 :         pa_bia_status_info
     324           0 :             = bytePosPtr[BYTE_POS_UPDATE_INFO_PARAMETERS_SET2] & BITS_BIA; // [1111 1110]
     325           0 :         pa_bia_status_info
     326           0 :             = pa_bia_status_info | (bytePosPtr[BYTE_POS_UPDATE_INFO_PARAMETERS_SET1] & 1);
     327             : 
     328             :         // REACTION_WHEELS_FREQUENCY, copy the incoming parameters in the local variable (to be
     329             :         // copied in HK packets)
     330           0 :         getReactionWheelsFrequencies(TC);
     331           0 :         set_hk_lfr_sc_rw_f_flags();
     332           0 :         build_sy_lfr_rw_masks();
     333             : 
     334             :         // once the masks are built, they have to be merged with the fbins_mask
     335           0 :         merge_fbins_masks();
     336             : 
     337             :         // increase the TC_LFR_UPDATE_INFO counter
     338           0 :         if (status == LFR_SUCCESSFUL) // if the parameter check is successful
     339             :         {
     340           0 :             val = (housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * CONST_256)
     341           0 :                 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
     342           0 :             val++;
     343           0 :             housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char)(val >> SHIFT_1_BYTE);
     344           0 :             housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char)(val);
     345             :         }
     346             :     }
     347             : 
     348           0 :     return status;
     349             : }
     350             : 
     351           0 : int action_enable_calibration()
     352             : {
     353             :     /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has
     354             :      * been received.
     355             :      *
     356             :      * @param TC points to the TeleCommand packet that is being processed
     357             :      * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
     358             :      *
     359             :      */
     360           0 :     setCalibration(true);
     361           0 :     return LFR_SUCCESSFUL;
     362             : }
     363             : 
     364           0 : int action_disable_calibration()
     365             : {
     366             :     /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has
     367             :      * been received.
     368             :      *
     369             :      * @param TC points to the TeleCommand packet that is being processed
     370             :      * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
     371             :      *
     372             :      */
     373             : 
     374           0 :     setCalibration(false);
     375           0 :     return LFR_SUCCESSFUL;
     376             : }
     377             : 
     378           0 : int action_update_time(const ccsdsTelecommandPacket_t* const TC)
     379             : {
     380             :     /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been
     381             :      * received.
     382             :      *
     383             :      * @param TC points to the TeleCommand packet that is being processed
     384             :      * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
     385             :      *
     386             :      * @return LFR_SUCCESSFUL
     387             :      *
     388             :      */
     389             : 
     390             :     unsigned int val;
     391             : 
     392           0 :     time_management_regs->coarse_time_load = (TC->dataAndCRC[BYTE_0] << SHIFT_3_BYTES)
     393           0 :         + (TC->dataAndCRC[BYTE_1] << SHIFT_2_BYTES) + (TC->dataAndCRC[BYTE_2] << SHIFT_1_BYTE)
     394           0 :         + TC->dataAndCRC[BYTE_3];
     395             : 
     396           0 :     val = (housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * CONST_256)
     397           0 :         + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
     398           0 :     val++;
     399           0 :     housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char)(val >> SHIFT_1_BYTE);
     400           0 :     housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char)(val);
     401             : 
     402           0 :     oneTcLfrUpdateTimeReceived = 1;
     403             : 
     404           0 :     return LFR_SUCCESSFUL;
     405             : }
     406             : 
     407             : //*******************
     408             : // ENTERING THE MODES
     409           0 : int check_mode_value(unsigned char requestedMode)
     410             : {
     411           6 :     int status = LFR_DEFAULT;
     412             : 
     413           6 :     if ((requestedMode != LFR_MODE_STANDBY) && (requestedMode != LFR_MODE_NORMAL)
     414             :         && (requestedMode != LFR_MODE_BURST) && (requestedMode != LFR_MODE_SBM1)
     415             :         && (requestedMode != LFR_MODE_SBM2))
     416             :     {
     417           0 :         status = LFR_DEFAULT;
     418             :     }
     419             :     else
     420             :     {
     421           6 :         status = LFR_SUCCESSFUL;
     422             :     }
     423             : 
     424           6 :     return status;
     425             : }
     426             : 
     427           6 : int check_mode_transition(unsigned char requestedMode)
     428             : {
     429             :     /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
     430             :      *
     431             :      * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
     432             :      *
     433             :      * @return LFR directive status codes:
     434             :      * - LFR_SUCCESSFUL - the transition is authorized
     435             :      * - LFR_DEFAULT - the transition is not authorized
     436             :      *
     437             :      */
     438             : 
     439             :     int status;
     440             : 
     441           6 :     switch (requestedMode)
     442             :     {
     443             :         case LFR_MODE_STANDBY:
     444           2 :             if (lfrCurrentMode == LFR_MODE_STANDBY)
     445             :             {
     446           1 :                 status = LFR_DEFAULT;
     447             :             }
     448             :             else
     449             :             {
     450           1 :                 status = LFR_SUCCESSFUL;
     451             :             }
     452             :             break;
     453             :         case LFR_MODE_NORMAL:
     454           1 :             if (lfrCurrentMode == LFR_MODE_NORMAL)
     455             :             {
     456           0 :                 status = LFR_DEFAULT;
     457             :             }
     458             :             else
     459             :             {
     460           1 :                 status = LFR_SUCCESSFUL;
     461             :             }
     462             :             break;
     463             :         case LFR_MODE_BURST:
     464           1 :             if (lfrCurrentMode == LFR_MODE_BURST)
     465             :             {
     466           0 :                 status = LFR_DEFAULT;
     467             :             }
     468             :             else
     469             :             {
     470           1 :                 status = LFR_SUCCESSFUL;
     471             :             }
     472             :             break;
     473             :         case LFR_MODE_SBM1:
     474           1 :             if (lfrCurrentMode == LFR_MODE_SBM1)
     475             :             {
     476           0 :                 status = LFR_DEFAULT;
     477             :             }
     478             :             else
     479             :             {
     480           1 :                 status = LFR_SUCCESSFUL;
     481             :             }
     482             :             break;
     483             :         case LFR_MODE_SBM2:
     484           1 :             if (lfrCurrentMode == LFR_MODE_SBM2)
     485             :             {
     486           0 :                 status = LFR_DEFAULT;
     487             :             }
     488             :             else
     489             :             {
     490           1 :                 status = LFR_SUCCESSFUL;
     491             :             }
     492             :             break;
     493             :         default:
     494           0 :             status = LFR_DEFAULT;
     495             :             break;
     496             :     }
     497             : 
     498           6 :     return status;
     499             : }
     500             : 
     501           5 : void update_last_valid_transition_date(unsigned int transitionCoarseTime)
     502             : {
     503           5 :     if (transitionCoarseTime == 0)
     504             :     {
     505           1 :         lastValidEnterModeTime = time_management_regs->coarse_time + 1;
     506             :         LFR_PRINTF("lastValidEnterModeTime = 0x%x (transitionCoarseTime = 0 => coarse_time+1)\n",
     507             :             lastValidEnterModeTime);
     508             :     }
     509             :     else
     510             :     {
     511           4 :         lastValidEnterModeTime = transitionCoarseTime;
     512             :         LFR_PRINTF("lastValidEnterModeTime = 0x%x\n", transitionCoarseTime);
     513             :     }
     514           5 : }
     515             : 
     516           5 : int check_transition_date(unsigned int transitionCoarseTime)
     517             : {
     518             :     int status;
     519             :     unsigned int localCoarseTime;
     520             :     unsigned int deltaCoarseTime;
     521             : 
     522           5 :     status = LFR_SUCCESSFUL;
     523             : 
     524           5 :     if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
     525             :     {
     526           5 :         status = LFR_SUCCESSFUL;
     527             :     }
     528             :     else
     529             :     {
     530           0 :         localCoarseTime = time_management_regs->coarse_time & COARSE_TIME_MASK;
     531             : 
     532             :         LFR_PRINTF("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime);
     533             : 
     534           0 :         if (transitionCoarseTime <= localCoarseTime) // SSS-CP-EQS-322
     535             :         {
     536           0 :             status = LFR_DEFAULT;
     537             :             LFR_PRINTF(
     538             :                 "ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n");
     539             :         }
     540             : 
     541           0 :         if (status == LFR_SUCCESSFUL)
     542             :         {
     543           0 :             deltaCoarseTime = transitionCoarseTime - localCoarseTime;
     544           0 :             if (deltaCoarseTime > MAX_DELTA_COARSE_TIME) // SSS-CP-EQS-323
     545             :             {
     546           0 :                 status = LFR_DEFAULT;
     547             :                 LFR_PRINTF(
     548             :                     "ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime);
     549             :             }
     550             :         }
     551             :     }
     552             : 
     553           5 :     return status;
     554             : }
     555             : 
     556           1 : int restart_asm_activities(unsigned char lfrRequestedMode)
     557             : {
     558             :     rtems_status_code status;
     559             : 
     560           1 :     status = stop_spectral_matrices();
     561             :     DEBUG_CHECK_STATUS(status);
     562             : 
     563           1 :     thisIsAnASMRestart = 1;
     564             : 
     565           1 :     status = restart_asm_tasks(lfrRequestedMode);
     566             :     DEBUG_CHECK_STATUS(status);
     567             : 
     568           1 :     launch_spectral_matrix();
     569             : 
     570           1 :     return status;
     571             : }
     572             : 
     573           1 : int stop_spectral_matrices(void)
     574             : {
     575             :     /** This function stops and restarts the current mode average spectral matrices activities.
     576             :      *
     577             :      * @return RTEMS directive status codes:
     578             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     579             :      * - RTEMS_INVALID_ID - task id invalid
     580             :      * - RTEMS_ALREADY_SUSPENDED - task already suspended
     581             :      *
     582             :      */
     583             : 
     584             :     rtems_status_code status;
     585             : 
     586           1 :     status = RTEMS_SUCCESSFUL;
     587             : 
     588             :     // (1) mask interruptions
     589           1 :     LEON_Mask_interrupt(IRQ_SPECTRAL_MATRIX); // mask spectral matrix interrupt
     590             : 
     591             :     // (2) reset spectral matrices registers
     592             :     set_sm_irq_onNewMatrix(0); // stop the spectral matrices
     593           1 :     reset_sm_status();
     594             : 
     595             :     // (3) clear interruptions
     596           1 :     LEON_Clear_interrupt(IRQ_SPECTRAL_MATRIX); // clear spectral matrix interrupt
     597             : 
     598             :     // suspend several tasks
     599           1 :     if (lfrCurrentMode != LFR_MODE_STANDBY)
     600             :     {
     601           1 :         status = suspend_asm_tasks();
     602             :         DEBUG_CHECK_STATUS(status);
     603             :     }
     604             : 
     605           1 :     if (status != RTEMS_SUCCESSFUL)
     606             :     {
     607             :         LFR_PRINTF("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status);
     608             :     }
     609             : 
     610           1 :     return status;
     611             : }
     612             : 
     613           3 : int stop_current_mode(void)
     614             : {
     615             :     /** This function stops the current mode by masking interrupt lines and suspending science
     616             :      * tasks.
     617             :      *
     618             :      * @return RTEMS directive status codes:
     619             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     620             :      * - RTEMS_INVALID_ID - task id invalid
     621             :      * - RTEMS_ALREADY_SUSPENDED - task already suspended
     622             :      *
     623             :      */
     624             : 
     625             :     rtems_status_code status;
     626             : 
     627           3 :     status = RTEMS_SUCCESSFUL;
     628             : 
     629             :     // (1) mask interruptions
     630           3 :     LEON_Mask_interrupt(IRQ_WAVEFORM_PICKER); // mask waveform picker interrupt
     631           3 :     LEON_Mask_interrupt(IRQ_SPECTRAL_MATRIX); // clear spectral matrix interrupt
     632             : 
     633             :     // (2) reset waveform picker registers
     634           3 :     reset_wfp_burst_enable(); // reset burst and enable bits
     635           3 :     reset_wfp_status(); // reset all the status bits
     636             : 
     637             :     // (3) reset spectral matrices registers
     638             :     set_sm_irq_onNewMatrix(0); // stop the spectral matrices
     639           3 :     reset_sm_status();
     640             : 
     641             :     // reset lfr VHDL module
     642           3 :     reset_lfr();
     643             : 
     644           3 :     reset_extractSWF(); // reset the extractSWF flag to false
     645             : 
     646             :     // (4) clear interruptions
     647           3 :     LEON_Clear_interrupt(IRQ_WAVEFORM_PICKER); // clear waveform picker interrupt
     648           3 :     LEON_Clear_interrupt(IRQ_SPECTRAL_MATRIX); // clear spectral matrix interrupt
     649             : 
     650             :     // suspend several tasks
     651           3 :     if (lfrCurrentMode != LFR_MODE_STANDBY)
     652             :     {
     653           3 :         status = suspend_science_tasks();
     654             :         DEBUG_CHECK_STATUS(status);
     655             :     }
     656             : 
     657           3 :     if (status != RTEMS_SUCCESSFUL)
     658             :     {
     659             :         LFR_PRINTF("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status);
     660             :     }
     661             : 
     662           3 :     return status;
     663             : }
     664             : 
     665           0 : int enter_mode_standby(void)
     666             : {
     667             :     /** This function is used to put LFR in the STANDBY mode.
     668             :      *
     669             :      * @param transitionCoarseTime is the requested transition time contained in the
     670             :      * TC_LFR_ENTER_MODE
     671             :      *
     672             :      * @return RTEMS directive status codes:
     673             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     674             :      * - RTEMS_INVALID_ID - task id invalid
     675             :      * - RTEMS_INCORRECT_STATE - task never started
     676             :      * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
     677             :      *
     678             :      * The STANDBY mode does not depends on a specific transition date, the effect of the
     679             :      * TC_LFR_ENTER_MODE is immediate.
     680             :      *
     681             :      */
     682             : 
     683             :     int status;
     684             : 
     685           1 :     status = stop_current_mode(); // STOP THE CURRENT MODE
     686             :     DEBUG_CHECK_STATUS(status);
     687             : 
     688             : #ifdef PRINT_TASK_STATISTICS
     689             :     rtems_cpu_usage_report();
     690             : #endif
     691             : 
     692             : #ifdef PRINT_STACK_REPORT
     693             :     LFR_PRINTF("stack report selected\n");
     694             :     rtems_stack_checker_report_usage();
     695             : #endif
     696             : 
     697           1 :     return status;
     698             : }
     699             : 
     700           1 : int enter_mode_normal(unsigned int transitionCoarseTime)
     701             : {
     702             :     /** This function is used to start the NORMAL mode.
     703             :      *
     704             :      * @param transitionCoarseTime is the requested transition time contained in the
     705             :      * TC_LFR_ENTER_MODE
     706             :      *
     707             :      * @return RTEMS directive status codes:
     708             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     709             :      * - RTEMS_INVALID_ID - task id invalid
     710             :      * - RTEMS_INCORRECT_STATE - task never started
     711             :      * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
     712             :      *
     713             :      * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or
     714             :      * SBM2, the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
     715             :      *
     716             :      */
     717             : 
     718             :     int status;
     719             : 
     720             : #ifdef PRINT_TASK_STATISTICS
     721             :     rtems_cpu_usage_reset();
     722             : #endif
     723             : 
     724           1 :     status = RTEMS_UNSATISFIED;
     725             : 
     726           1 :     switch (lfrCurrentMode)
     727             :     {
     728             :         case LFR_MODE_STANDBY:
     729           1 :             status = restart_science_tasks(LFR_MODE_NORMAL); // restart science tasks
     730             :             DEBUG_CHECK_STATUS(status);
     731           1 :             if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
     732             :             {
     733           1 :                 launch_spectral_matrix();
     734           1 :                 launch_waveform_picker(LFR_MODE_NORMAL, transitionCoarseTime);
     735             :             }
     736             :             break;
     737             :         case LFR_MODE_BURST:
     738           0 :             status = stop_current_mode(); // stop the current mode
     739             :             DEBUG_CHECK_STATUS(status);
     740           0 :             status = restart_science_tasks(LFR_MODE_NORMAL); // restart the science tasks
     741             :             DEBUG_CHECK_STATUS(status);
     742           0 :             if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
     743             :             {
     744           0 :                 launch_spectral_matrix();
     745           0 :                 launch_waveform_picker(LFR_MODE_NORMAL, transitionCoarseTime);
     746             :             }
     747             :             break;
     748             :         case LFR_MODE_SBM1:
     749             :         case LFR_MODE_SBM2:
     750           0 :             status = restart_asm_activities(
     751             :                 LFR_MODE_NORMAL); // this is necessary to restart ASM tasks to update the parameters
     752             :             DEBUG_CHECK_STATUS(status);
     753           0 :             status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of
     754             :                                      // close_action
     755           0 :             update_last_valid_transition_date(transitionCoarseTime);
     756             :             break;
     757             :         default:
     758             :             break;
     759             :     }
     760             : 
     761           1 :     if (status != RTEMS_SUCCESSFUL)
     762             :     {
     763             :         LFR_PRINTF("ERR *** in enter_mode_normal *** status = %d\n", status);
     764           0 :         status = RTEMS_UNSATISFIED;
     765             :     }
     766             : 
     767           1 :     return status;
     768             : }
     769             : 
     770           1 : int enter_mode_burst(unsigned int transitionCoarseTime)
     771             : {
     772             :     /** This function is used to start the BURST mode.
     773             :      *
     774             :      * @param transitionCoarseTime is the requested transition time contained in the
     775             :      * TC_LFR_ENTER_MODE
     776             :      *
     777             :      * @return RTEMS directive status codes:
     778             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     779             :      * - RTEMS_INVALID_ID - task id invalid
     780             :      * - RTEMS_INCORRECT_STATE - task never started
     781             :      * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
     782             :      *
     783             :      * The way the BURST mode is started does not depend on the LFR current mode.
     784             :      *
     785             :      */
     786             : 
     787             : 
     788             :     int status;
     789             : 
     790             : #ifdef PRINT_TASK_STATISTICS
     791             :     rtems_cpu_usage_reset();
     792             : #endif
     793             : 
     794           1 :     status = stop_current_mode(); // stop the current mode
     795             :     DEBUG_CHECK_STATUS(status);
     796           1 :     status = restart_science_tasks(LFR_MODE_BURST); // restart the science tasks
     797             :     DEBUG_CHECK_STATUS(status);
     798           1 :     if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
     799             :     {
     800           1 :         launch_spectral_matrix();
     801           1 :         launch_waveform_picker(LFR_MODE_BURST, transitionCoarseTime);
     802             :     }
     803             : 
     804           1 :     if (status != RTEMS_SUCCESSFUL)
     805             :     {
     806             :         LFR_PRINTF("ERR *** in enter_mode_burst *** status = %d\n", status);
     807           0 :         status = RTEMS_UNSATISFIED;
     808             :     }
     809             : 
     810           1 :     return status;
     811             : }
     812             : 
     813           1 : int enter_mode_sbm1(unsigned int transitionCoarseTime)
     814             : {
     815             :     /** This function is used to start the SBM1 mode.
     816             :      *
     817             :      * @param transitionCoarseTime is the requested transition time contained in the
     818             :      * TC_LFR_ENTER_MODE
     819             :      *
     820             :      * @return RTEMS directive status codes:
     821             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     822             :      * - RTEMS_INVALID_ID - task id invalid
     823             :      * - RTEMS_INCORRECT_STATE - task never started
     824             :      * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
     825             :      *
     826             :      * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or
     827             :      * SBM2, the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In
     828             :      * other cases, the acquisition is completely restarted.
     829             :      *
     830             :      */
     831             : 
     832             :     int status;
     833             : 
     834             : #ifdef PRINT_TASK_STATISTICS
     835             :     rtems_cpu_usage_reset();
     836             : #endif
     837             : 
     838           1 :     status = RTEMS_UNSATISFIED;
     839             : 
     840           1 :     switch (lfrCurrentMode)
     841             :     {
     842             :         case LFR_MODE_STANDBY:
     843           0 :             status = restart_science_tasks(LFR_MODE_SBM1); // restart science tasks
     844             :             DEBUG_CHECK_STATUS(status);
     845           0 :             if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
     846             :             {
     847           0 :                 launch_spectral_matrix();
     848           0 :                 launch_waveform_picker(LFR_MODE_SBM1, transitionCoarseTime);
     849             :             }
     850             :             break;
     851             :         case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
     852             :         case LFR_MODE_SBM2:
     853           0 :             status = restart_asm_activities(LFR_MODE_SBM1);
     854             :             DEBUG_CHECK_STATUS(status);
     855           0 :             status = LFR_SUCCESSFUL;
     856           0 :             update_last_valid_transition_date(transitionCoarseTime);
     857           0 :             break;
     858             :         case LFR_MODE_BURST:
     859           1 :             status = stop_current_mode(); // stop the current mode
     860             :             DEBUG_CHECK_STATUS(status);
     861           1 :             status = restart_science_tasks(LFR_MODE_SBM1); // restart the science tasks
     862             :             DEBUG_CHECK_STATUS(status);
     863           1 :             if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
     864             :             {
     865           1 :                 launch_spectral_matrix();
     866           1 :                 launch_waveform_picker(LFR_MODE_SBM1, transitionCoarseTime);
     867             :             }
     868             :             break;
     869             :         default:
     870             :             break;
     871             :     }
     872             : 
     873           1 :     if (status != RTEMS_SUCCESSFUL)
     874             :     {
     875             :         LFR_PRINTF("ERR *** in enter_mode_sbm1 *** status = %d\n", status);
     876           0 :         status = RTEMS_UNSATISFIED;
     877             :     }
     878             : 
     879           1 :     return status;
     880             : }
     881             : 
     882           1 : int enter_mode_sbm2(unsigned int transitionCoarseTime)
     883             : {
     884             :     /** This function is used to start the SBM2 mode.
     885             :      *
     886             :      * @param transitionCoarseTime is the requested transition time contained in the
     887             :      * TC_LFR_ENTER_MODE
     888             :      *
     889             :      * @return RTEMS directive status codes:
     890             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     891             :      * - RTEMS_INVALID_ID - task id invalid
     892             :      * - RTEMS_INCORRECT_STATE - task never started
     893             :      * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
     894             :      *
     895             :      * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or
     896             :      * SBM1, the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In
     897             :      * other cases, the acquisition is completely restarted.
     898             :      *
     899             :      */
     900             : 
     901             :     int status;
     902             : 
     903             : #ifdef PRINT_TASK_STATISTICS
     904             :     rtems_cpu_usage_reset();
     905             : #endif
     906             : 
     907           1 :     status = RTEMS_UNSATISFIED;
     908             : 
     909           1 :     switch (lfrCurrentMode)
     910             :     {
     911             :         case LFR_MODE_STANDBY:
     912           0 :             status = restart_science_tasks(LFR_MODE_SBM2); // restart science tasks
     913             :             DEBUG_CHECK_STATUS(status);
     914           0 :             if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
     915             :             {
     916           0 :                 launch_spectral_matrix();
     917           0 :                 launch_waveform_picker(LFR_MODE_SBM2, transitionCoarseTime);
     918             :             }
     919             :             break;
     920             :         case LFR_MODE_NORMAL:
     921             :         case LFR_MODE_SBM1:
     922           1 :             status = restart_asm_activities(LFR_MODE_SBM2);
     923             :             DEBUG_CHECK_STATUS(status);
     924           1 :             status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of
     925             :                                      // close_action
     926           1 :             update_last_valid_transition_date(transitionCoarseTime);
     927           1 :             break;
     928             :         case LFR_MODE_BURST:
     929           0 :             status = stop_current_mode(); // stop the current mode
     930             :             DEBUG_CHECK_STATUS(status);
     931           0 :             status = restart_science_tasks(LFR_MODE_SBM2); // restart the science tasks
     932             :             DEBUG_CHECK_STATUS(status);
     933           0 :             if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
     934             :             {
     935           0 :                 launch_spectral_matrix();
     936           0 :                 launch_waveform_picker(LFR_MODE_SBM2, transitionCoarseTime);
     937             :             }
     938             :             break;
     939             :         default:
     940             :             break;
     941             :     }
     942             : 
     943           1 :     if (status != RTEMS_SUCCESSFUL)
     944             :     {
     945             :         LFR_PRINTF("ERR *** in enter_mode_sbm2 *** status = %d\n", status);
     946           0 :         status = RTEMS_UNSATISFIED;
     947             :     }
     948             : 
     949           1 :     return status;
     950             : }
     951             : 
     952           3 : int restart_science_tasks(unsigned char lfrRequestedMode)
     953             : {
     954             :     /** This function is used to restart all science tasks.
     955             :      *
     956             :      * @return RTEMS directive status codes:
     957             :      * - RTEMS_SUCCESSFUL - task restarted successfully
     958             :      * - RTEMS_INVALID_ID - task id invalid
     959             :      * - RTEMS_INCORRECT_STATE - task never started
     960             :      * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
     961             :      *
     962             :      * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
     963             :      *
     964             :      */
     965             : 
     966           3 :     rtems_status_code status = RTEMS_SUCCESSFUL;
     967             :     rtems_status_code ret;
     968             : 
     969           3 :     ret = RTEMS_SUCCESSFUL;
     970             : 
     971           3 :     status |= rtems_task_restart(Task_id[TASKID_AVF0], lfrRequestedMode);
     972             :     DEBUG_CHECK_STATUS(status);
     973             : 
     974           3 :     status |= rtems_task_restart(Task_id[TASKID_PRC0], lfrRequestedMode);
     975             :     DEBUG_CHECK_STATUS(status);
     976             : 
     977           3 :     status |= rtems_task_restart(Task_id[TASKID_WFRM], 1);
     978             :     DEBUG_CHECK_STATUS(status);
     979             : 
     980           3 :     status |= rtems_task_restart(Task_id[TASKID_CWF3], 1);
     981             :     DEBUG_CHECK_STATUS(status);
     982             : 
     983           3 :     status |= rtems_task_restart(Task_id[TASKID_CWF2], 1);
     984             :     DEBUG_CHECK_STATUS(status);
     985             : 
     986           3 :     status |= rtems_task_restart(Task_id[TASKID_CWF1], 1);
     987             :     DEBUG_CHECK_STATUS(status);
     988             : 
     989           3 :     status |= rtems_task_restart(Task_id[TASKID_AVF1], lfrRequestedMode);
     990             :     DEBUG_CHECK_STATUS(status);
     991             : 
     992           3 :     status |= rtems_task_restart(Task_id[TASKID_PRC1], lfrRequestedMode);
     993             :     DEBUG_CHECK_STATUS(status);
     994             : 
     995           3 :     status |= rtems_task_restart(Task_id[TASKID_AVF2], 1);
     996             :     DEBUG_CHECK_STATUS(status);
     997             : 
     998           3 :     status |= rtems_task_restart(Task_id[TASKID_PRC2], 1);
     999             :     DEBUG_CHECK_STATUS(status);
    1000             : 
    1001           3 :     if (status != RTEMS_SUCCESSFUL)
    1002             :     {
    1003           0 :         ret = RTEMS_UNSATISFIED;
    1004             :     }
    1005             : 
    1006           3 :     return ret;
    1007             : }
    1008             : 
    1009           1 : int restart_asm_tasks(unsigned char lfrRequestedMode)
    1010             : {
    1011             :     /** This function is used to restart average spectral matrices tasks.
    1012             :      *
    1013             :      * @return RTEMS directive status codes:
    1014             :      * - RTEMS_SUCCESSFUL - task restarted successfully
    1015             :      * - RTEMS_INVALID_ID - task id invalid
    1016             :      * - RTEMS_INCORRECT_STATE - task never started
    1017             :      * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
    1018             :      *
    1019             :      * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
    1020             :      *
    1021             :      */
    1022             : 
    1023           1 :     rtems_status_code status= RTEMS_SUCCESSFUL;
    1024             : 
    1025           1 :     status |= rtems_task_restart(Task_id[TASKID_AVF0], lfrRequestedMode);
    1026             :     DEBUG_CHECK_STATUS(status);
    1027             : 
    1028           1 :     status |= rtems_task_restart(Task_id[TASKID_PRC0], lfrRequestedMode);
    1029             :     DEBUG_CHECK_STATUS(status);
    1030             : 
    1031           1 :     status |= rtems_task_restart(Task_id[TASKID_AVF1], lfrRequestedMode);
    1032             :     DEBUG_CHECK_STATUS(status);
    1033             : 
    1034           1 :     status |= rtems_task_restart(Task_id[TASKID_PRC1], lfrRequestedMode);
    1035             :     DEBUG_CHECK_STATUS(status);
    1036             : 
    1037           1 :     status |= rtems_task_restart(Task_id[TASKID_AVF2], 1);
    1038             :     DEBUG_CHECK_STATUS(status);
    1039             : 
    1040           1 :     status |= rtems_task_restart(Task_id[TASKID_PRC2], 1);
    1041             :     DEBUG_CHECK_STATUS(status);
    1042             : 
    1043           1 :     if (status != RTEMS_SUCCESSFUL)
    1044             :     {
    1045           0 :         status = RTEMS_UNSATISFIED;
    1046             :     }
    1047             : 
    1048           1 :     return status;
    1049             : }
    1050             : 
    1051           4 : int suspend_science_tasks(void)
    1052             : {
    1053             :     /** This function suspends the science tasks.
    1054             :      *
    1055             :      * @return RTEMS directive status codes:
    1056             :      * - RTEMS_SUCCESSFUL - task restarted successfully
    1057             :      * - RTEMS_INVALID_ID - task id invalid
    1058             :      * - RTEMS_ALREADY_SUSPENDED - task already suspended
    1059             :      *
    1060             :      */
    1061             : 
    1062             :     rtems_status_code status;
    1063             : 
    1064             :     LFR_PRINTF("in suspend_science_tasks\n");
    1065             : 
    1066           4 :     status = rtems_task_suspend(Task_id[TASKID_AVF0]); // suspend AVF0
    1067           4 :     if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1068             :     {
    1069             :         LFR_PRINTF("in suspend_science_task *** AVF0 ERR %d\n", status);
    1070             :     }
    1071             :     else
    1072             :     {
    1073           4 :         status = RTEMS_SUCCESSFUL;
    1074             :     }
    1075           4 :     if (status == RTEMS_SUCCESSFUL) // suspend PRC0
    1076             :     {
    1077           4 :         status = rtems_task_suspend(Task_id[TASKID_PRC0]);
    1078           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1079             :         {
    1080             :             LFR_PRINTF("in suspend_science_task *** PRC0 ERR %d\n", status);
    1081             :         }
    1082             :         else
    1083             :         {
    1084           4 :             status = RTEMS_SUCCESSFUL;
    1085             :         }
    1086             :     }
    1087           4 :     if (status == RTEMS_SUCCESSFUL) // suspend AVF1
    1088             :     {
    1089           4 :         status = rtems_task_suspend(Task_id[TASKID_AVF1]);
    1090           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1091             :         {
    1092             :             LFR_PRINTF("in suspend_science_task *** AVF1 ERR %d\n", status);
    1093             :         }
    1094             :         else
    1095             :         {
    1096           4 :             status = RTEMS_SUCCESSFUL;
    1097             :         }
    1098             :     }
    1099           4 :     if (status == RTEMS_SUCCESSFUL) // suspend PRC1
    1100             :     {
    1101           4 :         status = rtems_task_suspend(Task_id[TASKID_PRC1]);
    1102           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1103             :         {
    1104             :             LFR_PRINTF("in suspend_science_task *** PRC1 ERR %d\n", status);
    1105             :         }
    1106             :         else
    1107             :         {
    1108           4 :             status = RTEMS_SUCCESSFUL;
    1109             :         }
    1110             :     }
    1111           4 :     if (status == RTEMS_SUCCESSFUL) // suspend AVF2
    1112             :     {
    1113           4 :         status = rtems_task_suspend(Task_id[TASKID_AVF2]);
    1114           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1115             :         {
    1116             :             LFR_PRINTF("in suspend_science_task *** AVF2 ERR %d\n", status);
    1117             :         }
    1118             :         else
    1119             :         {
    1120           4 :             status = RTEMS_SUCCESSFUL;
    1121             :         }
    1122             :     }
    1123           4 :     if (status == RTEMS_SUCCESSFUL) // suspend PRC2
    1124             :     {
    1125           4 :         status = rtems_task_suspend(Task_id[TASKID_PRC2]);
    1126           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1127             :         {
    1128             :             LFR_PRINTF("in suspend_science_task *** PRC2 ERR %d\n", status);
    1129             :         }
    1130             :         else
    1131             :         {
    1132           4 :             status = RTEMS_SUCCESSFUL;
    1133             :         }
    1134             :     }
    1135           4 :     if (status == RTEMS_SUCCESSFUL) // suspend WFRM
    1136             :     {
    1137           4 :         status = rtems_task_suspend(Task_id[TASKID_WFRM]);
    1138           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1139             :         {
    1140             :             LFR_PRINTF("in suspend_science_task *** WFRM ERR %d\n", status);
    1141             :         }
    1142             :         else
    1143             :         {
    1144           4 :             status = RTEMS_SUCCESSFUL;
    1145             :         }
    1146             :     }
    1147           4 :     if (status == RTEMS_SUCCESSFUL) // suspend CWF3
    1148             :     {
    1149           4 :         status = rtems_task_suspend(Task_id[TASKID_CWF3]);
    1150           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1151             :         {
    1152             :             LFR_PRINTF("in suspend_science_task *** CWF3 ERR %d\n", status);
    1153             :         }
    1154             :         else
    1155             :         {
    1156           4 :             status = RTEMS_SUCCESSFUL;
    1157             :         }
    1158             :     }
    1159           4 :     if (status == RTEMS_SUCCESSFUL) // suspend CWF2
    1160             :     {
    1161           4 :         status = rtems_task_suspend(Task_id[TASKID_CWF2]);
    1162           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1163             :         {
    1164             :             LFR_PRINTF("in suspend_science_task *** CWF2 ERR %d\n", status);
    1165             :         }
    1166             :         else
    1167             :         {
    1168           4 :             status = RTEMS_SUCCESSFUL;
    1169             :         }
    1170             :     }
    1171           4 :     if (status == RTEMS_SUCCESSFUL) // suspend CWF1
    1172             :     {
    1173           4 :         status = rtems_task_suspend(Task_id[TASKID_CWF1]);
    1174           4 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1175             :         {
    1176             :             LFR_PRINTF("in suspend_science_task *** CWF1 ERR %d\n", status);
    1177             :         }
    1178             :         else
    1179             :         {
    1180           4 :             status = RTEMS_SUCCESSFUL;
    1181             :         }
    1182             :     }
    1183             : 
    1184           4 :     return status;
    1185             : }
    1186             : 
    1187           1 : int suspend_asm_tasks(void)
    1188             : {
    1189             :     /** This function suspends the science tasks.
    1190             :      *
    1191             :      * @return RTEMS directive status codes:
    1192             :      * - RTEMS_SUCCESSFUL - task restarted successfully
    1193             :      * - RTEMS_INVALID_ID - task id invalid
    1194             :      * - RTEMS_ALREADY_SUSPENDED - task already suspended
    1195             :      *
    1196             :      */
    1197             : 
    1198             :     rtems_status_code status;
    1199             : 
    1200             :     LFR_PRINTF("in suspend_science_tasks\n");
    1201             : 
    1202           1 :     status = rtems_task_suspend(Task_id[TASKID_AVF0]); // suspend AVF0
    1203           1 :     if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1204             :     {
    1205             :         LFR_PRINTF("in suspend_science_task *** AVF0 ERR %d\n", status);
    1206             :     }
    1207             :     else
    1208             :     {
    1209           1 :         status = RTEMS_SUCCESSFUL;
    1210             :     }
    1211             : 
    1212           1 :     if (status == RTEMS_SUCCESSFUL) // suspend PRC0
    1213             :     {
    1214           1 :         status = rtems_task_suspend(Task_id[TASKID_PRC0]);
    1215           1 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1216             :         {
    1217             :             LFR_PRINTF("in suspend_science_task *** PRC0 ERR %d\n", status);
    1218             :         }
    1219             :         else
    1220             :         {
    1221           1 :             status = RTEMS_SUCCESSFUL;
    1222             :         }
    1223             :     }
    1224             : 
    1225           1 :     if (status == RTEMS_SUCCESSFUL) // suspend AVF1
    1226             :     {
    1227           1 :         status = rtems_task_suspend(Task_id[TASKID_AVF1]);
    1228           1 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1229             :         {
    1230             :             LFR_PRINTF("in suspend_science_task *** AVF1 ERR %d\n", status);
    1231             :         }
    1232             :         else
    1233             :         {
    1234           1 :             status = RTEMS_SUCCESSFUL;
    1235             :         }
    1236             :     }
    1237             : 
    1238           1 :     if (status == RTEMS_SUCCESSFUL) // suspend PRC1
    1239             :     {
    1240           1 :         status = rtems_task_suspend(Task_id[TASKID_PRC1]);
    1241           1 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1242             :         {
    1243             :             LFR_PRINTF("in suspend_science_task *** PRC1 ERR %d\n", status);
    1244             :         }
    1245             :         else
    1246             :         {
    1247           1 :             status = RTEMS_SUCCESSFUL;
    1248             :         }
    1249             :     }
    1250             : 
    1251           1 :     if (status == RTEMS_SUCCESSFUL) // suspend AVF2
    1252             :     {
    1253           1 :         status = rtems_task_suspend(Task_id[TASKID_AVF2]);
    1254           1 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1255             :         {
    1256             :             LFR_PRINTF("in suspend_science_task *** AVF2 ERR %d\n", status);
    1257             :         }
    1258             :         else
    1259             :         {
    1260           1 :             status = RTEMS_SUCCESSFUL;
    1261             :         }
    1262             :     }
    1263             : 
    1264           1 :     if (status == RTEMS_SUCCESSFUL) // suspend PRC2
    1265             :     {
    1266           1 :         status = rtems_task_suspend(Task_id[TASKID_PRC2]);
    1267           1 :         if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
    1268             :         {
    1269             :             LFR_PRINTF("in suspend_science_task *** PRC2 ERR %d\n", status);
    1270             :         }
    1271             :         else
    1272             :         {
    1273           1 :             status = RTEMS_SUCCESSFUL;
    1274             :         }
    1275             :     }
    1276             : 
    1277           1 :     return status;
    1278             : }
    1279             : 
    1280           3 : void launch_waveform_picker(unsigned char mode, unsigned int transitionCoarseTime)
    1281             : {
    1282             : 
    1283           3 :     WFP_reset_current_ring_nodes();
    1284             : 
    1285           3 :     reset_waveform_picker_regs();
    1286             : 
    1287           3 :     set_wfp_burst_enable_register(mode);
    1288             : 
    1289           3 :     LEON_Clear_interrupt(IRQ_WAVEFORM_PICKER);
    1290           3 :     LEON_Unmask_interrupt(IRQ_WAVEFORM_PICKER);
    1291             : 
    1292           3 :     if (transitionCoarseTime == 0)
    1293             :     {
    1294             :         // instant transition means transition on the next valid date
    1295             :         // this is mandatory to have a good snapshot period and a good correction of the snapshot
    1296             :         // period
    1297           3 :         waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
    1298             :     }
    1299             :     else
    1300             :     {
    1301           0 :         waveform_picker_regs->start_date = transitionCoarseTime;
    1302             :     }
    1303             : 
    1304           3 :     update_last_valid_transition_date(waveform_picker_regs->start_date);
    1305           3 : }
    1306             : 
    1307           4 : void launch_spectral_matrix(void)
    1308             : {
    1309           4 :     SM_reset_current_ring_nodes();
    1310             : 
    1311           4 :     reset_spectral_matrix_regs();
    1312             : 
    1313           4 :     reset_nb_sm();
    1314             : 
    1315             :     set_sm_irq_onNewMatrix(1);
    1316             : 
    1317           4 :     LEON_Clear_interrupt(IRQ_SPECTRAL_MATRIX);
    1318           4 :     LEON_Unmask_interrupt(IRQ_SPECTRAL_MATRIX);
    1319           4 : }
    1320             : 
    1321           5 : void set_sm_irq_onNewMatrix(unsigned char value)
    1322             : {
    1323          13 :     if (value == 1)
    1324             :     {
    1325           4 :         spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_NEW_MATRIX;
    1326             :     }
    1327             :     else
    1328             :     {
    1329          18 :         spectral_matrix_regs->config
    1330           9 :             = spectral_matrix_regs->config & MASK_IRQ_ON_NEW_MATRIX; // 1110
    1331             :     }
    1332           5 : }
    1333             : 
    1334           5 : void set_sm_irq_onError(unsigned char value)
    1335             : {
    1336           5 :     if (value == 1)
    1337             :     {
    1338           0 :         spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_ERROR;
    1339             :     }
    1340             :     else
    1341             :     {
    1342           5 :         spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_ERROR; // 1101
    1343             :     }
    1344           5 : }
    1345             : 
    1346             : //*****************************
    1347             : // CONFIGURE CALIBRATION SIGNAL
    1348           0 : void setCalibrationPrescaler(unsigned int prescaler)
    1349             : {
    1350             :     // prescaling of the master clock (25 MHz)
    1351             :     // master clock is divided by 2^prescaler
    1352           1 :     time_management_regs->calPrescaler = prescaler;
    1353           0 : }
    1354             : 
    1355           0 : void setCalibrationDivisor(unsigned int divisionFactor)
    1356             : {
    1357             :     // division of the prescaled clock by the division factor
    1358           1 :     time_management_regs->calDivisor = divisionFactor;
    1359           0 : }
    1360             : 
    1361           1 : void setCalibrationData(void)
    1362             : {
    1363             :     /** This function is used to store the values used to drive the DAC in order to generate the SCM
    1364             :      * calibration signal
    1365             :      *
    1366             :      * @param void
    1367             :      *
    1368             :      * @return void
    1369             :      *
    1370             :      */
    1371             : 
    1372             :     unsigned short data;
    1373             :     float val;
    1374           1 :     float Ts = (float)(1. / CAL_FS);
    1375             : 
    1376           1 :     time_management_regs->calDataPtr = 0;
    1377             : 
    1378             : 
    1379             :     // build the signal for the SCM calibration
    1380         257 :     for (unsigned int k = 0; k < CAL_NB_PTS; k++)
    1381             :     {
    1382         256 :         val = (float)(CAL_A0 * sin(CAL_W0 * k * Ts) + CAL_A1 * sin(CAL_W1 * k * Ts));
    1383         256 :         data = (unsigned short)((val * CAL_SCALE_FACTOR) + CONST_2048);
    1384         256 :         time_management_regs->calData = data & CAL_DATA_MASK;
    1385             :     }
    1386           1 : }
    1387             : 
    1388           0 : void setCalibrationReload(bool state)
    1389             : {
    1390           1 :     if (state == true)
    1391             :     {
    1392           2 :         time_management_regs->calDACCtrl
    1393           1 :             = time_management_regs->calDACCtrl | BIT_CAL_RELOAD; // [0001 0000]
    1394             :     }
    1395             :     else
    1396             :     {
    1397           0 :         time_management_regs->calDACCtrl
    1398           0 :             = time_management_regs->calDACCtrl & MASK_CAL_RELOAD; // [1110 1111]
    1399             :     }
    1400           0 : }
    1401             : 
    1402           0 : void setCalibrationEnable(bool state)
    1403             : {
    1404             :     // this bit drives the multiplexer
    1405           1 :     if (state == true)
    1406             :     {
    1407           0 :         time_management_regs->calDACCtrl
    1408           0 :             = time_management_regs->calDACCtrl | BIT_CAL_ENABLE; // [0100 0000]
    1409             :     }
    1410             :     else
    1411             :     {
    1412           2 :         time_management_regs->calDACCtrl
    1413           1 :             = time_management_regs->calDACCtrl & MASK_CAL_ENABLE; // [1011 1111]
    1414             :     }
    1415           0 : }
    1416             : 
    1417             : 
    1418           1 : void setCalibration(bool state)
    1419             : {
    1420           1 :     if (state == true)
    1421             :     {
    1422             :         setCalibrationEnable(true);
    1423             :         setCalibrationReload(false);
    1424           0 :         set_hk_lfr_calib_enable(true);
    1425             :     }
    1426             :     else
    1427             :     {
    1428             :         setCalibrationEnable(false);
    1429             :         setCalibrationReload(true);
    1430           1 :         set_hk_lfr_calib_enable(false);
    1431             :     }
    1432           1 : }
    1433             : 
    1434           1 : void configureCalibration()
    1435             : {
    1436           1 :     setCalibration(false);
    1437             :     setCalibrationPrescaler(0); // 25 MHz   => 25 000 000
    1438             :     setCalibrationDivisor(CAL_F_DIVISOR); //          => 160 256 (39 - 1)
    1439           1 :     setCalibrationData();
    1440           1 : }
    1441             : 
    1442             : //****************
    1443             : // CLOSING ACTIONS
    1444          26 : void update_last_TC_exe(const ccsdsTelecommandPacket_t* const TC, const unsigned char* const time)
    1445             : {
    1446             :     /** This function is used to update the HK packets statistics after a successful TC execution.
    1447             :      *
    1448             :      * @param TC points to the TC being processed
    1449             :      * @param time is the time used to date the TC execution
    1450             :      *
    1451             :      */
    1452             : 
    1453             :     unsigned int val;
    1454             : 
    1455          26 :     housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
    1456          26 :     housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
    1457          26 :     housekeeping_packet.hk_lfr_last_exe_tc_type[0] = INIT_CHAR;
    1458          26 :     housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
    1459          26 :     housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = INIT_CHAR;
    1460          26 :     housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
    1461          26 :     housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_0] = time[BYTE_0];
    1462          26 :     housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_1] = time[BYTE_1];
    1463          26 :     housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_2] = time[BYTE_2];
    1464          26 :     housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_3] = time[BYTE_3];
    1465          26 :     housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_4] = time[BYTE_4];
    1466          26 :     housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_5] = time[BYTE_5];
    1467             : 
    1468          52 :     val = (housekeeping_packet.hk_lfr_exe_tc_cnt[0] * CONST_256)
    1469          26 :         + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
    1470          26 :     val++;
    1471          26 :     housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char)(val >> SHIFT_1_BYTE);
    1472          26 :     housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char)(val);
    1473          26 : }
    1474             : 
    1475           1 : void update_last_TC_rej(const ccsdsTelecommandPacket_t* const TC, const unsigned char* const time)
    1476             : {
    1477             :     /** This function is used to update the HK packets statistics after a TC rejection.
    1478             :      *
    1479             :      * @param TC points to the TC being processed
    1480             :      * @param time is the time used to date the TC rejection
    1481             :      *
    1482             :      */
    1483             : 
    1484             :     unsigned int val;
    1485             : 
    1486           1 :     housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
    1487           1 :     housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
    1488           1 :     housekeeping_packet.hk_lfr_last_rej_tc_type[0] = INIT_CHAR;
    1489           1 :     housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
    1490           1 :     housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = INIT_CHAR;
    1491           1 :     housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
    1492           1 :     housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_0] = time[BYTE_0];
    1493           1 :     housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_1] = time[BYTE_1];
    1494           1 :     housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_2] = time[BYTE_2];
    1495           1 :     housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_3] = time[BYTE_3];
    1496           1 :     housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_4] = time[BYTE_4];
    1497           1 :     housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_5] = time[BYTE_5];
    1498             : 
    1499           2 :     val = (housekeeping_packet.hk_lfr_rej_tc_cnt[0] * CONST_256)
    1500           1 :         + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
    1501           1 :     val++;
    1502           1 :     housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char)(val >> SHIFT_1_BYTE);
    1503           1 :     housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char)(val);
    1504           1 : }
    1505             : 
    1506          27 : void close_action(const ccsdsTelecommandPacket_t* const TC, int result, rtems_id queue_id)
    1507             : {
    1508             :     /** This function is the last step of the TC execution workflow.
    1509             :      *
    1510             :      * @param TC points to the TC being processed
    1511             :      * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
    1512             :      * @param queue_id is the id of the RTEMS message queue used to send TM packets
    1513             :      * @param time is the time used to date the TC execution
    1514             :      *
    1515             :      */
    1516             : 
    1517             :     unsigned char requestedMode;
    1518             : 
    1519          27 :     if (result == LFR_SUCCESSFUL)
    1520             :     {
    1521          52 :         if (!((TC->serviceType == TC_TYPE_TIME) & (TC->serviceSubType == TC_SUBTYPE_UPDT_TIME))
    1522          26 :             & !((TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_UPDT_INFO)))
    1523             :         {
    1524          26 :             send_tm_lfr_tc_exe_success(TC, queue_id);
    1525             :         }
    1526          26 :         if ((TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER))
    1527             :         {
    1528             :             //**********************************
    1529             :             // UPDATE THE LFRMODE LOCAL VARIABLE
    1530           5 :             requestedMode = TC->dataAndCRC[1];
    1531           5 :             updateLFRCurrentMode(requestedMode);
    1532             :         }
    1533             :     }
    1534           1 :     else if (result == LFR_EXE_ERROR)
    1535             :     {
    1536           0 :         send_tm_lfr_tc_exe_error(TC, queue_id);
    1537             :     }
    1538          27 : }
    1539             : 
    1540             : //****************
    1541             : // OTHER FUNCTIONS
    1542           1 : void updateLFRCurrentMode(unsigned char requestedMode)
    1543             : {
    1544             :     /** This function updates the value of the global variable lfrCurrentMode.
    1545             :      *
    1546             :      * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
    1547             :      *
    1548             :      */
    1549             : 
    1550             :     // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet
    1551             :     // structure
    1552           6 :     housekeeping_packet.lfr_status_word[0]
    1553           6 :         = (housekeeping_packet.lfr_status_word[0] & STATUS_WORD_LFR_MODE_MASK)
    1554             :         + (unsigned char)(requestedMode << STATUS_WORD_LFR_MODE_SHIFT);
    1555           6 :     lfrCurrentMode = requestedMode;
    1556           1 : }
    1557             : 
    1558           0 : void set_lfr_soft_reset(unsigned char value)
    1559             : {
    1560           8 :     if (value == 1)
    1561             :     {
    1562           4 :         time_management_regs->ctrl = time_management_regs->ctrl | BIT_SOFT_RESET; // [0100]
    1563             :     }
    1564             :     else
    1565             :     {
    1566           4 :         time_management_regs->ctrl = time_management_regs->ctrl & MASK_SOFT_RESET; // [1011]
    1567             :     }
    1568           0 : }
    1569             : 
    1570           4 : void reset_lfr(void)
    1571             : {
    1572             :     set_lfr_soft_reset(1);
    1573             : 
    1574             :     set_lfr_soft_reset(0);
    1575             : 
    1576           4 :     set_hk_lfr_sc_potential_flag(true);
    1577           4 : }

Generated by: LCOV version 1.14