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

          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           0 : ring_node* getRingNodeForAveraging(unsigned char frequencyChannel)
      70             : {
      71             :     ring_node* node;
      72             : 
      73           0 :     node = NULL;
      74           0 :     switch (frequencyChannel)
      75             :     {
      76             :         case CHANNELF0:
      77           0 :             node = ring_node_for_averaging_sm_f0;
      78           0 :             break;
      79             :         case CHANNELF1:
      80           0 :             node = ring_node_for_averaging_sm_f1;
      81           0 :             break;
      82             :         case CHANNELF2:
      83           0 :             node = ring_node_for_averaging_sm_f2;
      84             :             break;
      85             :         default:
      86             :             break;
      87             :     }
      88             : 
      89           0 :     return node;
      90             : }
      91             : 
      92             : //***********************************************************
      93             : // Interrupt Service Routine for spectral matrices processing
      94             : 
      95           0 : void spectral_matrices_isr_f0(int statusReg)
      96             : {
      97             :     unsigned char status;
      98             :     ring_node* full_ring_node;
      99             : 
     100           0 :     status = (unsigned char)(statusReg
     101             :         & BITS_STATUS_F0); // [0011] get the status_ready_matrix_f0_x bits
     102             : 
     103           0 :     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           0 :             full_ring_node = current_ring_node_sm_f0->previous;
     114           0 :             full_ring_node->coarseTime = spectral_matrix_regs->f0_0_coarse_time;
     115           0 :             full_ring_node->fineTime = spectral_matrix_regs->f0_0_fine_time;
     116           0 :             current_ring_node_sm_f0 = current_ring_node_sm_f0->next;
     117           0 :             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           0 :             nb_sm_f0 = nb_sm_f0 + 1;
     120           0 :             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           0 :             spectral_matrix_regs->status = BIT_READY_0; // [0000 0001]
     130           0 :             break;
     131             :         case BIT_READY_1:
     132           0 :             full_ring_node = current_ring_node_sm_f0->previous;
     133           0 :             full_ring_node->coarseTime = spectral_matrix_regs->f0_1_coarse_time;
     134           0 :             full_ring_node->fineTime = spectral_matrix_regs->f0_1_fine_time;
     135           0 :             current_ring_node_sm_f0 = current_ring_node_sm_f0->next;
     136           0 :             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           0 :             nb_sm_f0 = nb_sm_f0 + 1;
     139           0 :             if (nb_sm_f0 == NB_SM_BEFORE_AVF0_F1)
     140             :             {
     141           0 :                 ring_node_for_averaging_sm_f0 = full_ring_node;
     142           0 :                 if (rtems_event_send(Task_id[TASKID_AVF0], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     143             :                 {
     144             :                      send_event_dumb_task(RTEMS_EVENT_3);
     145             :                 }
     146           0 :                 nb_sm_f0 = 0;
     147             :             }
     148           0 :             spectral_matrix_regs->status = BIT_READY_1; // [0000 0010]
     149             :             break;
     150             :         default:
     151             :             break;
     152             :     }
     153           0 : }
     154             : 
     155           0 : void spectral_matrices_isr_f1(int statusReg)
     156             : {
     157             :     unsigned char status;
     158             :     ring_node* full_ring_node;
     159             : 
     160           0 :     status = (unsigned char)((statusReg & BITS_STATUS_F1)
     161             :         >> SHIFT_2_BITS); // [1100] get the status_ready_matrix_f1_x bits
     162             : 
     163           0 :     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           0 :             full_ring_node = current_ring_node_sm_f1->previous;
     174           0 :             full_ring_node->coarseTime = spectral_matrix_regs->f1_0_coarse_time;
     175           0 :             full_ring_node->fineTime = spectral_matrix_regs->f1_0_fine_time;
     176           0 :             current_ring_node_sm_f1 = current_ring_node_sm_f1->next;
     177           0 :             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           0 :             nb_sm_f1 = nb_sm_f1 + 1;
     180           0 :             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           0 :             spectral_matrix_regs->status = BIT_STATUS_F1_0; // [0000 0100]
     190           0 :             break;
     191             :         case BIT_READY_1:
     192           0 :             full_ring_node = current_ring_node_sm_f1->previous;
     193           0 :             full_ring_node->coarseTime = spectral_matrix_regs->f1_1_coarse_time;
     194           0 :             full_ring_node->fineTime = spectral_matrix_regs->f1_1_fine_time;
     195           0 :             current_ring_node_sm_f1 = current_ring_node_sm_f1->next;
     196           0 :             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           0 :             nb_sm_f1 = nb_sm_f1 + 1;
     199           0 :             if (nb_sm_f1 == NB_SM_BEFORE_AVF0_F1)
     200             :             {
     201           0 :                 ring_node_for_averaging_sm_f1 = full_ring_node;
     202           0 :                 if (rtems_event_send(Task_id[TASKID_AVF1], RTEMS_EVENT_0) != RTEMS_SUCCESSFUL)
     203             :                 {
     204             :                     send_event_dumb_task(RTEMS_EVENT_3);
     205             :                 }
     206           0 :                 nb_sm_f1 = 0;
     207             :             }
     208           0 :             spectral_matrix_regs->status = BIT_STATUS_F1_1; // [1000 0000]
     209             :             break;
     210             :         default:
     211             :             break;
     212             :     }
     213           0 : }
     214             : 
     215           0 : void spectral_matrices_isr_f2(int statusReg)
     216             : {
     217             :     unsigned char status;
     218             : 
     219           0 :     status = (unsigned char)((statusReg & BITS_STATUS_F2)
     220             :         >> SHIFT_4_BITS); // [0011 0000] get the status_ready_matrix_f2_x bits
     221             : 
     222           0 :     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           0 :             ring_node_for_averaging_sm_f2 = current_ring_node_sm_f2->previous;
     233           0 :             current_ring_node_sm_f2 = current_ring_node_sm_f2->next;
     234           0 :             ring_node_for_averaging_sm_f2->coarseTime = spectral_matrix_regs->f2_0_coarse_time;
     235           0 :             ring_node_for_averaging_sm_f2->fineTime = spectral_matrix_regs->f2_0_fine_time;
     236           0 :             spectral_matrix_regs->f2_0_address = current_ring_node_sm_f2->buffer_address;
     237           0 :             spectral_matrix_regs->status = BIT_STATUS_F2_0; // [0001 0000]
     238           0 :             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           0 :             ring_node_for_averaging_sm_f2 = current_ring_node_sm_f2->previous;
     245           0 :             current_ring_node_sm_f2 = current_ring_node_sm_f2->next;
     246           0 :             ring_node_for_averaging_sm_f2->coarseTime = spectral_matrix_regs->f2_1_coarse_time;
     247           0 :             ring_node_for_averaging_sm_f2->fineTime = spectral_matrix_regs->f2_1_fine_time;
     248           0 :             spectral_matrix_regs->f2_1_address = current_ring_node_sm_f2->buffer_address;
     249           0 :             spectral_matrix_regs->status = BIT_STATUS_F2_1; // [0010 0000]
     250           0 :             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           0 : }
     259             : 
     260           0 : 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           0 :     housekeeping_packet.hk_lfr_vhdl_aa_sm
     272           0 :         = (unsigned char)((statusReg & BITS_HK_AA_SM) >> SHIFT_7_BITS); // [0111 1000 0000]
     273             : 
     274           0 :     if (statusReg & BITS_SM_ERR) // [0111 1100 0000]
     275             :     {
     276             :         send_event_dumb_task(RTEMS_EVENT_8);
     277             :     }
     278             : 
     279           0 :     spectral_matrix_regs->status = spectral_matrix_regs->status & BITS_SM_ERR;
     280           0 : }
     281             : 
     282           0 : 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           0 :     statusReg = spectral_matrix_regs->status;
     297             : 
     298           0 :     if (thisIsAnASMRestart == 0)
     299             :     { // this is not a restart sequence, process incoming matrices normally
     300           0 :         spectral_matrices_isr_f0(statusReg);
     301             : 
     302           0 :         spectral_matrices_isr_f1(statusReg);
     303             : 
     304           0 :         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           0 :     spectral_matrix_isr_error_handler(statusReg);
     339           0 : }
     340             : 
     341             : //******************
     342             : // Spectral Matrices
     343             : 
     344           0 : void reset_nb_sm(void)
     345             : {
     346           0 :     nb_sm_f0 = 0;
     347           0 :     nb_sm_f0_aux_f1 = 0;
     348           0 :     nb_sm_f0_aux_f2 = 0;
     349             : 
     350           0 :     nb_sm_f1 = 0;
     351           0 : }
     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           0 : void ASM_generic_init_ring(ring_node_asm* ring, unsigned char nbNodes)
     368             : {
     369             :     DEBUG_CHECK_PTR(ring);
     370             : 
     371           0 :     ring[nbNodes - 1].next = &ring[0];
     372             : 
     373           0 :     for (unsigned char i = 0; i < nbNodes - 1; i++)
     374             :     {
     375           0 :         ring[i].next = &ring[i + 1];
     376             :     }
     377           0 : }
     378             : 
     379           1 : void SM_reset_current_ring_nodes(void)
     380             : {
     381           1 :     current_ring_node_sm_f0 = sm_ring_f0[0].next;
     382           1 :     current_ring_node_sm_f1 = sm_ring_f1[0].next;
     383           1 :     current_ring_node_sm_f2 = sm_ring_f2[0].next;
     384             : 
     385           1 :     ring_node_for_averaging_sm_f0 = NULL;
     386           1 :     ring_node_for_averaging_sm_f1 = NULL;
     387           1 :     ring_node_for_averaging_sm_f2 = NULL;
     388           1 : }
     389             : 
     390             : //*****************
     391             : // Basic Parameters
     392             : 
     393           0 : 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           0 :     packet->targetLogicalAddress = CCSDS_DESTINATION_ID;
     398           0 :     packet->protocolIdentifier = CCSDS_PROTOCOLE_ID;
     399           0 :     packet->reserved = INIT_CHAR;
     400           0 :     packet->userApplication = CCSDS_USER_APP;
     401           0 :     packet->packetID[0] = (unsigned char)(apid >> SHIFT_1_BYTE);
     402           0 :     packet->packetID[1] = (unsigned char)(apid);
     403           0 :     packet->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
     404           0 :     packet->packetSequenceControl[1] = INIT_CHAR;
     405           0 :     packet->packetLength[0] = (unsigned char)(packetLength >> SHIFT_1_BYTE);
     406           0 :     packet->packetLength[1] = (unsigned char)(packetLength);
     407             :     // DATA FIELD HEADER
     408           0 :     packet->spare1_pusVersion_spare2 = SPARE1_PUSVERSION_SPARE2;
     409           0 :     packet->serviceType = TM_TYPE_LFR_SCIENCE; // service type
     410           0 :     packet->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
     411           0 :     packet->destinationID = TM_DESTINATION_ID_GROUND;
     412           0 :     packet->time[BYTE_0] = INIT_CHAR;
     413           0 :     packet->time[BYTE_1] = INIT_CHAR;
     414           0 :     packet->time[BYTE_2] = INIT_CHAR;
     415           0 :     packet->time[BYTE_3] = INIT_CHAR;
     416           0 :     packet->time[BYTE_4] = INIT_CHAR;
     417           0 :     packet->time[BYTE_5] = INIT_CHAR;
     418             :     // AUXILIARY DATA HEADER
     419           0 :     packet->sid = sid;
     420           0 :     packet->pa_bia_status_info = INIT_CHAR;
     421           0 :     packet->sy_lfr_common_parameters_spare = INIT_CHAR;
     422           0 :     packet->sy_lfr_common_parameters = INIT_CHAR;
     423           0 :     packet->acquisitionTime[BYTE_0] = INIT_CHAR;
     424           0 :     packet->acquisitionTime[BYTE_1] = INIT_CHAR;
     425           0 :     packet->acquisitionTime[BYTE_2] = INIT_CHAR;
     426           0 :     packet->acquisitionTime[BYTE_3] = INIT_CHAR;
     427           0 :     packet->acquisitionTime[BYTE_4] = INIT_CHAR;
     428           0 :     packet->acquisitionTime[BYTE_5] = INIT_CHAR;
     429           0 :     packet->pa_lfr_bp_blk_nr[0] = INIT_CHAR; // BLK_NR MSB
     430           0 :     packet->pa_lfr_bp_blk_nr[1] = blkNr; // BLK_NR LSB
     431           0 : }
     432             : 
     433           0 : 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           0 :     packet->targetLogicalAddress = CCSDS_DESTINATION_ID;
     437           0 :     packet->protocolIdentifier = CCSDS_PROTOCOLE_ID;
     438           0 :     packet->reserved = INIT_CHAR;
     439           0 :     packet->userApplication = CCSDS_USER_APP;
     440           0 :     packet->packetID[0] = (unsigned char)(apid >> SHIFT_1_BYTE);
     441           0 :     packet->packetID[1] = (unsigned char)(apid);
     442           0 :     packet->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
     443           0 :     packet->packetSequenceControl[1] = INIT_CHAR;
     444           0 :     packet->packetLength[0] = (unsigned char)(packetLength >> SHIFT_1_BYTE);
     445           0 :     packet->packetLength[1] = (unsigned char)(packetLength);
     446             :     // DATA FIELD HEADER
     447           0 :     packet->spare1_pusVersion_spare2 = SPARE1_PUSVERSION_SPARE2;
     448           0 :     packet->serviceType = TM_TYPE_LFR_SCIENCE; // service type
     449           0 :     packet->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
     450           0 :     packet->destinationID = TM_DESTINATION_ID_GROUND;
     451             :     // AUXILIARY DATA HEADER
     452           0 :     packet->sid = sid;
     453           0 :     packet->pa_bia_status_info = INIT_CHAR;
     454           0 :     packet->sy_lfr_common_parameters_spare = INIT_CHAR;
     455           0 :     packet->sy_lfr_common_parameters = INIT_CHAR;
     456           0 :     packet->time[BYTE_0] = INIT_CHAR;
     457           0 :     packet->time[BYTE_1] = INIT_CHAR;
     458           0 :     packet->time[BYTE_2] = INIT_CHAR;
     459           0 :     packet->time[BYTE_3] = INIT_CHAR;
     460           0 :     packet->time[BYTE_4] = INIT_CHAR;
     461           0 :     packet->time[BYTE_5] = INIT_CHAR;
     462           0 :     packet->source_data_spare = INIT_CHAR;
     463           0 :     packet->pa_lfr_bp_blk_nr[0] = INIT_CHAR; // BLK_NR MSB
     464           0 :     packet->pa_lfr_bp_blk_nr[1] = blkNr; // BLK_NR LSB
     465           0 : }
     466             : 
     467           0 : void BP_send(const char* data, rtems_id queue_id, unsigned int nbBytesToSend)
     468             : {
     469             :     // SEND PACKET
     470             :     DEBUG_CHECK_PTR(data);
     471           0 :     DEBUG_CHECK_STATUS(rtems_message_queue_send(queue_id, data, nbBytesToSend));
     472           0 : }
     473             : 
     474           0 : 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           0 :     if (time_management_regs->coarse_time >= lastValidEnterModeTime)
     493             :     {
     494           0 :         DEBUG_CHECK_STATUS(rtems_message_queue_send(queue_id, data, nbBytesToSend));
     495             :     }
     496           0 : }
     497             : 
     498             : //******************
     499             : // general functions
     500             : 
     501           0 : 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           1 :     spectral_matrix_regs->status = BITS_STATUS_REG; // [0111 1111 1111]
     510           0 : }
     511             : 
     512           1 : 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           1 :     set_sm_irq_onError(0);
     528             : 
     529           1 :     set_sm_irq_onNewMatrix(0);
     530             : 
     531             :     reset_sm_status();
     532             : 
     533             :     // F1
     534           1 :     spectral_matrix_regs->f0_0_address = current_ring_node_sm_f0->previous->buffer_address;
     535           1 :     spectral_matrix_regs->f0_1_address = current_ring_node_sm_f0->buffer_address;
     536             :     // F2
     537           1 :     spectral_matrix_regs->f1_0_address = current_ring_node_sm_f1->previous->buffer_address;
     538           1 :     spectral_matrix_regs->f1_1_address = current_ring_node_sm_f1->buffer_address;
     539             :     // F3
     540           1 :     spectral_matrix_regs->f2_0_address = current_ring_node_sm_f2->previous->buffer_address;
     541           1 :     spectral_matrix_regs->f2_1_address = current_ring_node_sm_f2->buffer_address;
     542             : 
     543           1 :     spectral_matrix_regs->matrix_length = DEFAULT_MATRIX_LENGTH; // 25 * 128 / 16 = 200 = 0xc8
     544           1 : }
     545             : 
     546           0 : void set_time(unsigned char* time, const unsigned char* timeInBuffer)
     547             : {
     548           0 :     time[BYTE_0] = timeInBuffer[BYTE_0];
     549           0 :     time[BYTE_1] = timeInBuffer[BYTE_1];
     550           0 :     time[BYTE_2] = timeInBuffer[BYTE_2];
     551           0 :     time[BYTE_3] = timeInBuffer[BYTE_3];
     552           0 :     time[BYTE_4] = timeInBuffer[BYTE_6];
     553           0 :     time[BYTE_5] = timeInBuffer[BYTE_7];
     554           0 : }
     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