2014-05-21 07:42:26 +00:00
/*!
2014-06-01 11:22:26 +00:00
* \ file galileo_e5_signal_processing . cc
2014-05-21 07:42:26 +00:00
* \ brief This library implements various functions for Galileo E5 signals such
* as replica code generation
* \ author Marc Sales , 2014. marcsales92 ( at ) gmail . com
2014-05-20 19:53:12 +00:00
*
2014-05-21 07:42:26 +00:00
* Detailed description of the file here if needed .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2018-05-13 20:49:11 +00:00
* Copyright ( C ) 2010 - 2018 ( see AUTHORS file for a list of contributors )
2014-05-21 07:42:26 +00:00
*
* GNSS - SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS - SDR .
*
* GNSS - SDR 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 3 of the License , or
2015-01-08 18:49:59 +00:00
* ( at your option ) any later version .
2014-05-21 07:42:26 +00:00
*
* GNSS - SDR is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2018-05-13 20:49:11 +00:00
* along with GNSS - SDR . If not , see < https : //www.gnu.org/licenses/>.
2014-05-21 07:42:26 +00:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2014-05-20 19:53:12 +00:00
*/
# include "galileo_e5_signal_processing.h"
2016-01-10 21:21:31 +00:00
# include "Galileo_E5a.h"
# include "gnss_signal_processing.h"
2018-02-26 02:15:53 +00:00
# include <gnuradio/gr_complex.h>
2016-01-10 21:21:31 +00:00
2019-06-28 23:28:30 +00:00
void galileo_e5_a_code_gen_complex_primary ( gsl : : span < std : : complex < float > > _dest , int32_t _prn , std : : array < char , 3 > _Signal )
2014-05-20 19:53:12 +00:00
{
2018-08-13 08:18:05 +00:00
uint32_t prn = _prn - 1 ;
uint32_t index = 0 ;
int32_t a [ 4 ] ;
2014-06-17 17:13:24 +00:00
if ( ( _prn < 1 ) | | ( _prn > 50 ) )
2016-05-02 21:46:30 +00:00
{
return ;
}
2015-03-16 23:22:20 +00:00
if ( _Signal [ 0 ] = = ' 5 ' & & _Signal [ 1 ] = = ' Q ' )
2016-05-02 21:46:30 +00:00
{
2019-02-22 09:47:24 +00:00
for ( size_t i = 0 ; i < GALILEO_E5A_Q_PRIMARY_CODE [ prn ] . length ( ) - 1 ; i + + )
2016-05-02 21:46:30 +00:00
{
2019-02-22 09:47:24 +00:00
hex_to_binary_converter ( a , GALILEO_E5A_Q_PRIMARY_CODE [ prn ] . at ( i ) ) ;
2016-05-02 21:46:30 +00:00
_dest [ index ] = std : : complex < float > ( 0.0 , float ( a [ 0 ] ) ) ;
_dest [ index + 1 ] = std : : complex < float > ( 0.0 , float ( a [ 1 ] ) ) ;
_dest [ index + 2 ] = std : : complex < float > ( 0.0 , float ( a [ 2 ] ) ) ;
_dest [ index + 3 ] = std : : complex < float > ( 0.0 , float ( a [ 3 ] ) ) ;
index = index + 4 ;
}
// last 2 bits are filled up zeros
2019-02-22 09:47:24 +00:00
hex_to_binary_converter ( a , GALILEO_E5A_Q_PRIMARY_CODE [ prn ] . at ( GALILEO_E5A_Q_PRIMARY_CODE [ prn ] . length ( ) - 1 ) ) ;
2016-05-02 21:46:30 +00:00
_dest [ index ] = std : : complex < float > ( float ( 0.0 ) , a [ 0 ] ) ;
_dest [ index + 1 ] = std : : complex < float > ( float ( 0.0 ) , a [ 1 ] ) ;
}
2015-03-16 23:22:20 +00:00
else if ( _Signal [ 0 ] = = ' 5 ' & & _Signal [ 1 ] = = ' I ' )
2016-05-02 21:46:30 +00:00
{
2019-02-22 09:47:24 +00:00
for ( size_t i = 0 ; i < GALILEO_E5A_I_PRIMARY_CODE [ prn ] . length ( ) - 1 ; i + + )
2016-05-02 21:46:30 +00:00
{
2019-02-22 09:47:24 +00:00
hex_to_binary_converter ( a , GALILEO_E5A_I_PRIMARY_CODE [ prn ] . at ( i ) ) ;
2016-05-02 21:46:30 +00:00
_dest [ index ] = std : : complex < float > ( float ( a [ 0 ] ) , 0.0 ) ;
_dest [ index + 1 ] = std : : complex < float > ( float ( a [ 1 ] ) , 0.0 ) ;
_dest [ index + 2 ] = std : : complex < float > ( float ( a [ 2 ] ) , 0.0 ) ;
_dest [ index + 3 ] = std : : complex < float > ( float ( a [ 3 ] ) , 0.0 ) ;
index = index + 4 ;
}
// last 2 bits are filled up zeros
2019-02-22 09:47:24 +00:00
hex_to_binary_converter ( a , GALILEO_E5A_I_PRIMARY_CODE [ prn ] . at ( GALILEO_E5A_I_PRIMARY_CODE [ prn ] . length ( ) - 1 ) ) ;
2016-05-02 21:46:30 +00:00
_dest [ index ] = std : : complex < float > ( float ( a [ 0 ] ) , 0.0 ) ;
_dest [ index + 1 ] = std : : complex < float > ( float ( a [ 1 ] ) , 0.0 ) ;
}
2015-03-16 23:22:20 +00:00
else if ( _Signal [ 0 ] = = ' 5 ' & & _Signal [ 1 ] = = ' X ' )
2016-05-02 21:46:30 +00:00
{
2018-08-13 08:18:05 +00:00
int32_t b [ 4 ] ;
2019-02-22 09:47:24 +00:00
for ( size_t i = 0 ; i < GALILEO_E5A_I_PRIMARY_CODE [ prn ] . length ( ) - 1 ; i + + )
2016-05-02 21:46:30 +00:00
{
2019-02-22 09:47:24 +00:00
hex_to_binary_converter ( a , GALILEO_E5A_I_PRIMARY_CODE [ prn ] . at ( i ) ) ;
hex_to_binary_converter ( b , GALILEO_E5A_Q_PRIMARY_CODE [ prn ] . at ( i ) ) ;
2018-03-03 01:03:39 +00:00
_dest [ index ] = std : : complex < float > ( float ( a [ 0 ] ) , float ( b [ 0 ] ) ) ;
_dest [ index + 1 ] = std : : complex < float > ( float ( a [ 1 ] ) , float ( b [ 1 ] ) ) ;
_dest [ index + 2 ] = std : : complex < float > ( float ( a [ 2 ] ) , float ( b [ 2 ] ) ) ;
_dest [ index + 3 ] = std : : complex < float > ( float ( a [ 3 ] ) , float ( b [ 3 ] ) ) ;
2016-05-02 21:46:30 +00:00
index = index + 4 ;
}
// last 2 bits are filled up zeros
2019-02-22 09:47:24 +00:00
hex_to_binary_converter ( a , GALILEO_E5A_I_PRIMARY_CODE [ prn ] . at ( GALILEO_E5A_I_PRIMARY_CODE [ prn ] . length ( ) - 1 ) ) ;
hex_to_binary_converter ( b , GALILEO_E5A_Q_PRIMARY_CODE [ prn ] . at ( GALILEO_E5A_Q_PRIMARY_CODE [ prn ] . length ( ) - 1 ) ) ;
2016-05-02 21:46:30 +00:00
_dest [ index ] = std : : complex < float > ( float ( a [ 0 ] ) , float ( b [ 0 ] ) ) ;
_dest [ index + 1 ] = std : : complex < float > ( float ( a [ 1 ] ) , float ( b [ 1 ] ) ) ;
}
2014-06-17 17:13:24 +00:00
}
2018-08-13 08:18:05 +00:00
2019-06-28 23:28:30 +00:00
void galileo_e5_a_code_gen_complex_sampled ( gsl : : span < std : : complex < float > > _dest , std : : array < char , 3 > _Signal ,
2018-08-13 08:18:05 +00:00
uint32_t _prn , int32_t _fs , uint32_t _chip_shift )
2014-05-20 19:53:12 +00:00
{
2018-08-13 08:18:05 +00:00
uint32_t _samplesPerCode ;
uint32_t delay ;
2019-02-22 09:47:24 +00:00
const uint32_t _codeLength = GALILEO_E5A_CODE_LENGTH_CHIPS ;
const int32_t _codeFreqBasis = GALILEO_E5A_CODE_CHIP_RATE_HZ ;
2014-06-17 17:13:24 +00:00
2018-12-03 15:25:11 +00:00
auto * _code = new std : : complex < float > [ _codeLength ] ( ) ;
2014-06-17 17:13:24 +00:00
2019-06-28 23:28:30 +00:00
galileo_e5_a_code_gen_complex_primary ( gsl : : span < std : : complex < float > > ( _code , _codeLength ) , _prn , _Signal ) ;
2014-06-17 17:13:24 +00:00
2018-08-13 08:18:05 +00:00
_samplesPerCode = static_cast < uint32_t > ( static_cast < double > ( _fs ) / ( static_cast < double > ( _codeFreqBasis ) / static_cast < double > ( _codeLength ) ) ) ;
2014-08-05 00:01:37 +00:00
2015-03-16 23:22:20 +00:00
delay = ( ( _codeLength - _chip_shift ) % _codeLength ) * _samplesPerCode / _codeLength ;
2014-05-20 19:53:12 +00:00
if ( _fs ! = _codeFreqBasis )
{
2015-05-25 16:46:55 +00:00
std : : complex < float > * _resampled_signal ;
2018-12-08 17:49:31 +00:00
if ( posix_memalign ( reinterpret_cast < void * * > ( & _resampled_signal ) , 16 , _samplesPerCode * sizeof ( gr_complex ) ) = = 0 )
2018-03-03 01:03:39 +00:00
{
} ;
2019-06-28 23:28:30 +00:00
resampler ( gsl : : span < std : : complex < float > > ( _code , _codeLength ) , gsl : : span < std : : complex < float > > ( _resampled_signal , _samplesPerCode ) , _codeFreqBasis , _fs ) ; // resamples code to fs
2015-05-25 16:46:55 +00:00
delete [ ] _code ;
_code = _resampled_signal ;
2014-05-20 19:53:12 +00:00
}
2014-06-17 17:13:24 +00:00
2018-08-13 08:18:05 +00:00
for ( uint32_t i = 0 ; i < _samplesPerCode ; i + + )
2014-05-20 19:53:12 +00:00
{
2015-03-16 23:22:20 +00:00
_dest [ ( i + delay ) % _samplesPerCode ] = _code [ i ] ;
2014-05-20 19:53:12 +00:00
}
2019-03-02 01:48:26 +00:00
if ( _fs ! = _codeFreqBasis )
{
free ( _code ) ;
}
else
{
delete [ ] _code ;
}
2014-05-20 19:53:12 +00:00
}