view src/g23m-gprs/grlc/grlc_meass.c @ 72:7bf39f5e834d

backlight control on Luna: switch PWL instead of LEDB This change is preliminary toward upcoming rework of backlight control logic in our UI firmware. LEDB does not exist on Tango-based platforms (it is not brought out on Tango modules), thus turning it on and off produces absolutely no effect beyond making L1 disable deep sleep when LEDB is turned on. However, both iWOW DSK and our upcoming FC Caramel2 boards have a PWL LED, so let's switch that LED on and off to indicate the state of the UI firmware's backlight control. Note that we are NOT switching the actual Luna LCD backlight here, even though it is trivially controlled with a GPIO. The reason for this seemingly strange choice is that we don't want to turn this development board LCD backlight off until we bring the higher-level backlight control logic up to par, including new logic to "swallow" the first keypress that turns on the darkened LCD.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 24 Oct 2020 07:39:54 +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) */