LCOV - code coverage report
Current view: top level - src/processing - fsw_processing.c (source / functions) Hit Total Coverage
Test: trace.info Lines: 205 230 89.1 %
Date: 2023-02-20 11:47:18 Functions: 17 18 94.4 %

          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             : 
      25             : /** Functions related to data processing.
      26             :  *
      27             :  * @file
      28             :  * @author P. LEROY
      29             :  *
      30             :  * These function are related to data processing, i.e. spectral matrices averaging and basic
      31             :  * parameters computation.
      32             :  *
      33             :  */
      34             : 
      35             : #include "processing/fsw_processing.h"
      36             : #include "fsw_compile_warnings.h"
      37             : #include "fsw_debug.h"
      38             : #include "fsw_init.h"
      39             : #include "fsw_processing_globals.c"
      40             : #include "hw/lfr_regs.h"
      41             : 
      42             : unsigned int nb_sm_f0 = 0;
      43             : unsigned int nb_sm_f0_aux_f1 = 0;
      44             : unsigned int nb_sm_f1 = 0;
      45             : unsigned int nb_sm_f0_aux_f2 = 0;
      46             : 
      47             : typedef enum restartState_t
      48             : {
      49             :     WAIT_FOR_F2,
      50             :     WAIT_FOR_F1,
      51             :     WAIT_FOR_F0
      52             : } restartState;
      53             : 
      54             : //************************
      55             : // spectral matrices rings
      56             : DISABLE_MISSING_FIELD_INITIALIZER_WARNING
      57             : ring_node sm_ring_f0[NB_RING_NODES_SM_F0] = { { 0 } };
      58             : ring_node sm_ring_f1[NB_RING_NODES_SM_F1] = { { 0 } };
      59             : ring_node sm_ring_f2[NB_RING_NODES_SM_F2] = { { 0 } };
      60             : ENABLE_MISSING_FIELD_INITIALIZER_WARNING
      61             : ring_node* current_ring_node_sm_f0 = NULL;
      62             : ring_node* current_ring_node_sm_f1 = NULL;
      63             : ring_node* current_ring_node_sm_f2 = NULL;
      64             : ring_node* ring_node_for_averaging_sm_f0 = NULL;
      65             : ring_node* ring_node_for_averaging_sm_f1 = NULL;
      66             : ring_node* ring_node_for_averaging_sm_f2 = NULL;
      67             : 
      68             : //
      69        6939 : ring_node* getRingNodeForAveraging(unsigned char frequencyChannel)
      70             : {
      71             :     ring_node* node;
      72             : 
      73        6939 :     node = NULL;
      74        6939 :     switch (frequencyChannel)
      75             :     {
      76             :         case CHANNELF0:
      77        5554 :             node = ring_node_for_averaging_sm_f0;
      78        5554 :             break;
      79             :         case CHANNELF1:
      80         924 :             node = ring_node_for_averaging_sm_f1;
      81         924 :             break;
      82             :         case CHANNELF2:
      83         461 :             node = ring_node_for_averaging_sm_f2;
      84             :             break;
      85             :         default:
      86             :             break;
      87             :     }
      88             : 
      89        6939 :     return node;
      90             : }
      91             : 
      92             : //***********************************************************
      93             : // Interrupt Service Routine for spectral matrices processing
      94             : 
      95       52332 : void spectral_matrices_isr_f0(int statusReg)
      96             : {
      97             :     unsigned char status;
      98             :     ring_node* full_ring_node;
      99             : 
     100       52332 :     status = (unsigned char)(statusReg
     101             :         & BITS_STATUS_F0); // [0011] get the status_ready_matrix_f0_x bits
     102             : 
     103       52332 :     switch (status)
     104             :     {
     105             :         case 0:
     106             :             break;
     107             :         case BIT_READY_0_1:
     108             :             // UNEXPECTED VALUE
     109           0 :             spectral_matrix_regs->status = BIT_READY_0_1; // [0011]
     110             :             send_event_dumb_task(RTEMS_EVENT_11);
     111             :             break;
     112             :         case BIT_READY_0:
     113       22233 :             full_ring_node = current_ring_node_sm_f0->previous;
     114       22233 :             full_ring_node->coarseTime = spectral_matrix_regs->f0_0_coarse_time;
     115       22233 :             full_ring_node->fineTime = spectral_matrix_regs->f0_0_fine_time;
     116       22233 :             current_ring_node_sm_f0 = current_ring_node_sm_f0->next;
     117       22233 :             spectral_matrix_regs->f0_0_address = current_ring_node_sm_f0->buffer_address;
     118             :             // if there are enough ring nodes ready, wake up an AVFx task
     119       22233 :             nb_sm_f0 = nb_sm_f0 + 1;
     120       22233 :             if (nb_sm_f0 == NB_SM_BEFORE_AVF0_F1)
     121             :             {
     122           0 :                 ring_node_for_averaging_sm_f0 = full_ring_node;
     123           0 :                 if (rtems_event_send(Task_id[TASKID_AVF0], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     124             :                 {
     125             :                      send_event_dumb_task(RTEMS_EVENT_3);
     126             :                 }
     127           0 :                 nb_sm_f0 = 0;
     128             :             }
     129       22233 :             spectral_matrix_regs->status = BIT_READY_0; // [0000 0001]
     130       22233 :             break;
     131             :         case BIT_READY_1:
     132       22231 :             full_ring_node = current_ring_node_sm_f0->previous;
     133       22231 :             full_ring_node->coarseTime = spectral_matrix_regs->f0_1_coarse_time;
     134       22231 :             full_ring_node->fineTime = spectral_matrix_regs->f0_1_fine_time;
     135       22231 :             current_ring_node_sm_f0 = current_ring_node_sm_f0->next;
     136       22231 :             spectral_matrix_regs->f0_1_address = current_ring_node_sm_f0->buffer_address;
     137             :             // if there are enough ring nodes ready, wake up an AVFx task
     138       22231 :             nb_sm_f0 = nb_sm_f0 + 1;
     139       22231 :             if (nb_sm_f0 == NB_SM_BEFORE_AVF0_F1)
     140             :             {
     141        5556 :                 ring_node_for_averaging_sm_f0 = full_ring_node;
     142        5556 :                 if (rtems_event_send(Task_id[TASKID_AVF0], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     143             :                 {
     144             :                      send_event_dumb_task(RTEMS_EVENT_3);
     145             :                 }
     146        5556 :                 nb_sm_f0 = 0;
     147             :             }
     148       22231 :             spectral_matrix_regs->status = BIT_READY_1; // [0000 0010]
     149             :             break;
     150             :         default:
     151             :             break;
     152             :     }
     153       52332 : }
     154             : 
     155       52332 : void spectral_matrices_isr_f1(int statusReg)
     156             : {
     157             :     unsigned char status;
     158             :     ring_node* full_ring_node;
     159             : 
     160       52332 :     status = (unsigned char)((statusReg & BITS_STATUS_F1)
     161             :         >> SHIFT_2_BITS); // [1100] get the status_ready_matrix_f1_x bits
     162             : 
     163       52332 :     switch (status)
     164             :     {
     165             :         case 0:
     166             :             break;
     167             :         case BIT_READY_0_1:
     168             :             // UNEXPECTED VALUE
     169           0 :             spectral_matrix_regs->status = BITS_STATUS_F1; // [1100]
     170             :             send_event_dumb_task(RTEMS_EVENT_11);
     171             :             break;
     172             :         case BIT_READY_0:
     173        3705 :             full_ring_node = current_ring_node_sm_f1->previous;
     174        3705 :             full_ring_node->coarseTime = spectral_matrix_regs->f1_0_coarse_time;
     175        3705 :             full_ring_node->fineTime = spectral_matrix_regs->f1_0_fine_time;
     176        3705 :             current_ring_node_sm_f1 = current_ring_node_sm_f1->next;
     177        3705 :             spectral_matrix_regs->f1_0_address = current_ring_node_sm_f1->buffer_address;
     178             :             // if there are enough ring nodes ready, wake up an AVFx task
     179        3705 :             nb_sm_f1 = nb_sm_f1 + 1;
     180        3705 :             if (nb_sm_f1 == NB_SM_BEFORE_AVF0_F1)
     181             :             {
     182           0 :                 ring_node_for_averaging_sm_f1 = full_ring_node;
     183           0 :                 if (rtems_event_send(Task_id[TASKID_AVF1], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     184             :                 {
     185             :                     send_event_dumb_task(RTEMS_EVENT_3);
     186             :                 }
     187           0 :                 nb_sm_f1 = 0;
     188             :             }
     189        3705 :             spectral_matrix_regs->status = BIT_STATUS_F1_0; // [0000 0100]
     190        3705 :             break;
     191             :         case BIT_READY_1:
     192        3704 :             full_ring_node = current_ring_node_sm_f1->previous;
     193        3704 :             full_ring_node->coarseTime = spectral_matrix_regs->f1_1_coarse_time;
     194        3704 :             full_ring_node->fineTime = spectral_matrix_regs->f1_1_fine_time;
     195        3704 :             current_ring_node_sm_f1 = current_ring_node_sm_f1->next;
     196        3704 :             spectral_matrix_regs->f1_1_address = current_ring_node_sm_f1->buffer_address;
     197             :             // if there are enough ring nodes ready, wake up an AVFx task
     198        3704 :             nb_sm_f1 = nb_sm_f1 + 1;
     199        3704 :             if (nb_sm_f1 == NB_SM_BEFORE_AVF0_F1)
     200             :             {
     201         924 :                 ring_node_for_averaging_sm_f1 = full_ring_node;
     202         924 :                 if (rtems_event_send(Task_id[TASKID_AVF1], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     203             :                 {
     204             :                     send_event_dumb_task(RTEMS_EVENT_3);
     205             :                 }
     206         924 :                 nb_sm_f1 = 0;
     207             :             }
     208        3704 :             spectral_matrix_regs->status = BIT_STATUS_F1_1; // [1000 0000]
     209             :             break;
     210             :         default:
     211             :             break;
     212             :     }
     213       52332 : }
     214             : 
     215       52332 : void spectral_matrices_isr_f2(int statusReg)
     216             : {
     217             :     unsigned char status;
     218             : 
     219       52332 :     status = (unsigned char)((statusReg & BITS_STATUS_F2)
     220             :         >> SHIFT_4_BITS); // [0011 0000] get the status_ready_matrix_f2_x bits
     221             : 
     222       52332 :     switch (status)
     223             :     {
     224             :         case 0:
     225             :             break;
     226             :         case BIT_READY_0_1:
     227             :             // UNEXPECTED VALUE
     228           0 :             spectral_matrix_regs->status = BITS_STATUS_F2; // [0011 0000]
     229             :             send_event_dumb_task(RTEMS_EVENT_11);
     230             :             break;
     231             :         case BIT_READY_0:
     232         231 :             ring_node_for_averaging_sm_f2 = current_ring_node_sm_f2->previous;
     233         231 :             current_ring_node_sm_f2 = current_ring_node_sm_f2->next;
     234         231 :             ring_node_for_averaging_sm_f2->coarseTime = spectral_matrix_regs->f2_0_coarse_time;
     235         231 :             ring_node_for_averaging_sm_f2->fineTime = spectral_matrix_regs->f2_0_fine_time;
     236         231 :             spectral_matrix_regs->f2_0_address = current_ring_node_sm_f2->buffer_address;
     237         231 :             spectral_matrix_regs->status = BIT_STATUS_F2_0; // [0001 0000]
     238         231 :             if (rtems_event_send(Task_id[TASKID_AVF2], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     239             :             {
     240             :                 send_event_dumb_task(RTEMS_EVENT_3);
     241             :             }
     242             :             break;
     243             :         case BIT_READY_1:
     244         230 :             ring_node_for_averaging_sm_f2 = current_ring_node_sm_f2->previous;
     245         230 :             current_ring_node_sm_f2 = current_ring_node_sm_f2->next;
     246         230 :             ring_node_for_averaging_sm_f2->coarseTime = spectral_matrix_regs->f2_1_coarse_time;
     247         230 :             ring_node_for_averaging_sm_f2->fineTime = spectral_matrix_regs->f2_1_fine_time;
     248         230 :             spectral_matrix_regs->f2_1_address = current_ring_node_sm_f2->buffer_address;
     249         230 :             spectral_matrix_regs->status = BIT_STATUS_F2_1; // [0010 0000]
     250         230 :             if (rtems_event_send(Task_id[TASKID_AVF2], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     251             :             {
     252             :                 send_event_dumb_task(RTEMS_EVENT_3);
     253             :             }
     254             :             break;
     255             :         default:
     256             :             break;
     257             :     }
     258       52332 : }
     259             : 
     260       52332 : void spectral_matrix_isr_error_handler(int statusReg)
     261             : {
     262             :     // STATUS REGISTER
     263             :     // input_fifo_write(2) *** input_fifo_write(1) *** input_fifo_write(0)
     264             :     //           10                    9                       8
     265             :     // buffer_full ** [bad_component_err] ** f2_1 ** f2_0 ** f1_1 ** f1_0 ** f0_1 ** f0_0
     266             :     //      7                  6             5       4       3       2       1       0
     267             :     // [bad_component_err] not defined in the last version of the VHDL code
     268             : 
     269             :     //***************************************************
     270             :     // the ASM status register is copied in the HK packet
     271       52332 :     housekeeping_packet.hk_lfr_vhdl_aa_sm
     272       52332 :         = (unsigned char)((statusReg & BITS_HK_AA_SM) >> SHIFT_7_BITS); // [0111 1000 0000]
     273             : 
     274       52332 :     if (statusReg & BITS_SM_ERR) // [0111 1100 0000]
     275             :     {
     276             :         send_event_dumb_task(RTEMS_EVENT_8);
     277             :     }
     278             : 
     279       52332 :     spectral_matrix_regs->status = spectral_matrix_regs->status & BITS_SM_ERR;
     280       52332 : }
     281             : 
     282       52332 : rtems_isr spectral_matrices_isr(rtems_vector_number vector)
     283             : {
     284             :     // STATUS REGISTER
     285             :     // input_fifo_write(2) *** input_fifo_write(1) *** input_fifo_write(0)
     286             :     //           10                    9                       8
     287             :     // buffer_full ** bad_component_err ** f2_1 ** f2_0 ** f1_1 ** f1_0 ** f0_1 ** f0_0
     288             :     //      7                  6             5       4       3       2       1       0
     289             : 
     290             :     IGNORE_UNUSED_PARAMETER(vector);
     291             : 
     292             :     int statusReg;
     293             : 
     294             :     static restartState state = WAIT_FOR_F2;
     295             : 
     296       52332 :     statusReg = spectral_matrix_regs->status;
     297             : 
     298       52332 :     if (thisIsAnASMRestart == 0)
     299             :     { // this is not a restart sequence, process incoming matrices normally
     300       52332 :         spectral_matrices_isr_f0(statusReg);
     301             : 
     302       52332 :         spectral_matrices_isr_f1(statusReg);
     303             : 
     304       52332 :         spectral_matrices_isr_f2(statusReg);
     305             :     }
     306             :     else
     307             :     { // a restart sequence has to be launched
     308           0 :         switch (state)
     309             :         {
     310             :             case WAIT_FOR_F2:
     311           0 :                 if ((statusReg & BITS_STATUS_F2)
     312             :                     != INIT_CHAR) // [0011 0000] check the status_ready_matrix_f2_x bits
     313             :                 {
     314           0 :                     state = WAIT_FOR_F1;
     315             :                 }
     316             :                 break;
     317             :             case WAIT_FOR_F1:
     318           0 :                 if ((statusReg & BITS_STATUS_F1)
     319             :                     != INIT_CHAR) // [0000 1100] check the status_ready_matrix_f1_x bits
     320             :                 {
     321           0 :                     state = WAIT_FOR_F0;
     322             :                 }
     323             :                 break;
     324             :             case WAIT_FOR_F0:
     325           0 :                 if ((statusReg & BITS_STATUS_F0)
     326             :                     != INIT_CHAR) // [0000 0011] check the status_ready_matrix_f0_x bits
     327             :                 {
     328           0 :                     state = WAIT_FOR_F2;
     329           0 :                     thisIsAnASMRestart = 0;
     330             :                 }
     331             :                 break;
     332             :             default:
     333             :                 break;
     334             :         }
     335             :         reset_sm_status();
     336             :     }
     337             : 
     338       52332 :     spectral_matrix_isr_error_handler(statusReg);
     339       52332 : }
     340             : 
     341             : //******************
     342             : // Spectral Matrices
     343             : 
     344           4 : void reset_nb_sm(void)
     345             : {
     346           4 :     nb_sm_f0 = 0;
     347           4 :     nb_sm_f0_aux_f1 = 0;
     348           4 :     nb_sm_f0_aux_f2 = 0;
     349             : 
     350           4 :     nb_sm_f1 = 0;
     351           4 : }
     352             : 
     353           1 : void SM_init_rings(void)
     354             : {
     355           1 :     init_ring(sm_ring_f0, NB_RING_NODES_SM_F0, sm_f0, TOTAL_SIZE_SM);
     356           1 :     init_ring(sm_ring_f1, NB_RING_NODES_SM_F1, sm_f1, TOTAL_SIZE_SM);
     357           1 :     init_ring(sm_ring_f2, NB_RING_NODES_SM_F2, sm_f2, TOTAL_SIZE_SM);
     358             : 
     359             :     DEBUG_PRINTF("sm_ring_f0 @%x\n", (unsigned int)sm_ring_f0);
     360             :     DEBUG_PRINTF("sm_ring_f1 @%x\n", (unsigned int)sm_ring_f1);
     361             :     DEBUG_PRINTF("sm_ring_f2 @%x\n", (unsigned int)sm_ring_f2);
     362             :     DEBUG_PRINTF("sm_f0 @%x\n", (unsigned int)sm_f0);
     363             :     DEBUG_PRINTF("sm_f1 @%x\n", (unsigned int)sm_f1);
     364             :     DEBUG_PRINTF("sm_f2 @%x\n", (unsigned int)sm_f2);
     365           1 : }
     366             : 
     367          20 : void ASM_generic_init_ring(ring_node_asm* ring, unsigned char nbNodes)
     368             : {
     369             :     DEBUG_CHECK_PTR(ring);
     370             : 
     371          20 :     ring[nbNodes - 1].next = &ring[0];
     372             : 
     373         132 :     for (unsigned char i = 0; i < nbNodes - 1; i++)
     374             :     {
     375         112 :         ring[i].next = &ring[i + 1];
     376             :     }
     377          20 : }
     378             : 
     379           5 : void SM_reset_current_ring_nodes(void)
     380             : {
     381           5 :     current_ring_node_sm_f0 = sm_ring_f0[0].next;
     382           5 :     current_ring_node_sm_f1 = sm_ring_f1[0].next;
     383           5 :     current_ring_node_sm_f2 = sm_ring_f2[0].next;
     384             : 
     385           5 :     ring_node_for_averaging_sm_f0 = NULL;
     386           5 :     ring_node_for_averaging_sm_f1 = NULL;
     387           5 :     ring_node_for_averaging_sm_f2 = NULL;
     388           5 : }
     389             : 
     390             : //*****************
     391             : // Basic Parameters
     392             : 
     393          26 : void BP_init_header(bp_packet* packet, unsigned int apid, unsigned char sid,
     394             :     unsigned int packetLength, unsigned char blkNr)
     395             : {
     396             :     DEBUG_CHECK_PTR(packet);
     397          26 :     packet->targetLogicalAddress = CCSDS_DESTINATION_ID;
     398          26 :     packet->protocolIdentifier = CCSDS_PROTOCOLE_ID;
     399          26 :     packet->reserved = INIT_CHAR;
     400          26 :     packet->userApplication = CCSDS_USER_APP;
     401          26 :     packet->packetID[0] = (unsigned char)(apid >> SHIFT_1_BYTE);
     402          26 :     packet->packetID[1] = (unsigned char)(apid);
     403          26 :     packet->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
     404          26 :     packet->packetSequenceControl[1] = INIT_CHAR;
     405          26 :     packet->packetLength[0] = (unsigned char)(packetLength >> SHIFT_1_BYTE);
     406          26 :     packet->packetLength[1] = (unsigned char)(packetLength);
     407             :     // DATA FIELD HEADER
     408          26 :     packet->spare1_pusVersion_spare2 = SPARE1_PUSVERSION_SPARE2;
     409          26 :     packet->serviceType = TM_TYPE_LFR_SCIENCE; // service type
     410          26 :     packet->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
     411          26 :     packet->destinationID = TM_DESTINATION_ID_GROUND;
     412          26 :     packet->time[BYTE_0] = INIT_CHAR;
     413          26 :     packet->time[BYTE_1] = INIT_CHAR;
     414          26 :     packet->time[BYTE_2] = INIT_CHAR;
     415          26 :     packet->time[BYTE_3] = INIT_CHAR;
     416          26 :     packet->time[BYTE_4] = INIT_CHAR;
     417          26 :     packet->time[BYTE_5] = INIT_CHAR;
     418             :     // AUXILIARY DATA HEADER
     419          26 :     packet->sid = sid;
     420          26 :     packet->pa_bia_status_info = INIT_CHAR;
     421          26 :     packet->sy_lfr_common_parameters_spare = INIT_CHAR;
     422          26 :     packet->sy_lfr_common_parameters = INIT_CHAR;
     423          26 :     packet->acquisitionTime[BYTE_0] = INIT_CHAR;
     424          26 :     packet->acquisitionTime[BYTE_1] = INIT_CHAR;
     425          26 :     packet->acquisitionTime[BYTE_2] = INIT_CHAR;
     426          26 :     packet->acquisitionTime[BYTE_3] = INIT_CHAR;
     427          26 :     packet->acquisitionTime[BYTE_4] = INIT_CHAR;
     428          26 :     packet->acquisitionTime[BYTE_5] = INIT_CHAR;
     429          26 :     packet->pa_lfr_bp_blk_nr[0] = INIT_CHAR; // BLK_NR MSB
     430          26 :     packet->pa_lfr_bp_blk_nr[1] = blkNr; // BLK_NR LSB
     431          26 : }
     432             : 
     433           8 : void BP_init_header_with_spare(bp_packet_with_spare* packet, unsigned int apid, unsigned char sid,
     434             :     unsigned int packetLength, unsigned char blkNr)
     435             : {
     436           8 :     packet->targetLogicalAddress = CCSDS_DESTINATION_ID;
     437           8 :     packet->protocolIdentifier = CCSDS_PROTOCOLE_ID;
     438           8 :     packet->reserved = INIT_CHAR;
     439           8 :     packet->userApplication = CCSDS_USER_APP;
     440           8 :     packet->packetID[0] = (unsigned char)(apid >> SHIFT_1_BYTE);
     441           8 :     packet->packetID[1] = (unsigned char)(apid);
     442           8 :     packet->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
     443           8 :     packet->packetSequenceControl[1] = INIT_CHAR;
     444           8 :     packet->packetLength[0] = (unsigned char)(packetLength >> SHIFT_1_BYTE);
     445           8 :     packet->packetLength[1] = (unsigned char)(packetLength);
     446             :     // DATA FIELD HEADER
     447           8 :     packet->spare1_pusVersion_spare2 = SPARE1_PUSVERSION_SPARE2;
     448           8 :     packet->serviceType = TM_TYPE_LFR_SCIENCE; // service type
     449           8 :     packet->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
     450           8 :     packet->destinationID = TM_DESTINATION_ID_GROUND;
     451             :     // AUXILIARY DATA HEADER
     452           8 :     packet->sid = sid;
     453           8 :     packet->pa_bia_status_info = INIT_CHAR;
     454           8 :     packet->sy_lfr_common_parameters_spare = INIT_CHAR;
     455           8 :     packet->sy_lfr_common_parameters = INIT_CHAR;
     456           8 :     packet->time[BYTE_0] = INIT_CHAR;
     457           8 :     packet->time[BYTE_1] = INIT_CHAR;
     458           8 :     packet->time[BYTE_2] = INIT_CHAR;
     459           8 :     packet->time[BYTE_3] = INIT_CHAR;
     460           8 :     packet->time[BYTE_4] = INIT_CHAR;
     461           8 :     packet->time[BYTE_5] = INIT_CHAR;
     462           8 :     packet->source_data_spare = INIT_CHAR;
     463           8 :     packet->pa_lfr_bp_blk_nr[0] = INIT_CHAR; // BLK_NR MSB
     464           8 :     packet->pa_lfr_bp_blk_nr[1] = blkNr; // BLK_NR LSB
     465           8 : }
     466             : 
     467         290 : void BP_send(const char* data, rtems_id queue_id, unsigned int nbBytesToSend)
     468             : {
     469             :     // SEND PACKET
     470             :     DEBUG_CHECK_PTR(data);
     471         290 :     DEBUG_CHECK_STATUS(rtems_message_queue_send(queue_id, data, nbBytesToSend));
     472         290 : }
     473             : 
     474        1204 : void BP_send_s1_s2(const char* data, rtems_id queue_id, unsigned int nbBytesToSend)
     475             : {
     476             :     /** This function is used to send the BP paquets when needed.
     477             :      *
     478             :      * @param transitionCoarseTime is the requested transition time contained in the
     479             :      * TC_LFR_ENTER_MODE
     480             :      *
     481             :      * @return void
     482             :      *
     483             :      * SBM1 and SBM2 paquets are sent depending on the type of the LFR mode transition.
     484             :      * BURST paquets are sent everytime.
     485             :      *
     486             :      */
     487             :     DEBUG_CHECK_PTR(data);
     488             : 
     489             :     // SEND PACKET
     490             :     // before lastValidTransitionDate, the data are drops even if they are ready
     491             :     // this guarantees that no SBM packets will be received before the requested enter mode time
     492        1204 :     if (time_management_regs->coarse_time >= lastValidEnterModeTime)
     493             :     {
     494        1204 :         DEBUG_CHECK_STATUS(rtems_message_queue_send(queue_id, data, nbBytesToSend));
     495             :     }
     496        1204 : }
     497             : 
     498             : //******************
     499             : // general functions
     500             : 
     501           5 : void reset_sm_status(void)
     502             : {
     503             :     // error
     504             :     // 10 --------------- 9 ---------------- 8 ---------------- 7 ---------
     505             :     // input_fif0_write_2 input_fifo_write_1 input_fifo_write_0 buffer_full
     506             :     // ---------- 5 -- 4 -- 3 -- 2 -- 1 -- 0 --
     507             :     // ready bits f2_1 f2_0 f1_1 f1_1 f0_1 f0_0
     508             : 
     509          10 :     spectral_matrix_regs->status = BITS_STATUS_REG; // [0111 1111 1111]
     510           5 : }
     511             : 
     512           5 : void reset_spectral_matrix_regs(void)
     513             : {
     514             :     /** This function resets the spectral matrices module registers.
     515             :      *
     516             :      * The registers affected by this function are located at the following offset addresses:
     517             :      *
     518             :      * - 0x00 config
     519             :      * - 0x04 status
     520             :      * - 0x08 matrixF0_Address0
     521             :      * - 0x10 matrixFO_Address1
     522             :      * - 0x14 matrixF1_Address
     523             :      * - 0x18 matrixF2_Address
     524             :      *
     525             :      */
     526             : 
     527           5 :     set_sm_irq_onError(0);
     528             : 
     529           5 :     set_sm_irq_onNewMatrix(0);
     530             : 
     531             :     reset_sm_status();
     532             : 
     533             :     // F1
     534           5 :     spectral_matrix_regs->f0_0_address = current_ring_node_sm_f0->previous->buffer_address;
     535           5 :     spectral_matrix_regs->f0_1_address = current_ring_node_sm_f0->buffer_address;
     536             :     // F2
     537           5 :     spectral_matrix_regs->f1_0_address = current_ring_node_sm_f1->previous->buffer_address;
     538           5 :     spectral_matrix_regs->f1_1_address = current_ring_node_sm_f1->buffer_address;
     539             :     // F3
     540           5 :     spectral_matrix_regs->f2_0_address = current_ring_node_sm_f2->previous->buffer_address;
     541           5 :     spectral_matrix_regs->f2_1_address = current_ring_node_sm_f2->buffer_address;
     542             : 
     543           5 :     spectral_matrix_regs->matrix_length = DEFAULT_MATRIX_LENGTH; // 25 * 128 / 16 = 200 = 0xc8
     544           5 : }
     545             : 
     546        2988 : void set_time(unsigned char* time, const unsigned char* timeInBuffer)
     547             : {
     548        2988 :     time[BYTE_0] = timeInBuffer[BYTE_0];
     549        2988 :     time[BYTE_1] = timeInBuffer[BYTE_1];
     550        2988 :     time[BYTE_2] = timeInBuffer[BYTE_2];
     551        2988 :     time[BYTE_3] = timeInBuffer[BYTE_3];
     552        2988 :     time[BYTE_4] = timeInBuffer[BYTE_6];
     553        2988 :     time[BYTE_5] = timeInBuffer[BYTE_7];
     554        2988 : }
     555             : 
     556           0 : unsigned long long int get_acquisition_time(const unsigned char* const timePtr)
     557             : {
     558             :     unsigned long long int acquisitionTimeAslong;
     559           0 :     acquisitionTimeAslong = ((unsigned long long int)(timePtr[BYTE_0] & SYNC_BIT_MASK)
     560             :                                 << SHIFT_5_BYTES) // [0111 1111] mask the synchronization bit
     561           0 :         + ((unsigned long long int)timePtr[BYTE_1] << SHIFT_4_BYTES)
     562           0 :         + ((unsigned long long int)timePtr[BYTE_2] << SHIFT_3_BYTES)
     563           0 :         + ((unsigned long long int)timePtr[BYTE_3] << SHIFT_2_BYTES)
     564           0 :         + ((unsigned long long int)timePtr[BYTE_6] << SHIFT_1_BYTE)
     565           0 :         + ((unsigned long long int)timePtr[BYTE_7]);
     566           0 :     return acquisitionTimeAslong;
     567             : }

Generated by: LCOV version 1.14