LCOV - code coverage report
Current view: top level - felix-star/src - l1id_decoder.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 38 145 26.2 %
Date: 2025-06-10 03:23:28 Functions: 5 10 50.0 %

          Line data    Source code
       1             : #include "l1id_decoder.h"
       2             : #include "felix/felix_fid.h"
       3             : #include "log.h"
       4             : 
       5             : static int (*check_sequence)(uint64_t fid, struct l1id_data* xl1id, const uint8_t* data, size_t size);
       6             : static int check_sequence_latome( uint64_t fid, struct l1id_data* xl1id, const uint8_t* data, size_t size);
       7             : static int check_sequence_fmemu(  uint64_t fid, struct l1id_data* xl1id, const uint8_t* data, size_t size);
       8             : static int check_sequence_felig(  uint64_t fid, struct l1id_data* xl1id, const uint8_t* data, size_t size);
       9             : static int check_sequence_nsw_vmm(uint64_t fid, struct l1id_data* xl1id, const uint8_t* data, size_t size);
      10             : static int check_sequence_nsw_tp( uint64_t fid, struct l1id_data* xl1id, const uint8_t* data, size_t size);
      11             : 
      12             : 
      13           8 : static inline int compare(uint64_t fid, xl1id_t current, xl1id_t expected)
      14             : {
      15           8 :   if(current.fields.ec != expected.fields.ec){
      16           0 :     LOG_INFO("fid 0x%lx (0x%x) has L1ID 0x%06x, expected 0x%06x", fid, get_elink(fid), current.fields.ec, expected.fields.ec);
      17           0 :     return 1;
      18             :   }
      19             :   return 0;
      20             : }
      21             : 
      22         600 : int is_ttc2h_elink(uint64_t fid)
      23             : {
      24         600 :   uint32_t elink = get_elink(fid);
      25         600 :   if (elink == 315 || elink == 827 || elink == 1537 || elink == 0x600){
      26             :     return 1;
      27             :   } else {
      28           0 :     return 0;
      29             :   }
      30             : }
      31             : 
      32           8 : int check_sequence_ttc2h(uint64_t fid, struct l1id_data* last, const uint8_t* data, size_t size)
      33             : {
      34           8 :   if(size < 8){
      35           0 :     LOG_INFO("TTC2H message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", fid, get_elink(fid), size);
      36           0 :     return 1;
      37             :   }
      38           8 :   xl1id_t current, expected;
      39           8 :   bcid_t current_bc;
      40           8 :   current_bc.bc_data = ((uint32_t*)data)[0];
      41           8 :   current.xl1id = ((uint32_t*)data)[1];
      42           8 :   LOG_DBG("Current L1ID 0x%06x BCID 0x%04x", current.fields.ec, current_bc.fields.bcid);
      43           8 :   if(current.fields.ecrc == (last->l1id.fields.ecrc+1)){
      44           0 :     LOG_INFO("ECR on TTC2H fid 0x%lx (0x%x)", fid, get_elink(fid));
      45           0 :     expected.fields.ec = 0x0;
      46             :   } else {
      47           8 :     expected.fields.ec = (last->l1id.fields.ec+1) & 0x00ffffff;
      48             :   }
      49           8 :   int ret = compare(fid, current, expected);
      50           8 :   if (ret) {
      51           0 :       LOG_INFO("fid 0x%lx last data block address = %p, current data block address = %p",
      52             :               fid, last->ptr, data);
      53             :   }
      54           8 :   last->mask = 0xffffffff;
      55           8 :   last->l1id.xl1id = current.xl1id;
      56           8 :   last->ptr = data;
      57           8 :   return ret;
      58             : }
      59             : 
      60             : 
      61           8 : int check_sequence_daq(uint64_t fid, struct l1id_data* xl1id, const uint8_t* data, size_t size)
      62             : {
      63           8 :   int ret = 0;
      64           8 :   if(check_sequence){
      65           0 :     ret = check_sequence(fid, xl1id, data, size);
      66             :   }
      67           8 :   return ret;
      68             : }
      69             : 
      70             : 
      71          48 : void init_l1id_decoder(int format)
      72             : {
      73          48 :   switch(format){
      74          44 :       case 0:
      75          44 :         check_sequence = NULL;
      76          44 :         break;   
      77           2 :       case 1:
      78           2 :         LOG_INFO("L1ID sequentiality check enabled: TTC2H only");
      79           2 :         check_sequence = NULL;
      80           2 :         break;
      81           0 :       case 2:
      82           0 :         LOG_INFO("L1ID sequentiality check enabled: TTC2H, LATOME data");
      83           0 :         check_sequence = &check_sequence_latome;
      84           0 :         break;
      85           0 :       case 3:
      86           0 :         LOG_INFO("L1ID sequentiality check enabled: TTC2H, FMEMU data");
      87           0 :         check_sequence = &check_sequence_fmemu;
      88           0 :         break;
      89           2 :       case 4:
      90           2 :         LOG_INFO("L1ID sequentiality check enabled: TTC2H, FELIG data");
      91           2 :         check_sequence = &check_sequence_felig;
      92           2 :         break;
      93           0 :       case 5:
      94           0 :         LOG_INFO("L1ID sequentiality check enabled: TTC2H, NSW VMM data");
      95           0 :         check_sequence = &check_sequence_nsw_vmm;
      96           0 :         break;
      97           0 :       case 6:
      98           0 :         LOG_INFO("L1ID sequentiality check enabled: TTC2H, NSW TP data");
      99           0 :         check_sequence = &check_sequence_nsw_tp;
     100           0 :         break;
     101           0 :       default:
     102           0 :         LOG_INFO("Invalid choice for L1ID sequentiality check. Check disabled");
     103           0 :         check_sequence = NULL;
     104             :   }
     105          48 : }
     106             : 
     107             : 
     108           0 : static int check_sequence_latome(uint64_t fid, struct l1id_data* last, const uint8_t* data, size_t size){
     109           0 :   if(size < 48){
     110           0 :     LOG_INFO("LATOME message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.",fid, get_elink(fid), size);
     111           0 :     return 1;
     112             :   }
     113           0 :   xl1id_t current, expected;
     114           0 :   current.xl1id = ((uint32_t*)data)[5];
     115           0 :   if(current.fields.ecrc == (last->l1id.fields.ecrc+1)){
     116           0 :     LOG_DBG("ECR on fid 0x%lx (0x%x)", fid, get_elink(fid));
     117           0 :     expected.fields.ec = 0x0;
     118             :   } else{
     119           0 :     expected.fields.ec = (last->l1id.fields.ec+1) & 0x00ffffff;
     120             :   }
     121           0 :   last->mask = 0xffffffff;
     122           0 :   last->l1id.xl1id = current.xl1id;
     123           0 :   int ret = compare(fid, current, expected);
     124           0 :   return ret;
     125             : }
     126             : 
     127             : 
     128           0 : static int check_sequence_fmemu(uint64_t fid, struct l1id_data* last, const uint8_t* data, size_t size)
     129             : {
     130           0 :   if(size < 4){
     131           0 :     LOG_INFO("FMEMU message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", fid, get_elink(fid), size);
     132           0 :     return 1;
     133             :   }
     134           0 :   xl1id_t current, expected;
     135           0 :   current.xl1id = ((uint32_t*)data)[0];
     136           0 :   if(current.fields.ecrc == (last->l1id.fields.ecrc+1)){
     137           0 :     LOG_DBG("ECR on fid 0x%lx (0x%x)", fid, get_elink(fid));
     138           0 :     expected.fields.ec = 0x0;
     139             :   } else{
     140           0 :     expected.fields.ec = (last->l1id.fields.ec+1) & 0x00ffffff;
     141             :   }
     142           0 :   last->mask = 0xffffffff;
     143           0 :   last->l1id.xl1id = current.xl1id;
     144           0 :   int ret = compare(fid, current, expected);
     145           0 :   return ret;
     146             : }
     147             : 
     148             : 
     149           0 : static int check_sequence_felig(uint64_t fid, struct l1id_data* last, const uint8_t* data, size_t size){
     150           0 :   if(size < 8){
     151           0 :     LOG_INFO("FELIX message from fid 0x%lx (0x%x) smaller than FELIG header, size %lu.", fid, get_elink(fid), size);
     152           0 :     return 1;
     153             :   }
     154           0 :   xl1id_t current, expected;
     155           0 :   current.fields.ec = (data[4] | (data[3]<<8));
     156           0 :   expected.fields.ec = (last->l1id.fields.ec+1) & 0x0000ffff;
     157           0 :   last->mask = 0x0000ffff;
     158           0 :   last->l1id.xl1id = current.xl1id;
     159           0 :   int ret = compare(fid, current, expected);
     160           0 :   return ret;
     161             : }
     162             : 
     163             : 
     164           0 : static int check_sequence_nsw_vmm(uint64_t fid, struct l1id_data* last, const uint8_t* data, size_t size)
     165             : {
     166           0 :   if(size < 2){
     167           0 :     LOG_INFO("NSW VMM message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", fid, get_elink(fid), size);
     168           0 :     return 1;
     169             :   }
     170           0 :   if (size > 4*(512+4)) {
     171           0 :     LOG_INFO("NSW VMM message from fid 0x%lx (0x%x) too long, size %lu.", fid, get_elink(fid), size);
     172             :   }
     173           0 :   xl1id_t current, expected;
     174             :   //enum packetType { FULL_MM=0, NULL_EVENT=1, FULL_STGC=2 , ILLEGAL=3};
     175           0 :   unsigned char headerType = data[0] >> 6;
     176           0 :   switch (headerType){
     177           0 :     case 0:   // MM   full header
     178             :     case 2: // sTGC full header
     179           0 :       current.fields.ec = (data[3] | (data[2]<<8)) & 0xff;
     180           0 :       expected.fields.ec = (last->l1id.fields.ec+1) & 0xff;
     181           0 :       last->mask = 0xffff;
     182           0 :       last->l1id.fields.ec = (data[3] | (data[2]<<8)) & last->mask;
     183           0 :       break;
     184           0 :     case 1: // null header
     185           0 :       current.fields.ec = data[1];
     186           0 :       expected.fields.ec = (last->l1id.fields.ec+1) & 0xff;
     187           0 :       last->mask = 0xff;
     188           0 :       last->l1id.fields.ec = data[1];
     189           0 :       break;
     190           0 :     case 3: // illegal header type
     191             :       {
     192           0 :         unsigned int vmmHeader = (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[3];
     193           0 :         LOG_INFO("Illegal VMM message from fid 0x%lx (0x%x), headerType = 3, headerword = 0x%x, size %d.", fid, get_elink(fid), vmmHeader, size+8);
     194           0 :         break;
     195             :       }
     196             :     default:
     197             :       LOG_INFO("Invalid header from fid 0x%lx (0x%x), type 0x%x", fid, get_elink(fid), headerType);
     198             :   }
     199           0 :   int ret = compare(fid, current, expected);
     200           0 :   return ret;
     201             : }
     202             : 
     203             : 
     204           0 : static int check_sequence_nsw_tp(uint64_t fid, struct l1id_data* last, const uint8_t* data, size_t size)
     205             : {
     206           0 :   if(size < 8){
     207           0 :     LOG_INFO("NSW TP message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", fid, get_elink(fid), size);
     208           0 :     return 1;
     209             :   }
     210           0 :   xl1id_t current, expected;
     211           0 :   current.fields.ec =  ( data[5]<<16 | data[6]<<8 | data[7] ) & 0x00ffffff;
     212           0 :   current.fields.ecrc = (data[4]<<24) & 0xff;
     213           0 :   if(current.fields.ecrc == (last->l1id.fields.ecrc+1) ){
     214             :     LOG_DBG("ECR on fid 0x%lx (0x%x)", fid, get_elink(fid));
     215             :     expected.fields.ec = 0x0;
     216             :   } else{
     217           0 :     expected.fields.ec = (last->l1id.fields.ec+1) & 0x00ffffff;
     218             :   }
     219           0 :   last->mask = 0xffffffff;
     220           0 :   last->l1id.xl1id = current.xl1id;
     221           0 :   int ret = compare(fid, current, expected);
     222           0 :   return ret;
     223             : }

Generated by: LCOV version 1.0