提交 92d9f1c7 编写于 作者: M manjaro

Add UHD and RTLSDR test

上级 f67b9718
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
#include <stdio.h>
#include <uhd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <thread>
#include "../waveform.h"
static bool stop_signal_called = false;
#define UHD_DO(X) \
{\
uhd_error e = (X);\
if (e) { fprintf(stderr,"Error in line %d, NO %d.",__LINE__,e);\
return_code = 1;\
stop_signal_called = true;\
}\
}
void sigint_handler(int code){
(void)code;
stop_signal_called = true;
}
int runSend()
{
int return_code = EXIT_SUCCESS;
char dev_args[] = "";
char error_string[4096];
//Sample rate in Hz
double sprate = 240000 ;
double tx_freq = 200.0e6;
double tx_sprate = sprate;
double tx_gain = 70;
double tx_bw = sprate/MODRATE_N<200000?200000:sprate/MODRATE_N;
//发射信号。MIMO时,可以指定0,1
size_t tx_channel[] = {0};
//设备句柄
uhd_usrp_handle usrp = 0;
uhd_tx_streamer_handle tx_streamer = 0;
uhd_tx_metadata_handle tx_meta[4]={0,0,0,0};
fprintf(stderr, "Creating USRP with args \"%s\"...\n", dev_args);
UHD_DO(uhd_usrp_make(&usrp, dev_args));
//设置天线,子板号为0(multi-usrp支持级联)
UHD_DO(uhd_usrp_set_tx_antenna(usrp,"TX/RX",tx_channel[0]));
// Create TX streamer
UHD_DO(uhd_tx_streamer_make(&tx_streamer));
// Create TX metadata
UHD_DO(uhd_tx_metadata_make(tx_meta, false, 0, 0.1, false, false));
UHD_DO(uhd_tx_metadata_make(tx_meta+1, false, 0, 0.1, false, true));
UHD_DO(uhd_tx_metadata_make(tx_meta+2, false, 0, 0.1, true, false));
UHD_DO(uhd_tx_metadata_make(tx_meta+3, false, 0, 0.1, true, true));
// Create other necessary structs for TX
uhd_tune_request_t tx_tune_request = {
.target_freq = tx_freq,
.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
.rf_freq = 0,
.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
.dsp_freq = 0,
.args = 0
};
uhd_tune_result_t tx_tune_result;
//char tx_cpu_format[] = "fc32";
char tx_cpu_format[] = "sc16";
char tx_otw_format[] = "sc16";
char tx_args[] = "";
const size_t tx_channel_count = sizeof(tx_channel)/sizeof(tx_channel[0]);
uhd_stream_args_t tx_stream_args = {
.cpu_format = tx_cpu_format,
.otw_format = tx_otw_format,
.args = tx_args,
.channel_list = tx_channel,
.n_channels = tx_channel_count
};
size_t tx_sps_buff = 0;
// Set rate
fprintf(stderr, "Setting TX Rate: %f...\n", tx_sprate);
UHD_DO(uhd_usrp_set_tx_rate(usrp, tx_sprate, tx_channel[0]));
// See what rate actually is
UHD_DO(uhd_usrp_get_tx_rate(usrp, tx_channel[0], &tx_sprate));
fprintf(stderr, "Actual TX Rate: %f...\n\n", tx_sprate);
// Set gain
fprintf(stderr, "Setting TX Gain: %f db...\n", tx_gain);
UHD_DO(uhd_usrp_set_tx_gain(usrp, tx_gain, 0, ""));
// See what gain actually is
UHD_DO(uhd_usrp_get_tx_gain(usrp, tx_channel[0], "", &tx_gain));
fprintf(stderr, "Actual TX Gain: %f...\n", tx_gain);
// Set frequency
fprintf(stderr, "Setting TX frequency: %f MHz...\n", tx_freq / 1e6);
UHD_DO(uhd_usrp_set_tx_freq(usrp, &tx_tune_request, tx_channel[0], &tx_tune_result));
// See what frequency actually is
UHD_DO(uhd_usrp_get_tx_freq(usrp, tx_channel[0], &tx_freq));
fprintf(stderr, "Actual TX frequency: %f MHz...\n", tx_freq / 1e6);
//Band
fprintf(stderr, "Setting TX Bandwidth: %f MHz...\n", tx_bw/1e6);
UHD_DO(uhd_usrp_set_tx_bandwidth(usrp, tx_bw,tx_channel[0]));
UHD_DO(uhd_usrp_get_tx_bandwidth(usrp, tx_channel[0], &tx_bw));
fprintf(stderr, "Actual TX Bandwidth: %f MHz...\n", tx_bw / 1e6);
// Set up streamer
tx_stream_args.channel_list = tx_channel;
UHD_DO(uhd_usrp_get_tx_stream(usrp, &tx_stream_args, tx_streamer));
// Set up buffer
UHD_DO(uhd_tx_streamer_max_num_samps(tx_streamer, &tx_sps_buff));
fprintf(stderr, "Buffer size in samples: %zu\n", tx_sps_buff);
fprintf(stderr, "Press Ctrl+C to stop streaming.\n");
fprintf(stderr, "Input 0 or 1:");
// Actual streaming, TX Threading
while (!stop_signal_called) {
char c = getchar();
size_t total_sent = 0;
int wfm = -1;
if (c=='1'||c=='-')
wfm = 1;
else if (c=='0' || c=='.')
wfm = 0;
else
{
fprintf(stderr, "Input 0 or 1:");
continue;
}
if (wfm<0 || wfm >1)
{
fprintf(stderr, "Error Input.\n");
continue;
}
while (total_sent < WAVSIZE && !stop_signal_called )
{
size_t num_samps_sent = 0;
SPTYPE * tx_buff = wav_spread[wfm][total_sent];
const void ** tx_buff_ptr = (const void **) &tx_buff;
int start_of_burst = total_sent==0?1:0;
int end_of_burst = (total_sent + tx_sps_buff) >=WAVSIZE ?1:0;
int metai = start_of_burst * 2 + end_of_burst;
int send_sz = end_of_burst?(WAVSIZE - total_sent ):(tx_sps_buff);
UHD_DO(uhd_tx_streamer_send(tx_streamer, tx_buff_ptr,
send_sz, tx_meta + metai,
1, &num_samps_sent));
total_sent += num_samps_sent;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
if (tx_streamer) uhd_tx_streamer_free(&tx_streamer);
for (int i=0;i<4;++i)
if (tx_meta[i])
uhd_tx_metadata_free(tx_meta+i);
if(return_code != EXIT_SUCCESS && usrp != NULL){
uhd_usrp_last_error(usrp, error_string, 512);
fprintf(stderr, "USRP reported the following error: %s\n", error_string);
}
uhd_usrp_free(&usrp);
fprintf(stderr, (return_code ? "Failure\n" : "Success\n"));
return return_code;
}
int main()
{
// Ctrl+C will exit loop
init_wavform();
signal(SIGINT, &sigint_handler);
runSend();
return 0;
}
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
../waveform.cpp \
main.cpp
LIBS += -luhd
HEADERS += \
../waveform.h
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
#include <stdio.h>
#include <uhd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <thread>
#include <memory>
#include <atomic>
#include "../waveform.h"
static bool stop_signal_called = false;
#define UHD_DO(X) \
{\
uhd_error e = (X);\
if (e) { fprintf(stderr,"Error in line %d, NO %d.",__LINE__,e);\
return_code = 1;\
stop_signal_called = true;\
}\
}
void sigint_handler(int code){
(void)code;
stop_signal_called = true;
}
#define READ_BUF_SIZE 1024*1024
std::shared_ptr<SPTYPE[][2]> readbuf[2];
std::atomic<int> curr_active = 0;
std::atomic<int> curr_deal = 0;
//消费者线程,for rx
void dealer();
int runRecieve()
{
int return_code = EXIT_SUCCESS;
//Need soapyuhd soapysdr soapyplutosdr soapyosmo soapy_power
//要用libuhd操作RTLSDR,需要soapyuhd 来代理
char dev_args[] = "available=Yes,driver=rtlsdr,label=Generic RTL2832U :: 77771111153705700,manufacturer=Generic,product=RTL2832U,rtl=0,serial=77771111153705700,tuner=Rafael Micro R820T,type=soapy";
char error_string[4096];
//Sample rate in Hz
double sprate = 240000 ;
//接收频率
double rx_freq = 200e6;
double rx_sprate = sprate;
double rx_gain = 10.0;
bool rx_agc = false;
double rx_bw = 240000;
//接收信号。MIMO时,可以指定0,1
size_t rx_channel[] = {0};
//设备句柄
uhd_usrp_handle usrp = 0;
uhd_rx_streamer_handle rx_streamer = 0;
uhd_rx_metadata_handle rx_meta = 0;
size_t rx_sps_buff = 100000;
//ring buffer
fprintf(stderr, "Creating USRP with args \"%s\"...\n", dev_args);
UHD_DO(uhd_usrp_make(&usrp, dev_args));
fprintf(stderr, "Press Ctrl+C to stop streaming...\n");
UHD_DO(uhd_usrp_set_rx_antenna(usrp,"RX",rx_channel[0]));
// Create RX streamer
UHD_DO(uhd_rx_streamer_make(&rx_streamer));
// Create RX metadata
UHD_DO(uhd_rx_metadata_make(&rx_meta));
// Create other necessary structs
uhd_tune_request_t rx_tune_request =
{
.target_freq = rx_freq,
.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
.rf_freq = 0,
.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
.dsp_freq = 0,
.args = 0
};
uhd_tune_result_t rx_tune_result;
//char rx_cpu_format[] = "fc32";
char rx_cpu_format[] = "sc16";
char rx_otw_format[] = "sc16";
char rx_args[] = "";
const size_t rx_channel_count = sizeof(rx_channel)/sizeof(rx_channel[0]);
uhd_stream_args_t rx_stream_args = {
.cpu_format = rx_cpu_format,
.otw_format = rx_otw_format,
.args = rx_args,
.channel_list = rx_channel,
.n_channels = rx_channel_count
};
uhd_stream_cmd_t rx_stream_cmd = {
.stream_mode = UHD_STREAM_MODE_START_CONTINUOUS,
.num_samps = 0,
.stream_now = true,
.time_spec_full_secs = 0,
.time_spec_frac_secs = 0
};
// Set rate
fprintf(stderr, "Setting RX Rate: %f...\n", rx_sprate);
UHD_DO(uhd_usrp_set_rx_rate(usrp, rx_sprate, rx_channel[0]));
// See what rate actually is
UHD_DO(uhd_usrp_get_rx_rate(usrp, rx_channel[0], &rx_sprate));
fprintf(stderr, "Actual RX Rate: %f...\n", rx_sprate);
// Set gain
fprintf(stderr, "Setting RX Gain: %f dB...\n", rx_gain);
UHD_DO(uhd_usrp_set_rx_gain(usrp, rx_gain, rx_channel[0], ""));
// See what gain actually is
UHD_DO(uhd_usrp_get_rx_gain(usrp, rx_channel[0], "", &rx_gain));
fprintf(stderr, "Actual RX Gain: %f...\n", rx_gain);
if (rx_agc)
{
uhd_usrp_set_rx_agc(usrp,true,rx_channel[0]);
uhd_usrp_set_rx_dc_offset_enabled(usrp,true,rx_channel[0]);
}
// Set frequency
fprintf(stderr, "Setting RX frequency: %f MHz...\n", rx_freq/1e6);
UHD_DO(uhd_usrp_set_rx_freq(usrp, &rx_tune_request, rx_channel[0], &rx_tune_result));
// See what frequency actually is
UHD_DO(uhd_usrp_get_rx_freq(usrp, rx_channel[0], &rx_freq));
fprintf(stderr, "Actual RX frequency: %f MHz...\n", rx_freq / 1e6);
fprintf(stderr, "Setting RX Bandwidth: %f MHz...\n", rx_bw/1e6);
UHD_DO(uhd_usrp_set_rx_bandwidth(usrp, rx_bw, rx_channel[0]));
//Band
UHD_DO(uhd_usrp_get_rx_bandwidth(usrp, rx_channel[0], &rx_bw));
fprintf(stderr, "Actual RX Bandwidth: %f MHz...\n", rx_bw / 1e6);
// Set up streamer
rx_stream_args.channel_list = rx_channel;
UHD_DO(uhd_usrp_get_rx_stream(usrp, &rx_stream_args, rx_streamer));
// Set up buffer
UHD_DO(uhd_rx_streamer_max_num_samps(rx_streamer, &rx_sps_buff));
fprintf(stderr, "Buffer size in samples: %zu\n", rx_sps_buff);
// Issue stream command
fprintf(stderr, "Issuing stream command.\n");
UHD_DO(uhd_rx_streamer_issue_stream_cmd(rx_streamer, &rx_stream_cmd));
readbuf[0] = std::shared_ptr<SPTYPE[][2]> (new SPTYPE[READ_BUF_SIZE+rx_sps_buff*4][2]);
readbuf[1] = std::shared_ptr<SPTYPE[][2]> (new SPTYPE[READ_BUF_SIZE+rx_sps_buff*4][2]);
size_t total_red = 0;
//Read, RX in Main Thread
while (!stop_signal_called) {
size_t num_rx_samps = 0;
SPTYPE * rx_buff = (SPTYPE *) (readbuf[curr_active].get() + total_red);
void ** rx_buff_ptr = (void **)&rx_buff;
// Handle data
UHD_DO(uhd_rx_streamer_recv(rx_streamer, rx_buff_ptr, rx_sps_buff, &rx_meta, 1, false, &num_rx_samps));
uhd_rx_metadata_error_code_t error_code;
UHD_DO(uhd_rx_metadata_error_code(rx_meta, &error_code));
if(error_code != UHD_RX_METADATA_ERROR_CODE_NONE){
fprintf(stderr, "Warning: Error code 0x%x was returned during streaming.\n", error_code);
puts(error_string);
}
total_red += num_rx_samps;
//切换缓存
if (total_red > READ_BUF_SIZE)
{
fprintf(stderr, "Switch Cache to %d\n", (int) curr_active);
size_t start_move = READ_BUF_SIZE - WAVSIZE;
size_t end_move = total_red;
size_t copyto = end_move - start_move + 1;
SPTYPE (* dest)[2] = readbuf[1-curr_active].get();
SPTYPE (* src)[2] = readbuf[curr_active].get();
src += start_move;
memcpy(dest, src , copyto * sizeof(SPTYPE) * 2 );
total_red = copyto;
curr_active = 1 - curr_active;
}
}
if (rx_streamer) uhd_rx_streamer_free(&rx_streamer);
if (rx_meta) uhd_rx_metadata_free(&rx_meta);
if(return_code != EXIT_SUCCESS && usrp != NULL){
uhd_usrp_last_error(usrp, error_string, 512);
fprintf(stderr, "USRP reported the following error: %s\n", error_string);
}
uhd_usrp_free(&usrp);
fprintf(stderr, (return_code ? "Failure\n" : "Success\n"));
return return_code;
}
void runDeal()
{
const int DealEnd = READ_BUF_SIZE - WAVSIZE;
float (*cross)[2][2] = new float[DealEnd][2][2];
float (*judge)[2] = new float[DealEnd][2];
while (!stop_signal_called) {
if ((int)curr_active==(int)curr_deal)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
int deal = 1-curr_active;
short (*pBufRx)[2] = readbuf[deal].get();
fprintf(stderr,"Dealing %d\n",deal);
//xorr
#pragma omp simd
for (size_t i=0;i<DealEnd;++i)
{
cross[i][0][0] = 0;
cross[i][0][1] = 0;
cross[i][1][0] = 0;
cross[i][1][1] = 0;
for (size_t j=0;j<WAVSIZE;++j)
{
cross[i][0][0] += (pBufRx[i+j][0] * wav_xorr[0][j][0] - pBufRx[i+j][1] * wav_xorr[0][j][1]);
cross[i][0][1] += (pBufRx[i+j][0] * wav_xorr[0][j][1] + pBufRx[i+j][1] * wav_xorr[0][j][0]);
cross[i][1][0] += (pBufRx[i+j][0] * wav_xorr[1][j][0] - pBufRx[i+j][1] * wav_xorr[1][j][1]);
cross[i][1][1] += (pBufRx[i+j][0] * wav_xorr[1][j][1] + pBufRx[i+j][1] * wav_xorr[1][j][0]);
}
judge[i][0] = (cross[i][0][0]/32768 * cross[i][0][0]/32768 + cross[i][0][1]/32768 * cross[i][0][1]/32768 );
judge[i][1] = (cross[i][1][0]/32768 * cross[i][1][0]/32768 + cross[i][1][1]/32768 * cross[i][1][1]/32768 );
}
for (size_t i=0;i<DealEnd;++i)
{
if (judge[i][1] - judge[i][0] > 20000 )
{
printf("0=%f, 1=%f, 1\n",judge[i][0],judge[i][1]);
fflush(stdout);
i+=WAVSIZE;
}
else if (judge[i][0] - judge[i][1] > 20000)
{
printf("0=%f, 1=%f, 0\n",judge[i][0],judge[i][1]);
fflush(stdout);
i+=WAVSIZE;
}
}
//判决
curr_deal = 1-deal;
}
delete [] cross;
delete [] judge;
}
int main()
{
// Ctrl+C will exit loop
init_wavform();
signal(SIGINT, &sigint_handler);
std::thread th(runDeal);
runRecieve();
th.join();
return 0;
}
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
../waveform.cpp \
main.cpp
LIBS += -luhd -lpthread -lgomp
QMAKE_CXXFLAGS_RELEASE += -fopenmp -O3 -mavx2 -fopt-info
QMAKE_CFLAGS_RELEASE += -fopenmp -O3 -mavx2 -fopt-info
HEADERS += \
../waveform.h
#include <stdio.h>
#include <memory.h>
#include "waveform.h"
//4倍符号速率
SPTYPE wav_spread[2][WAVSIZE][2];
SPTYPE wav[2][MODRATE_N][2];
float wav_xorr[2][WAVSIZE][2];
void init_wavform(void)
{
for (int i=0;i<MODRATE_N;++i)
{
wav[0][i][0] = C_AMP ;
wav[0][i][1] = C_AMP ;
wav[1][i][0] = -C_AMP ;
wav[1][i][1] = -C_AMP ;
}
//扩频
char reg [21] = {1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
//seq[0]是 0的符号,1是1的符号。每个符号中的0,1又对应了wav的IQ路
char seq[2][SPREAD_RAT];
memset(seq,0,sizeof(seq));
int sw = 0;
//产生0,1的波形
fprintf (stderr,"0=");
for (int i=0;i<SPREAD_RAT;++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<MODRATE_N;++j)
{
wav_spread[0][i*MODRATE_N+j][0] = wav[seq[0][i]][j][0];
wav_spread[0][i*MODRATE_N+j][1] = wav[seq[0][i]][j][1];
wav_xorr[0][i*MODRATE_N+j][0] = wav[seq[0][i]][j][0]*1.0/C_AMP;
wav_xorr[0][i*MODRATE_N+j][1] = -wav[seq[0][i]][j][1]*1.0/C_AMP;
}
}
for (int i=0;i<377;++i)
{
reg[sw % 21] = reg[(sw + 3) % 21] ^ reg[(sw+20) % 21];
--sw;
if (sw < 0)
sw = 20;
}
fprintf (stderr,"\n1=");
for (int i=0;i<SPREAD_RAT;++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<MODRATE_N;++j)
{
wav_spread[1][i*MODRATE_N+j][0] = wav[seq[1][i]][j][0];
wav_spread[1][i*MODRATE_N+j][1] = wav[seq[1][i]][j][1];
wav_xorr[1][i*MODRATE_N+j][0] = wav[seq[1][i]][j][0]*1.0/C_AMP;
wav_xorr[1][i*MODRATE_N+j][1] = -wav[seq[1][i]][j][1]*1.0/C_AMP;
}
}
fprintf(stderr, "\nData inited.\n");
}
#ifndef WAVEFORM_H
#define WAVEFORM_H
typedef short SPTYPE;
#define MODRATE_N 4
#define C_AMP 8192
#define SPREAD_RAT 100
#define WAVSIZE SPREAD_RAT*MODRATE_N
extern SPTYPE wav_spread[2][WAVSIZE][2];
extern float wav_xorr[2][WAVSIZE][2];
void init_wavform();
#endif // WAVEFORM_H
......@@ -415,7 +415,6 @@ void init_wavform()
for (int i=0;i<377;++i)
{
reg[sw % 21] = reg[(sw + 3) % 21] ^ reg[(sw+20) % 21];
seq[0][i] = reg[sw % 21];
--sw;
if (sw < 0)
sw = 20;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册