📄 synch_complex_ics_rcv.c
字号:
/*************************************************************************** * synch_complex_rcv.c - Software Radio to detect primary synch * ------------------- * begin : 02/10/22 * authors : Linus Gasser * emails : Linus.Gasser@epfl.ch ***************************************************************************//*************************************************************************** * Changes * ------- * date - name - description * 02/10/22 - ineiti - init * 03/11/24 - ineiti - added complex function * 04/02/04 - ineiti - changed setting of offset in stfa_ics * 04/03/08 - ineiti - adjusted description * 04/03/08 - ineiti - deleted synch_move * 04/03/08 - ineiti - adjusted description * 04/03/08 - ineiti - deleted synch_move * 04/03/11 - ineiti - added 'mean' variable to take the mean over this * many slots * 04/03/12 - ineiti - adjusted private->offset to reflect symbols and not * samples * 04/03/12 - ineiti - adjusted synch_complex_rcv to work on samples and not * symbols. So private->offset does reflect samples for * real, now. This greatly enhances overall performance * of the synchronisation-process... * **************************************************************************//*************************************************************************** * * * 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. * * * ***************************************************************************//** * The desynchronisation uses a convolution to find the most probable * synchronistaion-signal. Due to the special format of the synch-signal, * it is possible to implement this as two convolutions, which reduces a * lot the computational complexity of the task. * This is adjusted for input of a ICS-card. */#include "spc.h"#include "mmx.h"#include "antenna.h"#include "synch.h"#include <math.h>#include <complex.h>#define DBG_LVL 0#define PRE_POST_LENGTH 32typedef struct { // If this is set to a valid id, it will set the offset for the stfa int stfa_id; // -1 // If this is 1, the sycnh_rcv also sets the offset_samples_rcv of the stfa int fine_adj; // 0 // Skip synchronisation if more than this number of other high peaks. // Useful numbers start at 5, 10 is a good bet. int skip; // 10 // Mean over this many slots to take the synchronisation int mean; // 1}config_t;typedef struct { // The position of the strongest synchronisation signal int synch_pos; // The amplitude of the strongest signal int synch_amp; // The fine position, 0-3 int fine_pos; // The fine amplitude int fine_amp; // The internal buffer - not really interesting block_t buffer; // The synchronisation signal - OK to look at it block_t synch; // The actual mean - debug int mean;}stats_t;typedef struct { complex double *buffer; int *synch; int slot_length_samples; int slots_per_frame; int stfa_id; int offset_samples; int fine_pos; int fine_adj; int mean; int config_mean; int skip;}private_t;/* * The initialisation function, or constructor, * is called the first time this module is instantiated. */int rcv_complex_ics_init( swr_sdb_t *context ) { // Definition of variables - don't touch if you're not an expert 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 ); private->slot_length_samples = 0; private->buffer = NULL; private->synch = NULL; private->fine_pos = 0; private->stfa_id = config->stfa_id = -1; stats->buffer.data = 0; stats->buffer.size = 0; stats->buffer.type = SIG_DOUBLE_COMPLEX; stats->synch.data = 0; stats->synch.size = 0; stats->synch.type = SIG_S32; stats->synch_pos = 0; stats->synch_amp = 0; stats->fine_pos = 0; stats->fine_amp = 0; config->fine_adj = 0; config->skip = 10; config->mean = 1; port_out(0).flags |= SWR_PORT_PASSED_THROUGH; // Definition - don't touch swr_sdb_free_config_struct( context->id, (void**)&config ); swr_sdb_free_stats_struct( context->id, (void**)&stats ); return 0;}/* * Every time modules from the outside change the value of a configuration parameter, * this function is called. */int rcv_complex_ics_reconfig( swr_sdb_t *context ) { // Definition of variables - don't touch config_t *config; swr_sdb_get_config_struct( context->id, (void**)&config ); if ( config->stfa_id != private->stfa_id ) { private->stfa_id = config->stfa_id; if ( private->stfa_id >= 0 ) { private->offset_samples = swr_sdb_get_config_int( private->stfa_id, "offset_chips_rcv" ) * 2; PR_DBG( 4, "Got offset-chips: %i\n", private->offset_samples ); } private->slots_per_frame = swr_sdb_get_config_int( private->stfa_id, "slots_per_frame" ); } private->fine_adj = config->fine_adj; if ( config->skip >= 0 ){ private->skip = config->skip; } if ( config->mean > 0 ){ private->config_mean = private->mean = config->mean; } PR_DBG( 4, "(%i) reconfig: %p\n", context->id, port_in(0).data ); // Definition - don't touch swr_sdb_free_config_struct( context->id, (void**)&config ); return(0);}/* * Reconfigure outputs, abused to set up internal structures */int rcv_complex_ics_configure_outputs( swr_sdb_t *context ) { stats_t *stats; config_t *config; int len; swr_sdb_get_stats_struct( context->id, (void**)&stats ); swr_sdb_get_config_struct( context->id, (void**)&config ); if ( private->slot_length_samples != size_in(0) ) { if ( private->slot_length_samples ) { swr_free( private->buffer ); swr_free( private->synch ); } private->slot_length_samples = size_in(0); len = ( private->slot_length_samples + 240 * 2 ) * sizeof( complex double ); private->buffer = swr_malloc( len ); memset( private->buffer, 0, len ); stats->buffer.data = private->buffer; stats->buffer.size = len / sizeof( complex double ); len = private->slot_length_samples * sizeof( S32 ); private->synch = swr_malloc( len ); memset( private->synch, 0, len ); stats->synch.data = private->synch; stats->synch.size = len / sizeof( S32 ); port_out(0).data = port_in(0).data + SYNCH_PRIM_LENGTH_SAMPLES_QI * sizeof( SYMBOL_COMPLEX_S32 ); } // Output 0 size_out(0) = size_in(0) - SYNCH_PRIM_LENGTH_SAMPLES_QI; PR_DBG( 4, "(%i) config-out: %p\n", context->id, port_in(0).data ); swr_sdb_free_config_struct( context->id, (void**)&config ); swr_sdb_free_stats_struct( context->id, (void**)&stats ); return 0;}/* * This is function that impements the `main method' of the class * Every calss has got just ONE method/working-mode. */int rcv_complex_ics_pdata( swr_sdb_t *context ) { // Definition of variables - don't touch stats_t *stats; config_t *config; int i, slot_length_samples, synch_pos, fine_pos = -1, fine_amp = 0, j, synch_amp, total_energy, other_peaks, length_frame; unsigned int p, shift; complex double *buffer, *buffer_ics;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -