view src/g23m-gprs/grlc/grlc_meass.c @ 303:f76436d19a7a default tip

!GPRS config: fix long-standing AT+COPS chance hanging bug There has been a long-standing bug in FreeCalypso going back years: sometimes in the AT command bring-up sequence of an ACI-only MS, the AT+COPS command would produce only a power scan followed by cessation of protocol stack activity (only L1 ADC traces), instead of the expected network search sequence. This behaviour was seen in different FC firmware versions going back to Citrine, and seemed to follow some law of chance, not reliably repeatable. This bug has been tracked down and found to be specific to !GPRS configuration, stemming from our TCS2/TCS3 hybrid and reconstruction of !GPRS support that was bitrotten in TCS3.2/LoCosto version. ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3 version and had to be pulled from TCS2 - but as it turns out, there is a new field in the MMR_REG_REQ primitive that needs to be set correctly, and that psa_mms.c module is the place where this initialization needed to be added.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Jun 2023 08:23:37 +0000
parents fa8dc04885d8
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  GPRS (8441)
|  Modul   :  GRLC
+----------------------------------------------------------------------------- 
|  Copyright 2002 Texas Instruments Berlin, AG 
|                 All rights reserved. 
| 
|                 This file is confidential and a trade secret of Texas 
|                 Instruments Berlin, AG 
|                 The receipt of or possession of this file does not convey 
|                 any rights to reproduce or disclose its contents or to 
|                 manufacture, use, or sell anything it may describe, in 
|                 whole, or in part, without the specific written consent of 
|                 Texas Instruments Berlin, AG. 
+----------------------------------------------------------------------------- 
|  Purpose :  This module implements signal handler functions for service
|             MEAS of entity GRLC.
+----------------------------------------------------------------------------- 
*/ 

#ifndef GRLC_MEASS_C
#define GRLC_MEASS_C
#endif /* #ifndef GRLC_MEASS_C */

#define ENTITY_GRLC

/*==== INCLUDES =============================================================*/

#include "typedefs.h"
#include "vsi.h"
#include "macdef.h"
#include "gprs.h"
#include "gsm.h"
#include "ccdapi.h"
#include "prim.h"
#include "message.h"
#include "grlc.h"
#include "grlc_meass.h"   
#include "grlc_measf.h"
#include "cl_rlcmac.h"

/*==== CONST ================================================================*/

#define MEAS_MAX_NUM_MEAN     1000   /* maximum numbers of element considered for    */
                                     /* calculating the mean                         */
/* maybe for later use */
/* 
#define M_ROUND_UP(x,meas_acrcy) (((x)>=0)?                                        \
                                  ((((x)%(meas_acrcy))< ((meas_acrcy)/ 2))?        \
                                   ( (x)/(meas_acrcy)   ):(((x)/(meas_acrcy))+1)): \
                                  ((((x)%(meas_acrcy))<=((meas_acrcy)/-2))?        \
                                   (((x)/(meas_acrcy))-1):( (x)/(meas_acrcy)   )))
*/

#define M_ROUND_UP(x,meas_acrcy)  ((((x)%(meas_acrcy))< ((meas_acrcy)/ 2))?        \
                                   ( (x)/(meas_acrcy)   ):(((x)/(meas_acrcy))+1))

#define MEAS_C_INC_INDEX(index) {                                        \
                                  if( index < (T_C_INDEX)(~0) ) index++; \
                                }

#define NORM_FFB_MAX   (ULONG)100000 /* normalised forgetting factor b maximum value */
#define NORM_FFC_MAX   (ULONG)500000 /* normalised forgetting factor c maximum value */
#define NORM_FFB_DIV   (ULONG)10     /* normalised forgetting factor b divisor value */
#define NORM_FFC_DIV   (ULONG)20     /* normalised forgetting factor c divisor value */

#define SV_ACRCY_DIV   (ULONG)10     /* signal variance accuracy divisor             */

#define C_VALUE_IDX_DEFAULT  0
#define C_VALUE_DEFAULT      0
#define SV_VALUE_DEFAULT     0
#define RXQUAL_VALUE_DEFAULT 0

#define SV_LEVEL_MAX            63
#define SV_LEVEL_STEP           ((T_SIGN_VAR_VALUE)(MEAS_ACRCY/4))
                                            /* dB2 step size of the signal   */
                                            /* variance                      */

/*==== LOCAL VARS ===========================================================*/

/*
 * normalised forgetting factor b used in context of C value calculation
 *
 * NORM_FFB_MAX * ( 1 / ( 6 * t_avg_t ) )
 */
LOCAL const ULONG norm_ffb[] = { NORM_FFB_MAX,
                                 70711, 50000, 35355, 25000, 17678, 12500,
                                  8839,  6250,  4419,  3125,  2210,  1563,
                                  1105,   781,   552,   391,   276,   195,
                                   138,    98,    69,    49,    35,    24,
                                    17 };

/*
 * normalised forgetting factor c used in context of C value calculation
 *
 * NORM_FFC_MAX * ( 1 / ( 12 * t_avg_t ) )
 */
LOCAL const ULONG norm_ffc[] = { NORM_FFC_MAX,
                                 353553, 250000, 176777, 125000,  88388,  62500,
                                  44194,  31250,  22097,  15625,  11049,   7813,
                                   5524,   3906,   2762,   1953,   1381,    977,
                                    691,    488,    345,    244,    173,    122,
                                     86 };

/*==== LOCAL TYPES===========================================================*/

#if !defined (NTRACE)

LOCAL void meas_int_trace_i_level( T_ilev *i_level );
  
#endif /* #if !defined (NTRACE) */

/*==== PUBLIC FUNCTIONS =====================================================*/
/*
+------------------------------------------------------------------------------
| Function    : meas_grlc_init
+------------------------------------------------------------------------------
| Description : 
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_grlc_init ( void )
{ 
  TRACE_FUNCTION( "meas_grlc_init" );

  /* initialization of C value management */
  meas_c_restart( );

  /* initialization of signal variance management */
  meas_sv_restart( );

  /* initialization of signal quality management */
  meas_sq_restart( );

} /* grlc_meas_init() */

/*
+------------------------------------------------------------------------------
| Function    : sig_rd_meas_qual_rpt_sent
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_RD_MEAS_QUAL_RPT_SENT
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_rd_meas_qual_rpt_sent ( void )
{ 
  TRACE_ISIG( "sig_rd_meas_qual_rpt_sent" );

  meas_sv_restart( );
  
  grlc_data->meas.sq_restart = TRUE;
  
} /* sig_rd_meas_qual_rpt_sent() */

/*
+------------------------------------------------------------------------------
| Function    : sig_tm_meas_ptm
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_TM_MEAS_PTM
|               
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_tm_meas_ptm ( void )
{ 
  TRACE_ISIG( "sig_tm_meas_ptm" );

  meas_sv_restart( );
  meas_sq_restart( );

} /* sig_tm_meas_ptm() */

/*
+------------------------------------------------------------------------------
| Function    : meas_grlc_c_get_value
+------------------------------------------------------------------------------
| Description : This function returns the current C value.
|
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL UBYTE meas_grlc_c_get_value ( void )
{
  UBYTE c_value;

  TRACE_FUNCTION( "meas_grlc_c_get_value" );

  if( grlc_data->meas.c_filter.index > 0 )
  {
    c_value = ( M_ROUND_UP( grlc_data->meas.c_filter.value, MEAS_ACRCY ) );
  }
  else
  {

#ifdef _SIMULATION_
    TRACE_ERROR( "meas_grlc_c_get_value: grlc_data->meas.c_filter.index EQ 0" );
#endif /* #ifdef _SIMULATION_ */

    c_value = C_VALUE_DEFAULT;
  }

  return( c_value );

} /* meas_grlc_c_get_value() */

/*
+------------------------------------------------------------------------------
| Function    : meas_grlc_c_get_c_value
+------------------------------------------------------------------------------
| Description : 
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_grlc_c_get_c_value ( T_CGRLC_c_value *c_value )
{
  TRACE_FUNCTION( "meas_grlc_c_get_c_value" );

  c_value->c_acrcy = MEAS_ACRCY;
  c_value->c_lev   = grlc_data->meas.c_filter.value;
  c_value->c_idx   = grlc_data->meas.c_filter.index;

} /* meas_grlc_c_get_c_value() */

/*
+------------------------------------------------------------------------------
| Function    : meas_grlc_c_set_c_value
+------------------------------------------------------------------------------
| Description : 
|
| Parameters  : 
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_grlc_c_set_c_value ( T_CGRLC_c_value *c_value )
{
  TRACE_FUNCTION( "meas_grlc_c_set_c_value" );

  grlc_data->meas.c_filter.value = (c_value->c_lev / c_value->c_acrcy) * 
									MEAS_ACRCY;

  grlc_data->meas.c_filter.index = c_value->c_idx;

} /* meas_grlc_c_set_c_value() */

/*
+------------------------------------------------------------------------------
| Function    : meas_c_val_update_ptm 
+------------------------------------------------------------------------------
| Description : ... 
|
| Parameters  : -
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_c_val_update_ptm ( T_MAC_PWR_CTRL_IND          *mac_pwr_ctrl_ind,
                                    T_CGRLC_glbl_pwr_ctrl_param *pwr_ctrl_param,
                                    T_CGRLC_freq_param          *freq_param )
{ 
  UBYTE       pb_rdc;       /* Pb reduction              */
  UBYTE       vld_smpl = 0; /* valid measurement samples */
 
  ULONG       ff_value;
  ULONG       c_value;
  
  T_C_FILTER *c_filter = &grlc_data->meas.c_filter;

  TRACE_FUNCTION( "meas_c_val_update_ptm" );

  if( pwr_ctrl_param->pc_meas_chan EQ  CGRLC_MEAS_CHAN_BCCH AND
      mac_pwr_ctrl_ind->bcch_level NEQ MAC_RXLEV_NONE           )
  {
    MEAS_C_INC_INDEX( c_filter->index );

    if( c_filter->index EQ 1 )
    {
      c_filter->value = MEAS_ACRCY * mac_pwr_ctrl_ind->bcch_level;
    }
    else
    {
      /* calculate the forgetting factor */
      ff_value = norm_ffb[pwr_ctrl_param->t_avg_t];

      /* update the filter */
      c_value = ( NORM_FFB_MAX - ff_value )       * 
                ( c_filter->value / NORM_FFB_DIV ) 
                +
                ff_value                          * 
                ( MEAS_ACRCY / NORM_FFB_DIV )     *
                mac_pwr_ctrl_ind->bcch_level;
    
      c_filter->value = (T_C_VALUE)(c_value / (NORM_FFB_MAX / NORM_FFB_DIV));
    }

#ifdef _SIMULATION_
    TRACE_EVENT_P2( "C-Value = %d, C-Index = %d", 
                    c_filter->value, c_filter->index );
#endif /* #ifdef _SIMULATION_ */
  }
  else if( pwr_ctrl_param->pc_meas_chan EQ CGRLC_MEAS_CHAN_PDCH )
  {
    vld_smpl = meas_c_calc_mean ( mac_pwr_ctrl_ind->burst_level,
                                  mac_pwr_ctrl_ind->radio_freq,
                                  &c_value, &pb_rdc, freq_param );

    if( vld_smpl )
    {
      MEAS_C_INC_INDEX( c_filter->index );

      /* consider the BTS output power reduction */
      c_value -= ( ( 2 * pwr_ctrl_param->pb ) *
                   ( MEAS_ACRCY * pb_rdc ) / MAC_BURST_PER_BLOCK );


      if( c_filter->index EQ 1 )
      {
        c_filter->value = (T_C_VALUE)c_value;
      }
      else
      {
        /* calculate the forgetting factor */
        ff_value = norm_ffc[pwr_ctrl_param->t_avg_t];

        /* update the filter */
        c_value = ( NORM_FFC_MAX - ff_value )      *
                  ( c_filter->value / NORM_FFC_DIV ) 
                  +
                  ff_value                         *
                  ( c_value / NORM_FFC_DIV );
    
        c_filter->value = (T_C_VALUE)(c_value / (NORM_FFC_MAX / NORM_FFC_DIV));
      }
    }
    else
    {
#ifdef _SIMULATION_
      TRACE_EVENT( "no valid RXLEV information in meas_c_val_update_ptm 1" );
#endif /* #ifdef _SIMULATION_ */
    }

#ifdef _SIMULATION_
      TRACE_EVENT_P2( "C-Value = %d, C-Index = %d", 
                      c_filter->value, c_filter->index );
#endif /* #ifdef _SIMULATION_ */
  }
  else
  {
#ifdef _SIMULATION_
    TRACE_EVENT( "no valid RXLEV information in meas_c_val_update_ptm 2" );
#endif /* #ifdef _SIMULATION_ */
  }
} /* meas_c_val_update_ptm() */

/*
+------------------------------------------------------------------------------
| Function    : meas_c_restart 
+------------------------------------------------------------------------------
| Description : This function initializes the parameters for deriving the
|               C value.
|
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_c_restart ( void )
{
  TRACE_FUNCTION( "meas_c_restart" );

  grlc_data->meas.c_filter.value = 0;
  grlc_data->meas.c_filter.index = 0;
} /* meas_c_restart() */

/*
+------------------------------------------------------------------------------
| Function    : meas_sv_get_value
+------------------------------------------------------------------------------
| Description : This function returns the current signal variance.
|
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL UBYTE meas_sv_get_value ( void )
{
  T_SIGN_VAR_VALUE sv_val; 

  TRACE_FUNCTION( "meas_sv_get_value" );

  sv_val = grlc_data->meas.sign_var.value / SV_LEVEL_STEP;

  if( grlc_data->meas.sign_var.value % SV_LEVEL_STEP EQ  0 AND 
      grlc_data->meas.sign_var.value                 NEQ 0     )
  {
    sv_val -= 1;
  }

  if( sv_val > SV_LEVEL_MAX )
  {
    sv_val = SV_LEVEL_MAX;
  }

  return( (UBYTE)sv_val );
} /* meas_sv_get_value() */

/*
+------------------------------------------------------------------------------
| Function    : meas_sv_update
+------------------------------------------------------------------------------
| Description : ... 
|
| Parameters  : -
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_sv_update ( T_MAC_PWR_CTRL_IND          *mac_pwr_ctrl_ind,
                             T_CGRLC_glbl_pwr_ctrl_param *pwr_ctrl_param,
                             T_CGRLC_freq_param          *freq_param )
{ 
  T_SIGN_VAR *sign_var = &grlc_data->meas.sign_var;

  UBYTE   i;               /* used for counting                         */
  UBYTE   ss_on_bcch[MAC_BURST_PER_BLOCK];
                           /* receive signal level measured on BCCH     */
  UBYTE   ss_off_bcch[MAC_BURST_PER_BLOCK];
                           /* receive signal level not measured on BCCH */
  UBYTE   j    = 0;        /* indicates the number of bursts received   */
                           /* on BCCH frequency                         */
  UBYTE  *ss_k = NULL;     /* points to the receive signal levels       */

  TRACE_FUNCTION( "meas_sv_update" );

  /* initialize arrays */
  for( i = 0; i < MAC_BURST_PER_BLOCK; i++ )
  {
    ss_on_bcch [i] = MAC_RXLEV_NONE;
    ss_off_bcch[i] = MAC_RXLEV_NONE;
  }

  if( mac_pwr_ctrl_ind->crc_error  EQ GRLC_CRC_PASS        AND
      pwr_ctrl_param->pc_meas_chan EQ CGRLC_MEAS_CHAN_PDCH     )
  {
    if( !freq_param->pdch_hopping )
    {
      /* sort burst level acc. its radio frequency */
      for( i = 0; i < MAC_BURST_PER_BLOCK; i++ )
      {
        if( mac_pwr_ctrl_ind->radio_freq[i] EQ freq_param->bcch_arfcn )
        {
          j++;

          ss_on_bcch[i] = mac_pwr_ctrl_ind->burst_level[i];
        }
        else
        {
          ss_off_bcch[i] = mac_pwr_ctrl_ind->burst_level[i];
        }
      }

      /* calculate the burst level that should be taken into account */
      switch( j )
      {
        case( 0 ): ss_k = &ss_off_bcch[0]; j = 4; break;
        case( 1 ): ss_k = &ss_off_bcch[0]; j = 3; break;
        case( 2 ): ss_k = NULL;                   break;
        case( 3 ): ss_k = &ss_on_bcch[0];  j = 3; break;
        case( 4 ): ss_k = &ss_on_bcch[0];  j = 4; break;
        default  : TRACE_ASSERT( j < 4 );         break;

      }
    }
    else
    {
      /* calculate the burst level that should be taken into account */
      ss_k = &mac_pwr_ctrl_ind->burst_level[0];
      j    = 4;
    }
  }

  if( ss_k NEQ NULL )
  {
    T_SIGN_VAR_INDEX  old_num;
    ULONG             old_elem; 
    UBYTE             pb_rdc;        /* Pb reduction                      */
    LONG              base;
    ULONG             sum      = 0;  /* sum of all squares                */
    ULONG             bl_var;        /* block variance                    */
    ULONG             ss_block;

    if( meas_c_calc_mean ( ss_k, mac_pwr_ctrl_ind->radio_freq,
                           &ss_block, &pb_rdc, freq_param ) > 0 )
    {
      /* calculate the sum of the squares of the difference between */
      /* each individual burst level value and the mean             */
      for( i = 0; i < j; i++ )
      {
        if( ss_k[i] NEQ MAC_RXLEV_NONE )
        {
          base = ( ( ss_k[i] * MEAS_ACRCY ) / SV_ACRCY_DIV ) -
                 ( ss_block / SV_ACRCY_DIV );
          sum += ( ULONG )( base * base );
        }
      }

      /*
       * calculate block variance
       *
       * in case ss_k NEQ NULL, j will be either set to the value 3 or 4 
       *
       * the lint comment below only works when linting current file alone, 
       * when linting current file together with all other files of the project,
       * an error message will be generated anyway
       *
       * I don't know why and gave-up to fix it 
       */
      bl_var = sum / ( UBYTE )( j - 1 ); /*lint !e414*/

      /* calculate the signal variance */
      if( sign_var->index EQ MEAS_MAX_NUM_MEAN )
      {
        old_num = MEAS_MAX_NUM_MEAN - 1;
      } 
      else
      {
        old_num = sign_var->index;
        sign_var->index++;
      }

      old_elem = sign_var->value * old_num;

      sign_var->value = 
        (T_SIGN_VAR_VALUE)((old_elem + (bl_var / SV_ACRCY_DIV)) / sign_var->index);
    }
    else
    {
#ifdef _SIMULATION_
      TRACE_EVENT( "no valid RXLEV information in meas_sv_update 1" );
#endif /* #ifdef _SIMULATION_ */
    }

#ifdef _SIMULATION_
    TRACE_EVENT_P2( "SIGN-VAR-Value = %d, SIGN-VAR-Index = %d", 
                    sign_var->value, sign_var->index );
#endif /* #ifdef _SIMULATION_ */
  }
  else
  {
#ifdef _SIMULATION_
    TRACE_EVENT( "no valid RXLEV information in meas_sv_update 2" );
#endif /* #ifdef _SIMULATION_ */
  }
} /* meas_sv_update() */

/*
+------------------------------------------------------------------------------
| Function    : meas_sv_restart 
+------------------------------------------------------------------------------
| Description : This function initializes the parameters for deriving the
|               signal variance.
|
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_sv_restart ( void )
{
  TRACE_FUNCTION( "meas_sv_restart" );

  grlc_data->meas.sign_var.value = 0;
  grlc_data->meas.sign_var.index = 0;
} /* meas_sv_restart() */

/*
+------------------------------------------------------------------------------
| Function    : meas_sq_get_rxqual_value
+------------------------------------------------------------------------------
| Description : This function returns the current RXQUAL value
|
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL UBYTE meas_sq_get_rxqual_value ( void)
{
  UBYTE      rxqual;
  T_BER_AVG *ber_avg = &grlc_data->meas.ber_avg; 

  TRACE_FUNCTION( "meas_sq_get_rxqual_value" );

  if      ( ber_avg->value < 200   )
  {
    rxqual = 0;         /* RX_QUAL_0 */
  }
  else if ( ber_avg->value < 400   )
  {
    rxqual = 1;         /* RX_QUAL_1 */
  }
  else if ( ber_avg->value < 800   )
  {
    rxqual = 2;         /* RX_QUAL_2 */
  }
  else if ( ber_avg->value < 1600  )
  {
    rxqual = 3;         /* RX_QUAL_3 */
  }
  else if ( ber_avg->value < 3200  )
  {
    rxqual = 4;         /* RX_QUAL_4 */
  }
  else if ( ber_avg->value < 6400  )
  {
    rxqual = 5;         /* RX_QUAL_5 */
  }
  else if ( ber_avg->value < 12800 )
  {
    rxqual = 6;         /* RX_QUAL_6 */
  }
  else 
  {
    rxqual = 7;         /* RX_QUAL_7 */
  }

  return ( rxqual );
} /* meas_sq_get_rxqual_value() */

/*
+------------------------------------------------------------------------------
| Function    : meas_sq_update
+------------------------------------------------------------------------------
| Description : This function updates the RXQUAL value.
|
| Parameters  : per_ind - Ptr to struct T_BER_IND
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_sq_update ( T_BER_IND *ber_ind )
{
  UBYTE        i;  
  ULONG        norm_fault;
  ULONG        norm_ber;
  ULONG        old_elem; 
  T_BER_INDEX  old_num;

  T_BER_AVG   *ber_avg = &grlc_data->meas.ber_avg;

  TRACE_FUNCTION( "meas_sq_update" );
  
  if(grlc_data->meas.sq_restart)
  {
    grlc_data->meas.ber_avg.value = 0;
    grlc_data->meas.ber_avg.index = 0;

    grlc_data->meas.sq_restart = FALSE;
  }

  for( i = 0; i < ber_ind->num_dl_blck; i++ )
  {
    if( ber_ind->be_info[i].total NEQ 0 )
    {
      if( ber_avg->index EQ MEAS_MAX_NUM_MEAN )
      {
        old_num = MEAS_MAX_NUM_MEAN - 1;
      } 
      else
      {
        old_num = ber_avg->index;
        ber_avg->index++;
      }

      old_elem       = ber_avg->value * old_num;
      norm_fault     = ber_ind->be_info[i].fault * MEAS_ACRCY * 100;
      norm_ber       = norm_fault / ber_ind->be_info[i].total;
      ber_avg->value = (T_BER_VALUE)((old_elem + norm_ber) / ber_avg->index);

      RX_SetRxQual( meas_sq_get_rxqual_value( ) );
    }
  }

#ifdef _SIMULATION_
  TRACE_EVENT_P2( "BER-Value = %d, BER-Index = %d", 
                  ber_avg->value, ber_avg->index );
#endif /* #ifdef _SIMULATION_ */
} /* meas_sq_update() */

/*
+------------------------------------------------------------------------------
| Function    : meas_sq_restart 
+------------------------------------------------------------------------------
| Description : This function initializes the parameters for deriving the
|               RXQUAL value.
|
| Parameters  : void
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_sq_restart ( void )
{
  TRACE_FUNCTION( "meas_sq_restart" );

  grlc_data->meas.ber_avg.value = 0;
  grlc_data->meas.ber_avg.index = 0;
} /* meas_sq_restart() */

/*
+------------------------------------------------------------------------------
| Function    : meas_int_get_rel_i_level
+------------------------------------------------------------------------------
| Description : This function returns the interference level values mapped to
|               values relative to the C value.
|
| Parameters  : *i_level - Ptr to relative interference level values
|
+------------------------------------------------------------------------------
*/
GLOBAL void meas_int_get_rel_i_level ( T_ilev *i_level )
{
  USHORT c_raw_data_lev = grlc_data->meas.c_filter.value;

  TRACE_FUNCTION( "meas_int_get_rel_i_level" );

  meas_int_fill_rel_iLevel( &i_level->v_ilev0, &i_level->ilev0, 0, c_raw_data_lev );
  meas_int_fill_rel_iLevel( &i_level->v_ilev1, &i_level->ilev1, 1, c_raw_data_lev );
  meas_int_fill_rel_iLevel( &i_level->v_ilev2, &i_level->ilev2, 2, c_raw_data_lev );
  meas_int_fill_rel_iLevel( &i_level->v_ilev3, &i_level->ilev3, 3, c_raw_data_lev );
  meas_int_fill_rel_iLevel( &i_level->v_ilev4, &i_level->ilev4, 4, c_raw_data_lev );
  meas_int_fill_rel_iLevel( &i_level->v_ilev5, &i_level->ilev5, 5, c_raw_data_lev );
  meas_int_fill_rel_iLevel( &i_level->v_ilev6, &i_level->ilev6, 6, c_raw_data_lev );
  meas_int_fill_rel_iLevel( &i_level->v_ilev7, &i_level->ilev7, 7, c_raw_data_lev );

#if !defined (NTRACE)

  meas_int_trace_i_level( i_level );
  
#endif /* #if !defined (NTRACE) */

} /* meas_int_get_rel_i_level() */

#if !defined (NTRACE)

/*
+------------------------------------------------------------------------------
| Function    : meas_int_trace_i_level
+------------------------------------------------------------------------------
| Description :
|
| Parameters  :
|
+------------------------------------------------------------------------------
*/
LOCAL void meas_int_trace_i_level( T_ilev *i_level )
{ 
  if( grlc_data->meas.v_im_trace NEQ 0 )
  {
    TRACE_EVENT_P8( "meas_int_trace_i_level: %02X %02X %02X %02X %02X %02X %02X %02X",
                    i_level->ilev0, i_level->ilev1, i_level->ilev2,
                    i_level->ilev3, i_level->ilev4, i_level->ilev5,
                    i_level->ilev6, i_level->ilev7 );
  }
} /* meas_int_trace_i_level() */
  
#endif /* #if !defined (NTRACE) */