Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
chain78
qtcpp_demo
提交
a5649f03
qtcpp_demo
项目概览
chain78
/
qtcpp_demo
与 Fork 源项目一致
Fork自
colorEagleStdio / qtcpp_demo
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
qtcpp_demo
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
a5649f03
编写于
2月 10, 2021
作者:
M
manjaro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add spread test app
上级
ffaf5b9f
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
535 addition
and
2 deletion
+535
-2
uhd_cpp/sdr.pro
uhd_cpp/sdr.pro
+3
-2
uhd_cpp/uhd_the_ark.cpp
uhd_cpp/uhd_the_ark.cpp
+532
-0
未找到文件。
uhd_cpp/sdr.pro
浏览文件 @
a5649f03
...
...
@@ -4,5 +4,6 @@ CONFIG -= app_bundle
CONFIG
-=
qt
SOURCES
+=
\
uhd_io_burst
.
cpp
LIBS
+=
-
luhd
-
lpthread
-
latomic
uhd_the_ark
.
cpp
LIBS
+=
-
luhd
-
lpthread
-
lgomp
QMAKE_CXXFLAGS_RELEASE
+=
-
fopenmp
-
O3
-
fopenmp
-
mavx2
uhd_cpp/uhd_the_ark.cpp
0 → 100644
浏览文件 @
a5649f03
/*
* Copyright 2015 Ettus Research LLC
* Copyright 2018 Ettus Research, a National Instruments Company
*
* SPDX-License-Identifier: GPL-3.0-or-later
* 丁劲犇修改 2021
*/
#include <uhd/types/tune_request.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/thread.hpp>
#include <chrono>
#include <complex>
#include <csignal>
#include <fstream>
#include <iostream>
#include <thread>
#include <vector>
#include <cmath>
using
uhd
::
tune_request_t
;
using
uhd
::
tx_streamer
;
using
uhd
::
usrp
::
multi_usrp
;
using
uhd
::
rx_streamer
;
using
std
::
thread
;
using
std
::
cerr
;
using
std
::
endl
;
using
std
::
string
;
using
std
::
vector
;
using
std
::
shared_ptr
;
static
bool
stop_signal_called
(
false
);
void
sigint_handler
(
int
code
){
(
void
)
code
;
stop_signal_called
=
true
;
}
/*!
* \brief The tag_channelOptions struct
* 通道配置参数
*/
struct
tag_channelOptions
{
string
type
=
"sc16"
;
//样点类型,为上位机上类型: fc64, fc32, or sc16
string
subdev
=
""
;
//通道,A:A, A:B两个通道,对应B210左侧、右侧接口.一般默认配置,用信道号channels选取接口。
string
ant
=
"TX/RX"
;
//天线选取,B210 有 TX/RX 或者 RX2两个
string
wirefmt
;
//内部类型 (sc8 or sc16),是片上处理的类型
vector
<
size_t
>
channels
{
0
};
//通道号,可以设置0,1之类的。默认subdev时,0=A:A,1=A:B,subdev被修改,则采取修改后的编号
size_t
spb
=
10000
;
//缓冲大小,太小会丢包,太大会超时
double
rate
=
500000
;
//采样率,单位Hz
double
freq
=
1.0e9
;
//射频频率,单位Hz
double
gain
=
55
;
//射频增益,单位dB
double
bw
=
rate
;
//滤波带宽,默认为采样窗口
double
lo_offset
=
0
;
//LO偏移,单位 Hz (缺省)
bool
int_n_mod
=
false
;
//int-n 模式(本例不配置)
bool
docheck
=
true
;
//在开始前执行检查
double
setup_time
=
1.0
;
//rx配置检查时间,可选。
};
//通道检查函数
bool
check_tx_status
(
const
string
&
ref
,
multi_usrp
::
sptr
usrp
,
const
tag_channelOptions
&
op
);
bool
check_rx_status
(
const
string
&
ref
,
multi_usrp
::
sptr
usrp
,
const
tag_channelOptions
&
op
);
void
do_io
(
const
tag_channelOptions
&
oprx
,
const
tag_channelOptions
&
optx
,
rx_streamer
::
sptr
rx
,
tx_streamer
::
sptr
tx
);
int
UHD_SAFE_MAIN
(
int
/*argc*/
,
char
*
/*argv*/
[])
{
//1.创建一个设备,可以不填写,则使用第一台设备。
string
args
(
""
);
//2.设置时钟参考 (internal, external, mimo)
string
ref
=
"internal"
;
cerr
<<
"Creating the usrp device with: "
<<
args
<<
"..."
<<
endl
;
multi_usrp
::
sptr
usrp
=
multi_usrp
::
make
(
args
);
usrp
->
set_clock_source
(
ref
,
multi_usrp
::
ALL_MBOARDS
);
//3.配置发射
tag_channelOptions
tx_op
;
tx_op
.
freq
=
230e6
;
tx_op
.
bw
=
tx_op
.
rate
;
tx_op
.
gain
=
70
;
tx_op
.
channels
[
0
]
=
0
;
//3.1子设备配置(默认),一般不动它。
if
(
tx_op
.
subdev
.
size
())
usrp
->
set_tx_subdev_spec
(
tx_op
.
subdev
,
multi_usrp
::
ALL_MBOARDS
);
cerr
<<
"TX Using Device: "
<<
usrp
->
get_pp_string
()
<<
endl
;
//3.2速率配置
cerr
<<
"Setting TX Rate: "
<<
(
tx_op
.
rate
/
1e6
)
<<
"Msps..."
<<
endl
;
usrp
->
set_tx_rate
(
tx_op
.
rate
,
multi_usrp
::
ALL_CHANS
);
cerr
<<
"Actual TX Rate: "
<<
usrp
->
get_tx_rate
(
tx_op
.
channels
[
0
])
/
1e6
<<
"Msps..."
<<
endl
;
//3.3中心频率配置
cerr
<<
"Setting TX Freq: "
<<
(
tx_op
.
freq
/
1e6
)
<<
"MHz..."
<<
endl
;
cerr
<<
"Setting TX LO Offset: "
<<
(
tx_op
.
lo_offset
/
1e6
)
<<
"MHz..."
<<
endl
;
tune_request_t
tune_request_tx
=
tune_request_t
(
tx_op
.
freq
,
tx_op
.
lo_offset
);
if
(
tx_op
.
int_n_mod
)
tune_request_tx
.
args
=
uhd
::
device_addr_t
(
"mode_n=integer"
);
usrp
->
set_tx_freq
(
tune_request_tx
,
tx_op
.
channels
[
0
]);
cerr
<<
"Actual TX Freq: "
<<
(
usrp
->
get_tx_freq
(
tx_op
.
channels
[
0
])
/
1e6
)
<<
"MHz..."
<<
endl
;
//3.4增益配置
cerr
<<
"Setting TX Gain: "
<<
tx_op
.
gain
<<
" dB..."
<<
endl
;
usrp
->
set_tx_gain
(
tx_op
.
gain
,
tx_op
.
channels
[
0
]);
cerr
<<
"Actual TX Gain: "
<<
usrp
->
get_tx_gain
(
tx_op
.
channels
[
0
])
<<
" dB..."
<<
endl
;
//3.5模拟前端滤波器带宽配置
cerr
<<
"Setting TX Bandwidth: "
<<
(
tx_op
.
bw
/
1e6
)
<<
"MHz..."
<<
endl
;
usrp
->
set_tx_bandwidth
(
tx_op
.
bw
,
tx_op
.
channels
[
0
]);
cerr
<<
"Actual TX Bandwidth: "
<<
usrp
->
get_tx_bandwidth
(
tx_op
.
channels
[
0
])
/
1e6
<<
"MHz..."
<<
endl
;
//3.6指定天线
if
(
tx_op
.
ant
.
size
())
usrp
->
set_tx_antenna
(
tx_op
.
ant
,
tx_op
.
channels
[
0
]);
//4.配置接收
tag_channelOptions
rx_op
;
rx_op
.
ant
=
"RX2"
;
rx_op
.
bw
=
rx_op
.
rate
;
rx_op
.
freq
=
230e6
;
rx_op
.
gain
=
30
;
rx_op
.
channels
[
0
]
=
1
;
//4.1 子设备
if
(
rx_op
.
subdev
.
size
())
usrp
->
set_rx_subdev_spec
(
rx_op
.
subdev
,
multi_usrp
::
ALL_MBOARDS
);
cerr
<<
"RX Using Device: "
<<
usrp
->
get_pp_string
()
<<
endl
;
//4.2 采样率
cerr
<<
"Setting RX Rate: "
<<
(
rx_op
.
rate
/
1e6
)
<<
"Msps..."
<<
endl
;
usrp
->
set_rx_rate
(
rx_op
.
rate
,
multi_usrp
::
ALL_CHANS
);
cerr
<<
"Actual RX Rate: "
<<
usrp
->
get_rx_rate
(
rx_op
.
channels
[
0
])
/
1e6
<<
"Msps..."
<<
endl
;
//4.3 中心频率
cerr
<<
"Setting RX Freq: "
<<
(
rx_op
.
freq
/
1e6
)
<<
"MHz..."
<<
endl
;
cerr
<<
"Setting RX LO Offset: "
<<
(
rx_op
.
lo_offset
/
1e6
)
<<
"MHz..."
<<
endl
;
tune_request_t
tune_request_rx
=
tune_request_t
(
rx_op
.
freq
,
rx_op
.
lo_offset
);
if
(
rx_op
.
int_n_mod
)
tune_request_rx
.
args
=
uhd
::
device_addr_t
(
"mode_n=integer"
);
usrp
->
set_rx_freq
(
tune_request_rx
,
rx_op
.
channels
[
0
]);
cerr
<<
"Actual RX Freq: "
<<
(
usrp
->
get_rx_freq
(
rx_op
.
channels
[
0
])
/
1e6
)
<<
"MHz..."
<<
endl
;
//4.4 增益
cerr
<<
"Setting RX Gain: "
<<
rx_op
.
gain
<<
" dB..."
<<
endl
;
usrp
->
set_rx_gain
(
rx_op
.
gain
,
rx_op
.
channels
[
0
]);
cerr
<<
"Actual RX Gain: "
<<
usrp
->
get_rx_gain
(
rx_op
.
channels
[
0
])
<<
" dB..."
<<
endl
;
//4.5 前端模拟滤波带宽
cerr
<<
"Setting RX Bandwidth: "
<<
(
rx_op
.
bw
/
1e6
)
<<
"MHz..."
<<
endl
;
usrp
->
set_rx_bandwidth
(
rx_op
.
bw
,
rx_op
.
channels
[
0
]);
cerr
<<
"Actual RX Bandwidth: "
<<
usrp
->
get_rx_bandwidth
(
rx_op
.
channels
[
0
])
/
1e6
<<
"MHz..."
<<
endl
;
//4.6 选择天线
if
(
rx_op
.
ant
.
size
())
usrp
->
set_rx_antenna
(
rx_op
.
ant
,
rx_op
.
channels
[
0
]);
//5 检查状态
if
(
tx_op
.
docheck
)
check_tx_status
(
ref
,
usrp
,
tx_op
);
if
(
rx_op
.
docheck
)
check_rx_status
(
ref
,
usrp
,
rx_op
);
//6.创建流对象实例
//6.1 发射
uhd
::
stream_args_t
stream_args_tx
(
tx_op
.
type
,
tx_op
.
wirefmt
);
stream_args_tx
.
channels
=
tx_op
.
channels
;
tx_streamer
::
sptr
tx_stream
=
usrp
->
get_tx_stream
(
stream_args_tx
);
// 6.2 接收
uhd
::
stream_args_t
stream_args_rx
(
rx_op
.
type
,
rx_op
.
wirefmt
);
stream_args_rx
.
channels
=
rx_op
.
channels
;
rx_streamer
::
sptr
rx_stream
=
usrp
->
get_rx_stream
(
stream_args_rx
);
//开始收发循环
do_io
(
rx_op
,
tx_op
,
rx_stream
,
tx_stream
);
// finished
cerr
<<
endl
<<
"Done!"
<<
endl
<<
endl
;
return
EXIT_SUCCESS
;
}
//收发计数
static
unsigned
long
long
rx_count
(
0
),
tx_count
(
0
);
//消费生产计数
static
unsigned
long
long
deal_count
(
0
),
gene_count
(
0
);
//缓存点数(IQ)
static
const
size_t
rxbuf_points
=
1000
*
1000
*
16
;
static
const
size_t
txbuf_points
=
1000
*
1000
*
16
;
//缓存,留有尾巴保护
static
std
::
shared_ptr
<
short
[][
2
]
>
rx_buf_ptr
(
new
short
[
rxbuf_points
+
1024
*
1024
][
2
]{{
0
,
0
}});
static
std
::
shared_ptr
<
short
[][
2
]
>
tx_buf_ptr
(
new
short
[
txbuf_points
+
1024
*
1024
][
2
]{{
0
,
0
}});
void
init_wavform
();
//生产者线程,for tx
void
producer
();
//消费者线程,for rx
void
dealer
();
/*!
* 范例吞吐函数,使用环形队列保持跟随收发
*/
void
do_io
(
const
tag_channelOptions
&
oprx
,
const
tag_channelOptions
&
optx
,
rx_streamer
::
sptr
rx
,
tx_streamer
::
sptr
tx
)
{
if
(
oprx
.
channels
.
size
()
>
1
||
optx
.
channels
.
size
()
>
1
)
{
cerr
<<
"multi channels IO is not suitable for this simple demo."
<<
endl
;
return
;
}
//初始化队列
short
(
*
pBufRx
)[
2
]
=
rx_buf_ptr
.
get
();
short
(
*
pBufTx
)[
2
]
=
tx_buf_ptr
.
get
();
rx_count
=
0
;
tx_count
=
0
;
deal_count
=
0
;
gene_count
=
0
;
//接收线程
auto
thcall_rx
=
[
&
]()
->
void
{
uhd
::
rx_metadata_t
md_rx
;
uhd
::
stream_cmd_t
stream_cmd
(
uhd
::
stream_cmd_t
::
STREAM_MODE_START_CONTINUOUS
);
stream_cmd
.
num_samps
=
size_t
(
oprx
.
spb
);
stream_cmd
.
stream_now
=
true
;
stream_cmd
.
time_spec
=
uhd
::
time_spec_t
();
rx
->
issue_stream_cmd
(
stream_cmd
);
while
(
!
stop_signal_called
)
{
size_t
red
=
rx
->
recv
((
void
*
)(
pBufRx
[
rx_count
%
rxbuf_points
]),
oprx
.
spb
,
md_rx
,
10
,
false
);
rx_count
+=
red
;
const
size_t
newBg
=
rx_count
%
rxbuf_points
;
if
(
newBg
<
oprx
.
spb
&&
newBg
>
0
)
memcpy
(
pBufRx
[
0
],
pBufRx
[
rxbuf_points
],
sizeof
(
short
)
*
2
*
newBg
);
//md_rx可以读取时戳
//auto tm_first = md_rx.time_spec;
if
(
md_rx
.
error_code
==
uhd
::
rx_metadata_t
::
ERROR_CODE_TIMEOUT
)
fputs
(
"Time out."
,
stderr
);
else
if
(
md_rx
.
error_code
==
uhd
::
rx_metadata_t
::
ERROR_CODE_OVERFLOW
)
fputs
(
"Over flow"
,
stderr
);
else
if
(
md_rx
.
error_code
!=
uhd
::
rx_metadata_t
::
ERROR_CODE_NONE
)
cerr
<<
"Receiver error: "
<<
md_rx
.
strerror
()
<<
endl
;
}
};
//发射线程
auto
thcall_tx
=
[
&
]()
->
void
{
uhd
::
tx_metadata_t
md_tx
;
md_tx
.
end_of_burst
=
false
;
md_tx
.
start_of_burst
=
false
;
while
(
!
stop_signal_called
)
{
const
size_t
cur_bg
=
tx_count
%
txbuf_points
;
const
size_t
new_bg
=
(
tx_count
+
optx
.
spb
)
%
txbuf_points
;
if
(
new_bg
<
optx
.
spb
&&
new_bg
>
0
)
memcpy
(
pBufTx
[
txbuf_points
],
pBufTx
[
0
],
sizeof
(
short
)
*
2
*
new_bg
);
const
size_t
sent
=
tx
->
send
((
void
*
)(
pBufTx
[
cur_bg
]),
optx
.
spb
,
md_tx
,
1
);
tx_count
+=
sent
;
if
(
sent
!=
optx
.
spb
)
cerr
<<
"The tx_stream timed out sending "
<<
optx
.
spb
<<
" samples ("
<<
sent
<<
" sent)."
<<
endl
;
}
};
init_wavform
();
//启动线程
thread
produce_thread
(
producer
);
thread
tx_thread
(
thcall_tx
);
thread
rx_thread
(
thcall_rx
);
thread
deal_thread
(
dealer
);
cerr
<<
"Press ^C to Stop."
<<
endl
;
//主线程不断打印状态
while
(
!
stop_signal_called
)
{
cerr
<<
"P "
<<
gene_count
<<
" TX "
<<
tx_count
<<
" RX "
<<
rx_count
<<
"D "
<<
deal_count
<<
"
\r
"
;
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
100
));
if
(
rx_count
>=
4
*
1024
*
1024
)
stop_signal_called
=
true
;
}
//退出
produce_thread
.
join
();
rx_thread
.
join
();
tx_thread
.
join
();
deal_thread
.
join
();
}
static
const
int
modraten
=
32
;
static
const
int
amp
=
1000
;
static
const
int
spread_ratio
=
16
;
static
const
size_t
wav_size
=
spread_ratio
*
modraten
;
static
short
wav_spread
[
2
][
wav_size
][
2
];
static
short
wav_xorr
[
2
][
wav_size
][
2
];
void
init_wavform
()
{
const
double
pi
=
3.14159265358979323846
;
// 2FSK, 0/1, modraten samples, i,q
short
wav
[
2
][
modraten
][
2
];
for
(
int
i
=
0
;
i
<
modraten
;
++
i
)
{
wav
[
0
][
i
][
0
]
=
amp
*
cos
(
2
*
pi
*
i
/
modraten
);
wav
[
0
][
i
][
1
]
=
amp
*
sin
(
2
*
pi
*
i
/
modraten
);
wav
[
1
][
i
][
0
]
=
amp
*
cos
(
2
*
pi
*
i
/
modraten
);
wav
[
1
][
i
][
1
]
=-
amp
*
sin
(
2
*
pi
*
i
/
modraten
);
}
//M序列扩频
char
reg
[
21
]
=
{
0
,
1
,
1
,
0
,
0
,
1
,
0
,
1
,
1
,
0
,
0
,
1
,
0
,
1
,
1
,
0
,
0
,
1
,
0
,
1
,
1
};
//seq[0]是 0的符号,1是1的符号。每个符号中的0,1又对应了wav的IQ路
char
seq
[
2
][
spread_ratio
];
int
sw
=
0
;
//产生0,1的波形
fprintf
(
stderr
,
"0="
);
for
(
int
i
=
0
;
i
<
spread_ratio
;
++
i
)
{
reg
[
sw
%
21
]
=
reg
[(
sw
+
3
)
%
21
]
^
reg
[(
sw
+
20
)
%
21
];
seq
[
0
][
i
]
=
reg
[
sw
%
21
];
fprintf
(
stderr
,
"%d"
,
seq
[
0
][
i
]);
--
sw
;
if
(
sw
<
0
)
sw
=
20
;
for
(
int
j
=
0
;
j
<
modraten
;
++
j
)
{
wav_spread
[
0
][
i
*
modraten
+
j
][
0
]
=
wav
[
seq
[
0
][
i
]][
j
][
0
];
wav_spread
[
0
][
i
*
modraten
+
j
][
1
]
=
wav
[
seq
[
0
][
i
]][
j
][
1
];
wav_xorr
[
0
][
i
*
modraten
+
j
][
0
]
=
wav
[
seq
[
0
][
i
]][
j
][
0
];
wav_xorr
[
0
][
i
*
modraten
+
j
][
1
]
=
-
wav
[
seq
[
0
][
i
]][
j
][
1
];
}
}
for
(
int
i
=
0
;
i
<
spread_ratio
*
16
;
++
i
)
{
reg
[
sw
%
21
]
=
reg
[(
sw
+
3
)
%
21
]
^
reg
[(
sw
+
20
)
%
21
];
seq
[
0
][
i
]
=
reg
[
sw
%
21
];
--
sw
;
if
(
sw
<
0
)
sw
=
20
;
}
fprintf
(
stderr
,
"
\n
1="
);
for
(
int
i
=
0
;
i
<
spread_ratio
;
++
i
)
{
reg
[
sw
%
21
]
=
reg
[(
sw
+
3
)
%
21
]
^
reg
[(
sw
+
20
)
%
21
];
seq
[
1
][
i
]
=
reg
[
sw
%
21
];
fprintf
(
stderr
,
"%d"
,
seq
[
1
][
i
]);
--
sw
;
if
(
sw
<
0
)
sw
=
20
;
for
(
int
j
=
0
;
j
<
modraten
;
++
j
)
{
wav_spread
[
1
][
i
*
modraten
+
j
][
0
]
=
wav
[
seq
[
1
][
i
]][
j
][
0
];
wav_spread
[
1
][
i
*
modraten
+
j
][
1
]
=
wav
[
seq
[
1
][
i
]][
j
][
1
];
wav_xorr
[
1
][
i
*
modraten
+
j
][
0
]
=
wav
[
seq
[
1
][
i
]][
j
][
0
];
wav_xorr
[
1
][
i
*
modraten
+
j
][
1
]
=
-
wav
[
seq
[
1
][
i
]][
j
][
1
];
}
}
fprintf
(
stderr
,
"
\n
Data inited.
\n
"
);
}
//生产者线程,for tx
void
producer
()
{
short
(
*
pBufTx
)[
2
]
=
tx_buf_ptr
.
get
();
//Push 0x7e
char
idle
[
8
]
=
{
0
,
1
,
1
,
1
,
1
,
1
,
1
,
0
};
while
(
!
stop_signal_called
)
{
if
(
gene_count
>
tx_count
+
txbuf_points
/
2
)
{
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
10
));
continue
;
}
const
unsigned
long
long
clk_wav_sprd
=
gene_count
%
wav_size
;
const
unsigned
long
long
clk_bits
=
(
gene_count
/
wav_size
)
%
8
;
const
int
curr_bit
=
idle
[
clk_bits
];
pBufTx
[
gene_count
%
txbuf_points
][
0
]
=
wav_spread
[
curr_bit
][
clk_wav_sprd
][
0
];
pBufTx
[
gene_count
%
txbuf_points
][
1
]
=
wav_spread
[
curr_bit
][
clk_wav_sprd
][
1
];
++
gene_count
;
}
}
//消费者线程,for rx
void
dealer
()
{
unsigned
long
long
next_test
=
wav_size
;
short
(
*
pBufRx
)[
2
]
=
rx_buf_ptr
.
get
();
while
(
!
stop_signal_called
)
{
if
(
deal_count
+
wav_size
>=
rx_count
||
rx_count
<
wav_size
)
{
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
10
));
continue
;
}
if
(
deal_count
<
next_test
)
{
++
deal_count
;
continue
;
}
long
long
cross
[
2
][
3
]
=
{{
0
,
0
,
0
},{
0
,
0
,
0
}};
unsigned
long
long
start_x
=
deal_count
-
wav_size
;
//xorr
#pragma omp simd
for
(
size_t
i
=
0
;
i
<
wav_size
;
++
i
)
{
int
xb
=
(
start_x
+
i
)
%
rxbuf_points
;
cross
[
0
][
0
]
+=
(
long
long
)(
pBufRx
[
xb
][
0
])
*
wav_xorr
[
0
][
i
][
0
]
-
(
long
long
)(
pBufRx
[
xb
][
1
])
*
wav_xorr
[
0
][
i
][
1
];
cross
[
0
][
1
]
+=
(
long
long
)(
pBufRx
[
xb
][
0
])
*
wav_xorr
[
0
][
i
][
1
]
+
(
long
long
)(
pBufRx
[
xb
][
1
])
*
wav_xorr
[
0
][
i
][
0
];
cross
[
1
][
0
]
+=
(
long
long
)(
pBufRx
[
xb
][
0
])
*
wav_xorr
[
1
][
i
][
0
]
-
(
long
long
)(
pBufRx
[
xb
][
1
])
*
wav_xorr
[
1
][
i
][
1
];
cross
[
1
][
1
]
+=
(
long
long
)(
pBufRx
[
xb
][
0
])
*
wav_xorr
[
1
][
i
][
1
]
+
(
long
long
)(
pBufRx
[
xb
][
1
])
*
wav_xorr
[
1
][
i
][
0
];
}
cross
[
0
][
2
]
=
(
abs
(
cross
[
0
][
0
])
+
abs
(
cross
[
0
][
1
]));
cross
[
1
][
2
]
=
(
abs
(
cross
[
1
][
0
])
+
abs
(
cross
[
1
][
1
]))
;
if
(
cross
[
0
][
2
]
/
5
>
cross
[
1
][
2
]
)
{
printf
(
"Clock %lld(%lld) > 0=%lld,1=%lld, %lf
\n
"
,
deal_count
,
deal_count
/
wav_size
,
cross
[
0
][
2
],
cross
[
1
][
2
]
,
log
((
cross
[
0
][
2
]
+
1.0
)
/
(
cross
[
1
][
2
]
+
1.0
))
/
log
(
10
)
*
10
);
next_test
=
deal_count
+
wav_size
-
modraten
*
2
;
}
if
(
cross
[
1
][
2
]
/
5
>
cross
[
0
][
2
]
)
{
printf
(
"Clock %lld(%lld) > 1=%lld,0=%lld, %lf
\n
"
,
deal_count
,
deal_count
/
wav_size
,
cross
[
1
][
2
],
cross
[
0
][
2
]
,
log
((
cross
[
1
][
2
]
+
1.0
)
/
(
cross
[
0
][
2
]
+
1.0
))
/
log
(
10
)
*
10
);
next_test
=
deal_count
+
wav_size
-
modraten
*
2
;
}
++
deal_count
;
}
}
//-----------------------维护代码------------------------
bool
check_tx_status
(
const
string
&
ref
,
multi_usrp
::
sptr
usrp
,
const
tag_channelOptions
&
op
)
{
// Check Ref and LO Lock detect
vector
<
string
>
sensor_names
;
for
(
size_t
c
:
op
.
channels
)
{
sensor_names
=
usrp
->
get_tx_sensor_names
(
c
);
if
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
"lo_locked"
)
!=
sensor_names
.
end
())
{
uhd
::
sensor_value_t
lo_locked
=
usrp
->
get_tx_sensor
(
"lo_locked"
,
op
.
channels
[
0
]);
cerr
<<
"Checking TX: "
<<
lo_locked
.
to_pp_string
()
<<
std
::
endl
;
UHD_ASSERT_THROW
(
lo_locked
.
to_bool
());
}
}
sensor_names
=
usrp
->
get_mboard_sensor_names
(
0
);
if
((
ref
==
"mimo"
)
and
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
"mimo_locked"
)
!=
sensor_names
.
end
()))
{
uhd
::
sensor_value_t
mimo_locked
=
usrp
->
get_mboard_sensor
(
"mimo_locked"
,
0
);
std
::
cerr
<<
"Checking TX: "
<<
mimo_locked
.
to_pp_string
()
<<
std
::
endl
;
UHD_ASSERT_THROW
(
mimo_locked
.
to_bool
());
}
if
((
ref
==
"external"
)
and
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
"ref_locked"
)
!=
sensor_names
.
end
()))
{
uhd
::
sensor_value_t
ref_locked
=
usrp
->
get_mboard_sensor
(
"ref_locked"
,
0
);
std
::
cout
<<
"Checking TX: %s ..."
<<
ref_locked
.
to_pp_string
()
<<
std
::
endl
;
UHD_ASSERT_THROW
(
ref_locked
.
to_bool
());
}
return
true
;
}
typedef
std
::
function
<
uhd
::
sensor_value_t
(
const
string
&
)
>
get_sensor_fn_t
;
bool
check_locked_sensor
(
vector
<
string
>
sensor_names
,
const
char
*
sensor_name
,
get_sensor_fn_t
get_sensor_fn
,
double
setup_time
)
{
if
(
std
::
find
(
sensor_names
.
begin
(),
sensor_names
.
end
(),
sensor_name
)
==
sensor_names
.
end
())
return
false
;
auto
setup_timeout
=
std
::
chrono
::
steady_clock
::
now
()
+
std
::
chrono
::
milliseconds
(
int64_t
(
setup_time
*
1000
));
bool
lock_detected
=
false
;
std
::
cerr
<<
"Checking RX Waiting for: "
<<
sensor_name
;
std
::
cerr
.
flush
();
while
(
true
)
{
if
(
lock_detected
and
(
std
::
chrono
::
steady_clock
::
now
()
>
setup_timeout
))
{
std
::
cerr
<<
" locked."
<<
std
::
endl
;
break
;
}
if
(
get_sensor_fn
(
sensor_name
).
to_bool
())
{
std
::
cerr
<<
"+"
;
std
::
cerr
.
flush
();
lock_detected
=
true
;
}
else
{
if
(
std
::
chrono
::
steady_clock
::
now
()
>
setup_timeout
)
{
std
::
cerr
<<
std
::
endl
;
std
::
cerr
<<
"timed out waiting for consecutive locks on sensor : "
<<
sensor_name
;
return
false
;
}
std
::
cerr
.
flush
();
}
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
100
));
}
std
::
cout
<<
std
::
endl
;
return
true
;
}
bool
check_rx_status
(
const
string
&
ref
,
multi_usrp
::
sptr
usrp
,
const
tag_channelOptions
&
op
)
{
// check Ref and LO Lock detect
for
(
size_t
c
:
op
.
channels
)
{
check_locked_sensor
(
usrp
->
get_rx_sensor_names
(
c
),
"lo_locked"
,
[
usrp
,
op
,
c
](
const
string
&
sensor_name
)
{
return
usrp
->
get_rx_sensor
(
sensor_name
,
c
);
},
op
.
setup_time
);
}
if
(
ref
==
"mimo"
)
{
check_locked_sensor
(
usrp
->
get_mboard_sensor_names
(
0
),
"mimo_locked"
,
[
usrp
](
const
string
&
sensor_name
)
{
return
usrp
->
get_mboard_sensor
(
sensor_name
);
},
op
.
setup_time
);
}
if
(
ref
==
"external"
)
{
check_locked_sensor
(
usrp
->
get_mboard_sensor_names
(
0
),
"ref_locked"
,
[
usrp
](
const
string
&
sensor_name
)
{
return
usrp
->
get_mboard_sensor
(
sensor_name
);
},
op
.
setup_time
);
}
return
true
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录