mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-16 05:00:35 +00:00
301 lines
9.9 KiB
C++
301 lines
9.9 KiB
C++
/*----------------------------------------------------------------------------------------------*/
|
|
/*! \file gn3s.cpp
|
|
//
|
|
// FILENAME: gn3s.cpp
|
|
//
|
|
// DESCRIPTION: Impelements the GN3S class.
|
|
//
|
|
// DEVELOPERS: Gregory W. Heckler (2003-2009)
|
|
//
|
|
// LICENSE TERMS: Copyright (c) Gregory W. Heckler 2009
|
|
//
|
|
// This file is part of the GPS Software Defined Radio (GPS-SDR)
|
|
//
|
|
// The GPS-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 2 of
|
|
// the License, or (at your option) any later version. The GPS-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.
|
|
//
|
|
// Note: Comments within this file follow a syntax that is compatible with
|
|
// DOXYGEN and are utilized for automated document extraction
|
|
//
|
|
// Reference:
|
|
*/
|
|
/*----------------------------------------------------------------------------------------------*/
|
|
|
|
#include "sdr.h"
|
|
#include "fx2.h"
|
|
|
|
/* global variables ----------------------------------------------------------*/
|
|
using namespace std;
|
|
Fx2_dev fx2_d;
|
|
|
|
/* GN3S initialization ---------------------------------------------------------
|
|
* search front end and initialization
|
|
* args : none
|
|
* return : int status 0:okay -1:failure
|
|
*-----------------------------------------------------------------------------*/
|
|
extern int gn3s_init(void)
|
|
{
|
|
char version; /* version of modules */
|
|
unsigned char uc_flags[5];
|
|
|
|
/* Look for a device */
|
|
fx2_d = Fx2_dev(1); /* PID 0x0b39 */
|
|
if (fx2_d.usb_fx2_find() != 0) {
|
|
version = 2;
|
|
if (sdrini.fend!=FEND_GN3SV2) {
|
|
SDRPRINTF("error: wrong frontend type, GN3SV2 is found\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
fx2_d = Fx2_dev(2); /* PID 0x0b3a */
|
|
if (fx2_d.usb_fx2_find() != 0) {
|
|
version = 3;
|
|
if (sdrini.fend!=FEND_GN3SV3) {
|
|
SDRPRINTF("error: wrong frontend type, GN3SV3 is found\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
fx2_d = Fx2_dev(3); /* PID 0x0b3f */
|
|
if(fx2_d.usb_fx2_find()!=0) {
|
|
version = 3;
|
|
if (sdrini.fend!=FEND_GN3SV3) {
|
|
SDRPRINTF("error: wrong frontend type, GN3SV3 is found\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
SDRPRINTF("error: no GN3S frontend found\n");
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
fx2_d.usb_fx2_init();
|
|
/* version 2 */
|
|
if (version==2) {
|
|
fx2_d.usrp_xfer(VRQ_XFER, 1);
|
|
}
|
|
/* version 3 */
|
|
if (version==3) {
|
|
fx2_d.usrp_xfer (VRQ_AGC,0); /* AGC OFF */
|
|
fx2_d.usrp_xfer (VRQ_CMODE,132 );
|
|
fx2_d.usrp_xfer (VRQ_XFER, 0 );
|
|
fx2_d.usrp_xfer (VRQ_XFER, 1);
|
|
fx2_d.usrp_xfer2(VRQ_FLAGS, 0, uc_flags, 5);
|
|
fx2_d.usrp_xfer (VRQ_XFER, 0 );
|
|
fx2_d.usrp_xfer(VRQ_CMODE,GN3S_MODE);
|
|
fx2_d.usrp_xfer(VRQ_XFER, 1);
|
|
}
|
|
return 0;
|
|
}
|
|
/* stop front-end --------------------------------------------------------------
|
|
* stop grabber of front end
|
|
* args : none
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern void gn3s_quit(void)
|
|
{
|
|
fx2_d.close();
|
|
fx2_d.~Fx2_dev();
|
|
}
|
|
/* data expansion to binary (GN3S v2) ------------------------------------------
|
|
* get current data buffer from memory buffer
|
|
* args : char *buf I memory buffer
|
|
* int n I number of grab data
|
|
* char *expbuff O extracted data buffer
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern void gn3s_exp_v2(unsigned char *buf, int n, char *expbuf)
|
|
{
|
|
int i;
|
|
char LUT_1bit[2]={1,-1};
|
|
char shift=0, endshift=0;
|
|
|
|
/* data shift (refer gn3s-full.cc) */
|
|
/* http://ccar.colorado.edu/gnss/files/GN3Sv2.7z */
|
|
if ((buf[ 0]&0x02)!=2) shift=1;
|
|
if ((buf[n-1]&0x02)!=0) endshift=1;
|
|
|
|
for (i=0;i<n;i++) {
|
|
if (shift) {
|
|
if ((i==(n-1))&&!endshift) expbuf[i]=0;
|
|
else if ((i==(n-1))&&endshift) expbuf[i-1]=0;
|
|
else expbuf[i]=LUT_1bit[buf[i+1]&0x01];
|
|
} else {
|
|
if ((i==(n-1))&&endshift) expbuf[i]=0;
|
|
else expbuf[i]=LUT_1bit[buf[i]&0x01];
|
|
}
|
|
}
|
|
}
|
|
/* get current data buffer (GN3S v2) -------------------------------------------
|
|
* get current data buffer from memory buffer
|
|
* args : uint64_t buffloc I buffer location
|
|
* int n I number of grab data
|
|
* int dtype I data type (DTYPEI or DTYPEIQ)
|
|
* char *expbuff O extracted data buffer
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern void gn3s_getbuff_v2(uint64_t buffloc, int n, int dtype, char *expbuf)
|
|
{
|
|
uint64_t membuffloc=2*buffloc%(MEMBUFFLEN*GN3S_BUFFSIZE);
|
|
int nout;
|
|
n=2*n;
|
|
nout=(int)((membuffloc+n)-(MEMBUFFLEN*GN3S_BUFFSIZE));
|
|
|
|
mlock(hbuffmtx);
|
|
if (nout>0) {
|
|
gn3s_exp_v2(&sdrstat.buff[membuffloc],n-nout,expbuf);
|
|
gn3s_exp_v2(&sdrstat.buff[0],nout,&expbuf[n-nout]);
|
|
} else {
|
|
gn3s_exp_v2(&sdrstat.buff[membuffloc],n,expbuf);
|
|
}
|
|
unmlock(hbuffmtx);
|
|
}
|
|
/* data expansion to binary (GN3S v3) ------------------------------------------
|
|
* get current data buffer from memory buffer
|
|
* args : char *buf I memory buffer
|
|
* int n I number of grab data
|
|
* int i_mode I GN3S data grabber mode
|
|
* char *expbuff O extracted data buffer
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern void gn3s_exp_v3(unsigned char *buf, int n, int i_mode, char *expbuf)
|
|
{
|
|
int i=0;
|
|
int i_idx=0;
|
|
int i_dtype=0;
|
|
char LUT_2bit[4]={1,-1,3,-3};
|
|
char LUT_I_4bit[16]={1,-1,0,0,3,-3,0,0,0,0,0,0,0,0,0,0};
|
|
char LUT_Q_4bit[16]={1,0,-1,0,0,0,0,0,3,0,-3,0,0,0,0,0};
|
|
char MASK_2bit=0x03;
|
|
char MASK_4bit_I=0x05;
|
|
char MASK_4bit_Q=0x0A;
|
|
|
|
/* determine mode */
|
|
if (((i_mode% 100)==32)|| ((i_mode% 100)==38)) {
|
|
i_dtype =2;
|
|
}
|
|
if (((i_mode% 100)==36)|| ((i_mode% 100)==42)) {
|
|
i_dtype =4;
|
|
}
|
|
|
|
for (i=0;i<n;i++) {
|
|
switch (i_dtype) {
|
|
case 2:
|
|
expbuf[i_idx]=LUT_2bit[buf[i] & MASK_2bit];
|
|
i_idx++;
|
|
break;
|
|
case 4:
|
|
expbuf[i_idx]=LUT_I_4bit[buf[i] & MASK_4bit_I];
|
|
i_idx++;
|
|
expbuf[i_idx]=LUT_Q_4bit[buf[i] & MASK_4bit_Q];
|
|
i_idx++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/* get current data buffer (GN3S v3) -------------------------------------------
|
|
* get current data buffer from memory buffer
|
|
* args : uint64_t buffloc I buffer location
|
|
* int n I number of grab data
|
|
* int dtype I data type (DTYPEI or DTYPEIQ)
|
|
* char *expbuff O extracted data buffer
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern void gn3s_getbuff_v3(uint64_t buffloc, int n, int dtype, char *expbuf)
|
|
{
|
|
uint64_t membuffloc=buffloc%(MEMBUFFLEN*GN3S_BUFFSIZE);
|
|
int nout=(int)((membuffloc+n)-(MEMBUFFLEN*GN3S_BUFFSIZE));
|
|
|
|
mlock(hbuffmtx);
|
|
if (nout>0) {
|
|
gn3s_exp_v3(&sdrstat.buff[membuffloc],n-nout,GN3S_MODE,expbuf);
|
|
gn3s_exp_v3(&sdrstat.buff[0],nout,GN3S_MODE,&expbuf[dtype*(n-nout)]);
|
|
} else {
|
|
gn3s_exp_v3(&sdrstat.buff[membuffloc],n,GN3S_MODE,expbuf);
|
|
}
|
|
unmlock(hbuffmtx);
|
|
}
|
|
/* push data to memory buffer --------------------------------------------------
|
|
* push data to memory buffer from GN3S front end
|
|
* args : none
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern int gn3s_pushtomembuf(void)
|
|
{
|
|
bool b_overrun=false;
|
|
int nbuff;
|
|
|
|
/* check buffer overrun */
|
|
fx2_d.check_rx_overrun(&b_overrun);
|
|
if (b_overrun) return -1;
|
|
|
|
mlock(hbuffmtx);
|
|
nbuff=fx2_d.read_IF(
|
|
&sdrstat.buff[(sdrstat.buffcnt%MEMBUFFLEN)*GN3S_BUFFSIZE]);
|
|
unmlock(hbuffmtx);
|
|
|
|
if (nbuff!=GN3S_BUFFSIZE) {
|
|
SDRPRINTF("GN3S read IF error...\n");
|
|
}
|
|
|
|
mlock(hreadmtx);
|
|
sdrstat.buffcnt++;
|
|
unmlock(hreadmtx);
|
|
|
|
|
|
return 0;
|
|
}
|
|
/* push data to memory buffer --------------------------------------------------
|
|
* post-processing function: push data to memory buffer from GN3S binary IF file
|
|
* args : none
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern void fgn3s_pushtomembuf(void)
|
|
{
|
|
size_t nread;
|
|
|
|
mlock(hbuffmtx);
|
|
|
|
nread=fread(&sdrstat.buff[(sdrstat.buffcnt%MEMBUFFLEN)*GN3S_BUFFSIZE],
|
|
1,GN3S_BUFFSIZE,sdrini.fp1);
|
|
|
|
unmlock(hbuffmtx);
|
|
|
|
if (nread<GN3S_BUFFSIZE) {
|
|
sdrstat.stopflag=ON;
|
|
SDRPRINTF("end of file!\n");
|
|
}
|
|
|
|
mlock(hreadmtx);
|
|
sdrstat.buffcnt++;
|
|
unmlock(hreadmtx);
|
|
}
|
|
/* get current data buffer from IF file ----------------------------------------
|
|
* post-processing function: get current data buffer from memory buffer
|
|
* args : uint64_t buffloc I buffer location
|
|
* int n I number of grab data
|
|
* int dtype I data type (DTYPEI or DTYPEIQ)
|
|
* char *expbuff O extracted data buffer
|
|
* return : none
|
|
*-----------------------------------------------------------------------------*/
|
|
extern void fgn3s_getbuff(uint64_t buffloc, int n, int dtype, char *expbuf)
|
|
{
|
|
uint64_t membuffloc=dtype*buffloc%(MEMBUFFLEN*dtype*GN3S_BUFFSIZE);
|
|
int nout;
|
|
|
|
n=dtype*n;
|
|
nout=(int)((membuffloc+n)-(MEMBUFFLEN*dtype*GN3S_BUFFSIZE));
|
|
|
|
mlock(hbuffmtx);
|
|
if (nout>0) {
|
|
memcpy(expbuf,&sdrstat.buff[membuffloc],n-nout);
|
|
memcpy(&expbuf[(n-nout)],&sdrstat.buff[0],nout);
|
|
} else {
|
|
memcpy(expbuf,&sdrstat.buff[membuffloc],n);
|
|
}
|
|
unmlock(hbuffmtx);
|
|
}
|