⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_data_rcv.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
字号:
/*************************************************************************** *    test_data_rcv.c  -  Takes the two streams and gives BER *                           ------------------- *   begin                :  2003 *   authors              :  ineiti *   emails               :  linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** *                                Changes *                                ------- * date - name - description * 03/02/06 - ineiti - begin * 03/04/28 - ineiti - added mode-flag to clear on every count * 04/03/20 - ineiti - swapped BER and ERROR in stats, for nicer display * 04/05/14 - ineiti - added print-parameter to config * **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//* *  This module gives the total number of received u8s, as well as the number * of wrongly received ones. *  For chains without a STFA, one can set config->size, which will * influence the size of the input-port. */#include "spc.h"#define DBG_LVL 0typedef struct {  // If the chain doesn't have a size-giving module, this config-param  // can be used  int size; // 0  // Set to one to clear the counter  int clear; // 0  // 0 - add up total and error  // 1 - write a new total and error on each call  int mode; // 0  // 0 - wait for both inputs  // 1 - react already if input 0 is active  // 2 - react already if input 1 is active  int wait; // 0  // 0 - Don't print  // 1 - Print counters  int print;}config_t;typedef struct {  // The calculated bit error rate, that is, error / total  double ber;  // Number of bits that are different between in0 and in1  int error;  // Number of received bits  int total;}stats_t;typedef struct {  int size;  int mode;  int wait;  int iter;  int print;}private_t;/* * The initialisation function, or constructor,  * is called the first time this module is instantiated. */int rcv_init( swr_sdb_t *context ) {  // Begin system-definitions {  config_t *config;  stats_t *stats;  MOD_INC_USE_COUNT;  if ( sizeof( private_t ) > 0 )    context->private_data = swr_malloc( sizeof( private_t ) );  swr_sdb_get_config_struct( context->id, (void**)&config );  swr_sdb_get_stats_struct( context->id, (void**)&stats );  // } End of system-definitions  // Tell the subsystem that we'll change both output AND input  context->status |= SUBS_STATUS_RESIZE_BOTH;  config->size = 0;  config->clear = 0;  config->mode = 0;  config->wait = 0;  config->print = 0;  stats->total = stats->error = 0;  private->iter = 0;  // Begin system-definitions  swr_sdb_free_stats_struct( context->id, (void**)&stats );  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;  // End system-definitions}/* * To configure the outputs * this is called when the input-sizes change * Input 0 is the one that underwent testing, while input 1 * should come directly from the test_data_send. */int rcv_configure_outputs( swr_sdb_t *context ) {  if ( size_in(0) != size_in(1) ) {    if ( !size_in(0) ) {      PR_DBG( 1, "Input 1 is defined, waiting for 0\n" );      return 0;    } else if ( !size_in(1) ) {      PR_DBG( 1, "Copying size from input 0 to input 1\n" );      size_in(1) = size_in(0);    } else if ( size_in(0) && size_in(1) ) {      if ( size_in(0) == private->size ) {        PR_DBG( 1, "Input 1 changed, waiting for confirmation\n" );        return 0;      } else if ( size_in(1) == private->size ) {        PR_DBG( 1, "Setting new size from input 0 to input 1\n" );        size_in(1) = size_in(0);      } else {        PR_DBG( 1, "Input-sizes dont match old: (%i,%i) != %i\n",                size_in(0), size_in(1), private->size );      }    }  }  private->size = size_in(0);  PR_DBG( 1, "Setting input-size to %i\n", private->size );  return 0;}/* * Every time modules from the outside change the value of a configuration parameter, * this function is called. */int rcv_reconfig( swr_sdb_t *context ) {  // Definition of variables - don't touch  config_t *config;  stats_t *stats;  swr_sdb_get_config_struct( context->id, (void**)&config );  private->mode = config->mode;  private->wait = config->wait;  private->print = config->print;  if ( config->size > 0 ) {    PR_DBG( 4, "Making input size %i\n", config->size );    size_in(0) = config->size;    size_in(1) = config->size;    private->size = config->size;  }  swr_sdb_get_stats_struct( context->id, (void**)&stats );  if (config->clear) {    stats->total =0;    stats->error=0;    config->clear=0;  }  swr_sdb_free_stats_struct( context->id, (void**)&stats );  // Definition - don't touch  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;}/* * This is the function that implements the `main method' of the class * Every class has got just ONE method/working-mode. */int rcv_pdata( swr_sdb_t *context ) {  // Definition of variables - don't touch  stats_t *stats;  int i, j, err, size, da0, da1;  U8 *in0, *in1;  // Check for the correct input active  da0 = data_available( 0 );  da1 = data_available( 1 );    PR_DBG(4,"iter = %i\n",++private->iter);  // if wait == 0, then both inputs need to be active  if ( ( private->wait == 0 ) && ( !da0 || !da1 ) ) {    PR_DBG(4," Wait on both, iter = %i\n",private->iter);    return -1;  }  // if wait == 1, then data_available( 0 ) has to be true  if ( ( private->wait == 1 ) && !da0 ) {    PR_DBG(4,"Wait on 1, iter = %i\n",private->iter);    return -1;  }  // if wait == 2, then data_available( 1 ) has to be true  if ( ( private->wait == 2 ) && !da1 ) {    PR_DBG(4,"Wait on 2, iter = %i\n",private->iter);    return -1;  }  PR_DBG( 4, "processing data\n" );  size = size_in(0);  in0 = buffer_in(0);  in1 = buffer_in(1);  PR_DBG( 3, " " );  for ( i=0, err=0; i<size; i++, in0++, in1++ ) {    PR_DBG_CL( 3, "%2x:%2x ", *in1, *in0 );    for ( j=0; j<8; j++ ) {      err += ( *in0 & ( 1 << j ) ) != ( *in1 & ( 1 << j ) );    }  }  PR_DBG_CL( 3, "\n" );  PR_DBG( 1,"Error = %i\n",err);  PR_DBG( 1,"%i\n",err);    swr_sdb_get_stats_struct( context->id, (void**)&stats );  switch( private->mode ) {  case 0:    stats->total += size * 8;    stats->error += err;    break;  case 1:    stats->total = size * 8;    stats->error = err;    break;  }  if ( private->print || DBG_LVL >= 1 ){    if ( !stats->error ) {      PR_DBG( 0, "Transmission OK\n"  );    } else {      PR_DBG( 0, "Errors: %i/%i\n", stats->error, stats->total );    }  }  if ( stats->total > 0 ) {    stats->ber = (double)stats->error / (double)stats->total;  } else {    stats->ber = 1;  }  swr_sdb_free_stats_struct( context->id, (void**)&stats );  return(0);}/* * This is the `destructor'. */int rcv_finalize( swr_sdb_t *context ) {  if ( sizeof( private_t ) > 0 )    swr_free( private );  MOD_DEC_USE_COUNT;  return 0;}/* * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */swr_spc_id_t rcv_id;int rcv_module_init(void) {  swr_spc_desc_t *desc;  /**   * Get a description-part from SPM   * Give the following parameters:   * Input-ports, output-ports, config-params, stat-params   */  desc = swr_spc_get_new_desc( 2, 0, 5, 3 );  if ( !desc ) {    PR_DBG( 0, "Can't initialise the module. This is BAD!\n" );    return -1;  }  /**   * Define the different parts of config and stats. You have to define   * them in the same order as they appear in the structures. The names   * can be freely chosen.   *   * UM_CONFIG_{INT,DOUBLE,STRING128,POINTER}( "name" );   * UM_STATS_{INT,DOUBLE,STRING128,POINTER,BLOCK}( "name" );   */  UM_CONFIG_INT( "size", PARAMETER_DEBUG );  UM_CONFIG_INT( "clear", PARAMETER_DEBUG );  UM_CONFIG_INT( "mode" );  UM_CONFIG_INT( "wait", PARAMETER_DEBUG );  UM_CONFIG_INT( "print", PARAMETER_DEBUG );  UM_STATS_DOUBLE( "ber" );  UM_STATS_INT( "error" );  UM_STATS_INT( "total" );  /**   * The in- and outputs have also to be defined in the right order. First   * port first. The additional flag is not used yet, but it will...   *   * UM_INPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 );   * UM_OUTPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 );   */  UM_INPUT( SIG_U8, 0 );  UM_INPUT( SIG_U8, 0 );  // Initialise the callback-functions. Delete the ones you don't use  desc->fn_init              = rcv_init;  desc->fn_reconfigure       = rcv_reconfig;  desc->fn_process_data      = rcv_pdata;  desc->fn_configure_outputs = rcv_configure_outputs;  desc->fn_finalize          = rcv_finalize;  // And register the module in the SPM. Change the name!  rcv_id = swr_cdb_register_spc( &desc, "test_data_rcv" );  if ( rcv_id == SWR_SPM_INVALID_ID ) {    swr_spc_free_desc( desc );    PR_DBG( 0, "Couldn't register the module!\n" );    return 1;  }  PR_DBG( 4, "Ready\n" );  return 0;}/* * This is called upon rmmod */void rcv_module_exit( void ) {  PR_DBG( 4, "Freeing id: %i\n", rcv_id );  if ( swr_cdb_unregister_spc( rcv_id ) < 0 ) {    PR_DBG( 0, "Still in use somewhere\n" );  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -