Skip to content

Commit

Permalink
add tx stream code
Browse files Browse the repository at this point in the history
  • Loading branch information
jocover committed Aug 25, 2017
1 parent b3f52c9 commit bb0d64e
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 59 deletions.
10 changes: 5 additions & 5 deletions PlutoSDR_Registation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ static std::vector<SoapySDR::Kwargs> find_PlutoSDR(const SoapySDR::Kwargs &args)
std::vector<SoapySDR::Kwargs> results;

ssize_t ret=0;
iio_context *ctx;
iio_context *ctx=nullptr;
iio_scan_context *scan_ctx;
iio_context_info **info;
SoapySDR::Kwargs options;
Expand All @@ -19,11 +19,11 @@ static std::vector<SoapySDR::Kwargs> find_PlutoSDR(const SoapySDR::Kwargs &args)
if(ret == 0){

ctx=iio_create_network_context(PLUTOSDR_DEFAULT_IP);
if(ctx !=NULL){
if(ctx !=nullptr){
options["hostname"]=PLUTOSDR_DEFAULT_IP;
}else{
ctx=iio_create_network_context(PLUTOSDR_DEFAULT_HOSTNAME);
if(ctx !=NULL){
if(ctx !=nullptr){
options["hostname"]=PLUTOSDR_DEFAULT_HOSTNAME;}
else{
return results;
Expand All @@ -33,7 +33,7 @@ static std::vector<SoapySDR::Kwargs> find_PlutoSDR(const SoapySDR::Kwargs &args)
}else if (ret == 1){

ctx = iio_create_context_from_uri(iio_context_info_get_uri(info[0]));
if (ctx != NULL)
if (ctx != nullptr)
options["uri"] = std::string(iio_context_info_get_uri(info[0]));

}else{
Expand All @@ -52,7 +52,7 @@ static std::vector<SoapySDR::Kwargs> find_PlutoSDR(const SoapySDR::Kwargs &args)

results.push_back(options);

if (ctx)iio_context_destroy(ctx);
if (ctx!=nullptr)iio_context_destroy(ctx);

return results;
}
Expand Down
35 changes: 18 additions & 17 deletions PlutoSDR_Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@
SoapyPlutoSDR::SoapyPlutoSDR( const SoapySDR::Kwargs &args ):
ctx(nullptr){

if (args.count("label") != 0)
SoapySDR_logf( SOAPY_SDR_INFO, "Opening %s...", args.at("label").c_str());
if (args.count("label") != 0)
SoapySDR_logf( SOAPY_SDR_INFO, "Opening %s...", args.at("label").c_str());


if(args.count("uri") != 0) {
if(args.count("uri") != 0) {

ctx = iio_create_context_from_uri(args.at("uri").c_str());
ctx = iio_create_context_from_uri(args.at("uri").c_str());

}else if(args.count("hostname")!=0){
ctx = iio_create_network_context(args.at("hostname").c_str());
}else{
ctx = iio_create_default_context();
}

if (ctx == NULL)
throw std::runtime_error("not device found");
}else if(args.count("hostname")!=0){
ctx = iio_create_network_context(args.at("hostname").c_str());
}else{
ctx = iio_create_default_context();
}

dev = iio_context_find_device(ctx, "ad9361-phy");
if (ctx == NULL)
throw std::runtime_error("not device found");

this->setAntenna(SOAPY_SDR_RX, 0, "A_BALANCED");
dev = iio_context_find_device(ctx, "ad9361-phy");

this->setAntenna(SOAPY_SDR_RX, 0, "A_BALANCED");
this->setAntenna(SOAPY_SDR_TX, 0, "A");

}
}

SoapyPlutoSDR::~SoapyPlutoSDR(void){

Expand Down Expand Up @@ -122,7 +122,7 @@ void SoapyPlutoSDR::setAntenna( const int direction, const size_t channel, const
if (direction == SOAPY_SDR_TX) {

iio_channel_attr_write(iio_device_find_channel(dev, "voltage0", true), "rf_port_select", name.c_str());

}
}

Expand All @@ -135,7 +135,7 @@ std::string SoapyPlutoSDR::getAntenna( const int direction, const size_t channel
options = "A_BALANCED";
}
if (direction == SOAPY_SDR_TX) {

options = "A";
}
return options;
Expand Down Expand Up @@ -221,6 +221,7 @@ double SoapyPlutoSDR::getGain( const int direction, const size_t channel, const

if(direction==SOAPY_SDR_TX){


if(iio_channel_attr_read_longlong(iio_device_find_channel(dev, "voltage0", true),"hardwaregain",&gain )!=0)
return 0;
}
Expand Down
149 changes: 119 additions & 30 deletions PlutoSDR_Streaming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ SoapySDR::Stream *SoapyPlutoSDR::setupStream(

if (direction == SOAPY_SDR_TX) {

stream->tx = std::shared_ptr<tx_streamer>(new tx_streamer());
stream->tx = std::shared_ptr<tx_streamer>(new tx_streamer(ctx, format,channels, args));
}

return reinterpret_cast<SoapySDR::Stream *>(stream);
Expand All @@ -70,8 +70,6 @@ void SoapyPlutoSDR::closeStream( SoapySDR::Stream *handle)

size_t SoapyPlutoSDR::getStreamMTU( SoapySDR::Stream *handle) const
{
PlutoSDRStream *stream = reinterpret_cast<PlutoSDRStream *>(handle);

return 8196;
}

Expand Down Expand Up @@ -116,14 +114,16 @@ int SoapyPlutoSDR::readStream(
}

int SoapyPlutoSDR::writeStream(
SoapySDR::Stream *stream,
SoapySDR::Stream *handle,
const void * const *buffs,
const size_t numElems,
int &flags,
const long long timeNs,
const long timeoutUs )
{
return numElems;
PlutoSDRStream *stream = reinterpret_cast<PlutoSDRStream *>(handle);

return stream->tx->send(buffs,numElems,flags,timeNs,timeoutUs);;

}

Expand All @@ -140,7 +140,7 @@ int SoapyPlutoSDR::readStreamStatus(


rx_streamer::rx_streamer(const iio_context *ctx, const std::string &_format, const std::vector<size_t> &channels, const SoapySDR::Kwargs &args):
buf(nullptr),buffer_size(16384),dev(nullptr)
dev(nullptr),buffer_size(16384),buf(nullptr)

{
dev=iio_context_find_device(ctx, "cf-ad9361-lpc");
Expand All @@ -154,7 +154,6 @@ rx_streamer::rx_streamer(const iio_context *ctx, const std::string &_format, con

iio_channel_enable(channel_list[i]);
}

buffer.reserve(buffer_size);
buffer.resize(buffer_size);

Expand Down Expand Up @@ -192,40 +191,38 @@ size_t rx_streamer::recv(void * const *buffs,

while (please_refill_buffer) {
cond2.wait_for(lock,std::chrono::milliseconds(timeoutUs));

if (thread_stopped)
return -1; /* EOF */

}

size_t items = std::min(items_in_buffer,numElems);

int16_t* ptr = (int16_t*)buffs[0];

buffer.resize(items);
for (unsigned int i = 0; i < 2; i++) {

channel_read(channel_list[i], buffer.data(), items * sizeof(int16_t));

if (format == SOAPY_SDR_CS16) {
int16_t *samples_cs16 = (int16_t *)buffs[0];
for (size_t j = 0; j < items; ++j) {
samples_cs16[j*2+ i]=buffer[j];
}
}else if (format == SOAPY_SDR_CF32) {
float *samples_cf32 = (float *)buffs[0];
for (size_t j = 0; j < items; ++j) {
samples_cf32[j * 2 + i] = buffer[j]/2048.0;
}

buffer.resize(items);
for (unsigned int i = 0; i < 2; i++) {

channel_read(channel_list[i], buffer.data(), items * sizeof(int16_t));

if (format == SOAPY_SDR_CS16) {
int16_t *samples_cs16 = (int16_t *)buffs[0];
for (size_t j = 0; j < items; ++j) {
samples_cs16[j*2+ i]=buffer[j];
}
}else if (format == SOAPY_SDR_CF32) {
float *samples_cf32 = (float *)buffs[0];
for (size_t j = 0; j < items; ++j) {
samples_cf32[j * 2 + i] = buffer[j]/2048.0;
}
}

}


items_in_buffer -= items;
byte_offset += items * iio_buffer_step(buf);


return(items);

}
Expand Down Expand Up @@ -321,8 +318,100 @@ void rx_streamer::channel_read(const struct iio_channel *chn, void *dst, size_t
ptrdiff_t buf_step = iio_buffer_step(buf);

for (src_ptr = (uintptr_t)iio_buffer_first(buf, chn)+ byte_offset;
src_ptr < buf_end && dst_ptr + length <= end;
src_ptr += buf_step, dst_ptr += length)
src_ptr < buf_end && dst_ptr + length <= end;
src_ptr += buf_step, dst_ptr += length)
iio_channel_convert(chn,
(void *)dst_ptr, (const void *)src_ptr);
(void *)dst_ptr, (const void *)src_ptr);
}


tx_streamer::tx_streamer(const iio_context *ctx, const std::string &format, const std::vector<size_t> &channels, const SoapySDR::Kwargs &args):
dev(nullptr),buffer_size(16384),buf(nullptr)
{
dev=iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc");
if(dev == NULL)
throw std::runtime_error("cf-ad9361-dds-core-lpc not found!");
channel_list.push_back(iio_device_find_channel(dev, "voltage0", true));
channel_list.push_back(iio_device_find_channel(dev, "voltage1", true));

for(unsigned int i=0;i<channel_list.size(); ++i){

iio_channel_enable(channel_list[i]);
}
buf = iio_device_create_buffer(dev, buffer_size,false);
if (!buf)
throw std::runtime_error("Unable to create buffer: ");
buffer.reserve(buffer_size);
buffer.resize(buffer_size);

}

tx_streamer::~tx_streamer(){

if (buf) { iio_buffer_destroy(buf); }

for(unsigned int i=0;i<channel_list.size(); ++i)
iio_channel_disable(channel_list[i]);

}

int tx_streamer::send( const void * const *buffs,
const size_t numElems,
int &flags,
const long long timeNs,
const long timeoutUs )

{
size_t items = std::min(buffer_size,numElems);

buffer.resize(items);
for (unsigned int i = 0; i < 2; i++) {

if(format==SOAPY_SDR_CS16){

int16_t *samples_cs16 = (int16_t *)buffs[0];
for (size_t j = 0; j < items; ++j) {
buffer[j]=samples_cs16[j*2+i];
}

channel_write(channel_list[i],buffer.data(),items);

}else if(format==SOAPY_SDR_CF32){

float *samples_cf32 = (float *)buffs[0];
for (size_t j = 0; j < items; ++j) {
buffer[j]=(float)(samples_cf32[j*2+i]*2048);
}

channel_write(channel_list[i],buffer.data(),items);

}

}

int ret = iio_buffer_push(buf);

if (ret < 0){

return -1;

}

return items;

}

void tx_streamer::channel_write(iio_channel *chn,const void *src, size_t len){

uintptr_t dst_ptr, src_ptr = (uintptr_t) src, end = src_ptr + len;
unsigned int length = iio_channel_get_data_format(chn)->length / 8;
uintptr_t buf_end = (uintptr_t) iio_buffer_end(buf);
ptrdiff_t buf_step = iio_buffer_step(buf);

for (dst_ptr = (uintptr_t) iio_buffer_first(buf, chn);
dst_ptr < buf_end && src_ptr + length <= end;
dst_ptr += buf_step, src_ptr += length)
iio_channel_convert_inverse(chn,
(void *) dst_ptr, (const void *) src_ptr);

}
21 changes: 14 additions & 7 deletions SoapyPlutoSDR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
#include <mutex>
#include <thread>
#include <chrono>
#include <queue>
#include <deque>
#include <complex>
#include <condition_variable>
#include <SoapySDR/Device.hpp>
#include <SoapySDR/Logger.hpp>
Expand Down Expand Up @@ -43,24 +40,34 @@ class rx_streamer {
std::condition_variable cond, cond2;
std::vector<iio_channel* > channel_list;
volatile bool thread_stopped, please_refill_buffer;
iio_buffer *buf;
iio_device *dev;

std::vector<int16_t> buffer;

size_t buffer_size;
size_t byte_offset;
size_t items_in_buffer;

iio_buffer *buf;
std::string format;

};

class tx_streamer {

public:
tx_streamer(const iio_context *ctx, const std::string &format, const std::vector<size_t> &channels, const SoapySDR::Kwargs &args);
~tx_streamer();
int send(const void * const *buffs,const size_t numElems,int &flags,const long long timeNs,const long timeoutUs );

private:


void channel_write(iio_channel *chn,const void *src, size_t len);
std::vector<iio_channel* > channel_list;
iio_device *dev;
std::vector<int16_t> buffer;
std::string format;
size_t buffer_size;
bool cyclic;
iio_buffer *buf;
};


Expand Down

0 comments on commit bb0d64e

Please sign in to comment.