support parallel rx tx

pull/30/head
Paul 2022-06-30 08:56:55 +02:00
rodzic b7129605d3
commit 2e3c8f6d69
3 zmienionych plików z 172 dodań i 118 usunięć

Wyświetl plik

@ -23,119 +23,131 @@ typedef enum radioberrysdrStreamFormat {
RADIOBERRY_SDR_CS16
} radioberrysdrStreamFormat;
class SoapyRadioberry : public SoapySDR::Device{
class sdr_stream
{
public:
sdr_stream(int dir)
{
direction = dir;
}
int get_direction() { return direction; }
void set_stream_format(radioberrysdrStreamFormat sf) { streamFormat = sf; };
radioberrysdrStreamFormat get_stream_format() { return streamFormat; };
public:
SoapyRadioberry( const SoapySDR::Kwargs & args );
~SoapyRadioberry();
private:
int direction;
radioberrysdrStreamFormat streamFormat;
};
/*******************************************************************
class SoapyRadioberry : public SoapySDR::Device
{
public:
SoapyRadioberry(const SoapySDR::Kwargs &args);
~SoapyRadioberry();
/*******************************************************************
* Identification API
******************************************************************/
std::string getDriverKey( void ) const;
std::string getDriverKey(void) const;
std::string getHardwareKey( void ) const;
SoapySDR::Kwargs getHardwareInfo( void ) const;
/*******************************************************************
std::string getHardwareKey(void) const;
SoapySDR::Kwargs getHardwareInfo(void) const;
/*******************************************************************
* Channels API
******************************************************************/
size_t getNumChannels( const int direction ) const;
size_t getNumChannels(const int direction) const;
bool getFullDuplex( const int direction, const size_t channel ) const;
/*******************************************************************
bool getFullDuplex(const int direction, const size_t channel) const;
/*******************************************************************
* Stream API
******************************************************************/
SoapySDR::RangeList getSampleRateRange(const int direction, const size_t channel) const;
SoapySDR::RangeList getSampleRateRange(const int direction, const size_t channel) const;
std::vector<std::string> getStreamFormats(const int direction, const size_t channel) const;
std::vector<std::string> getStreamFormats(const int direction, const size_t channel) const;
std::string getNativeStreamFormat(const int direction, const size_t channel, double &fullScale) const;
std::string getNativeStreamFormat(const int direction, const size_t channel, double &fullScale) const;
SoapySDR::ArgInfoList getStreamArgsInfo(const int direction, const size_t channel) const;
SoapySDR::ArgInfoList getStreamArgsInfo(const int direction, const size_t channel) const;
void closeStream(SoapySDR::Stream *stream);
SoapySDR::Stream *setupStream(
const int direction,
const std::string &format,
const std::vector<size_t> &channels = std::vector<size_t>(),
const SoapySDR::Kwargs &args = SoapySDR::Kwargs() );
int readStream(
SoapySDR::Stream *stream,
void * const *buffs,
const size_t numElems,
int &flags,
long long &timeNs,
const long timeoutUs = 100000 );
int writeStream(
SoapySDR::Stream *stream,
const void * const *buffs,
const size_t numElems,
int &flags,
const long long timeNs = 0,
const long timeoutUs = 100000);
SoapySDR::Stream *setupStream(
const int direction,
const std::string &format,
const std::vector<size_t> &channels = std::vector<size_t>(),
const SoapySDR::Kwargs &args = SoapySDR::Kwargs());
int readStream(
SoapySDR::Stream *stream,
void *const *buffs,
const size_t numElems,
int &flags,
long long &timeNs,
const long timeoutUs = 100000);
/*******************************************************************
int writeStream(
SoapySDR::Stream *stream,
const void *const *buffs,
const size_t numElems,
int &flags,
const long long timeNs = 0,
const long timeoutUs = 100000);
/*******************************************************************
* Sample Rate API
******************************************************************/
void setSampleRate( const int direction, const size_t channel, const double rate );
void setSampleRate(const int direction, const size_t channel, const double rate);
double getBandwidth( const int direction, const size_t channel ) const;
double getBandwidth(const int direction, const size_t channel) const;
std::vector<double> listBandwidths(const int direction, const size_t channel) const;
std::vector<double> listSampleRates(const int direction, const size_t channel) const;
std::vector<double> listBandwidths( const int direction, const size_t channel ) const;
std::vector<double> listSampleRates( const int direction, const size_t channel ) const;
/*******************************************************************
/*******************************************************************
* Frequency API
******************************************************************/
void setFrequency(
const int direction,
const size_t channel,
const double frequency,
const SoapySDR::Kwargs &args = SoapySDR::Kwargs());
void setFrequency(
const int direction,
const size_t channel,
const double frequency,
const SoapySDR::Kwargs &args = SoapySDR::Kwargs());
SoapySDR::RangeList getFrequencyRange( const int direction, const size_t channel) const;
SoapySDR::RangeList getFrequencyRange(const int direction, const size_t channel) const;
/*******************************************************************
/*******************************************************************
* Antenna API
******************************************************************/
std::vector<std::string> listAntennas( const int direction, const size_t channel ) const;
std::vector<std::string> listAntennas(const int direction, const size_t channel) const;
/*******************************************************************
/*******************************************************************
* Gain API
******************************************************************/
std::vector<std::string> listGains( const int direction, const size_t channel ) const;
std::vector<std::string> listGains(const int direction, const size_t channel) const;
void setGain( const int direction, const size_t channel, const double value );
void setGain(const int direction, const size_t channel, const double value);
SoapySDR::Range getGainRange( const int direction, const size_t channel ) const;
SoapySDR::Range getGainRange(const int direction, const size_t channel) const;
void controlRadioberry(uint32_t command, uint32_t command_data);
void controlRadioberry(uint32_t command, uint32_t command_data);
/*******************************************************************
* I2C API
******************************************************************/
std::string readI2C(const int addr, const size_t numBytes);
void writeI2C(const int addr, const std::string &data);
std::string readI2C(const int addr, const size_t numBytes);
void writeI2C(const int addr, const std::string &data);
private:
@ -144,8 +156,9 @@ class SoapyRadioberry : public SoapySDR::Device{
int rx_frequency;
int no_channels;
struct rb_info_arg_t rb_control;
std::unique_ptr<rpihw::driver::i2c> i2c_ptr;
bool i2c_available = false;
radioberrysdrStreamFormat streamFormat;
std::mutex send_command;
std::vector<sdr_stream *> streams;
std::unique_ptr<rpihw::driver::i2c> i2c_ptr;
bool i2c_available;
bool mox;
};

Wyświetl plik

@ -13,25 +13,26 @@ SoapyRadioberry::SoapyRadioberry( const SoapySDR::Kwargs &args ){
SoapySDR_setLogLevel(SOAPY_SDR_INFO);
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::SoapyRadioberry constructor called");
mox = false;
no_channels = 1;
fd_rb = open("/dev/radioberry", O_RDWR);
try
{
i2c_ptr = std::make_unique<rpihw::driver::i2c> (rpihw::driver::i2c("/dev/i2c-1"));
i2c_ptr = std::make_unique<rpihw::driver::i2c>(rpihw::driver::i2c("/dev/i2c-1"));
i2c_available = true;
}
catch (std::string s)
{
printf("I2c not found %s", s.c_str());
i2c_available = false;
}
}
}
SoapyRadioberry::~SoapyRadioberry(void){
SoapyRadioberry::~SoapyRadioberry(void)
{
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::SoapyRadioberry destructor called");
for (auto con : streams)
delete (con);
if (fd_rb != 0) close(fd_rb);
}
@ -130,21 +131,10 @@ bool SoapyRadioberry::getFullDuplex( const int direction, const size_t channel )
std::vector<double> SoapyRadioberry::listBandwidths( const int direction, const size_t channel ) const
{
// radioberry does nor support bandwidth
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::listBandwidths called");
std::vector<double> options;
if (direction == SOAPY_SDR_RX) {
options.push_back(0.048e6);
options.push_back(0.096e6);
options.push_back(0.192e6);
options.push_back(0.384e6);
}
if (direction == SOAPY_SDR_TX) {
options.push_back(0.048e6);
}
return(options);
}
@ -242,17 +232,24 @@ void SoapyRadioberry::setGain( const int direction, const size_t channel, const
if (direction == SOAPY_SDR_RX)
{
command = 0x14;
if (mox)
command = 0x15;
else
command = 0x14;
command_data = (0x40 | (((uint32_t)value + 12) & 0x3F));
}
if(direction==SOAPY_SDR_TX)
{ // 0 -7 TX RF gain
{ // 0 -7 TX RF gain
if (!mox)
return;
uint32_t z = (uint32_t)value;
if (value > 15) z = 15;
if (value < 0.0) z = 0;
z = z << 28;
command = 0x13;
command_data = z;
command_data = z;
}
this->SoapyRadioberry::controlRadioberry(command, command_data);
@ -266,10 +263,22 @@ void SoapyRadioberry::setFrequency( const int direction, const size_t channel,
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::setFrequency called");
uint32_t command = 0;
if(direction==SOAPY_SDR_RX) command = 4;
if(direction==SOAPY_SDR_TX) command = 3;
if (direction == SOAPY_SDR_RX)
{
if (mox)
command = 5;
else
command = 4;
}
if (direction == SOAPY_SDR_TX)
{
if (!mox)
return;
command = 3;
}
uint32_t command_data = (uint32_t) frequency;
this->SoapyRadioberry::controlRadioberry(command, command_data);
@ -277,27 +286,27 @@ void SoapyRadioberry::setFrequency( const int direction, const size_t channel,
void SoapyRadioberry::writeI2C(const int addr, const std::string &data)
{
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::writeI2C called");
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::writeI2C called");
if (!i2c_available)
return;
i2c_ptr->addr(addr);
try
{
i2c_ptr->write((uint8_t *)data.c_str(), data.size());
i2c_ptr->write((uint8_t *)data.c_str(), data.size());
}
catch (std::string s)
{
printf("%s", s.c_str());
}
printf("%s", s.c_str());
}
}
std::string SoapyRadioberry::readI2C(const int addr, const size_t numBytes)
{
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::readI2C called");
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::readI2C called");
std::string data;
if (!i2c_available)
return std::string("");
i2c_ptr->addr(addr);
@ -310,7 +319,7 @@ std::string SoapyRadioberry::readI2C(const int addr, const size_t numBytes)
catch (std::string s)
{
printf("%s", s.c_str());
}
}
return data;
}
// end of source.

Wyświetl plik

@ -12,13 +12,21 @@
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::setSampleRate called");
int irate = floor(rate);
uint32_t ucom =0x00000004;
uint32_t ucom =0x4;
uint32_t command = 0;
if (direction == SOAPY_SDR_TX)
{
command = 0x1;
if (!mox)
return;
}
if (direction == SOAPY_SDR_RX)
{
sample_rate = rate;
if (mox)
command = 1;
}
// incase of transmit still the receive samplerate need to be send
if (sample_rate < 48001.0)
@ -99,14 +107,18 @@ SoapySDR::Stream *SoapyRadioberry::setupStream(
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::setupStream called");
startTime = std::chrono::high_resolution_clock::now();
//check the format
sdr_stream *ptr;
ptr = new sdr_stream(direction);
if (format == SOAPY_SDR_CF32) {
SoapySDR_log(SOAPY_SDR_INFO, "Using format CF32.");
streamFormat = RADIOBERRY_SDR_CF32;
ptr->set_stream_format(RADIOBERRY_SDR_CF32);
}
else if(format == SOAPY_SDR_CS16 && direction == SOAPY_SDR_TX)
{
SoapySDR_log(SOAPY_SDR_INFO, "Using format CS16.");
streamFormat = RADIOBERRY_SDR_CS16;
ptr->set_stream_format(RADIOBERRY_SDR_CS16);
mox = true;
}
else
{
@ -114,8 +126,27 @@ SoapySDR::Stream *SoapyRadioberry::setupStream(
"setupStream invalid format '" + format + "' -- Only CF32 is supported by SoapyRadioberrySDR module.");
}
return (SoapySDR::Stream *) this;
streams.push_back(ptr);
return (SoapySDR::Stream *)ptr;
}
void SoapyRadioberry::closeStream(SoapySDR::Stream *stream)
{
int i = 0;
for (auto con : streams)
{
if ((sdr_stream *)stream == con)
{
if (((sdr_stream *)stream)->get_direction() == SOAPY_SDR_TX)
{ // switch off TX stream
mox = false;
setSampleRate(SOAPY_SDR_RX, 0, sample_rate);
}
delete ((sdr_stream *)stream);
streams.erase(streams.begin() + i);
}
i++;
}
}
int SoapyRadioberry::readStream(
@ -133,14 +164,15 @@ int SoapyRadioberry::readStream(
int16_t *itarget_buffer = (int16_t *) buff_base;
int32_t left_sample;
int32_t right_sample;
sdr_stream *ptr = (sdr_stream *)handle;
char rx_buffer[512];
for(int ii = 0 ; ii < npackages ; ii++)
{
no_bytes = read(fd_rb, rx_buffer, sizeof(rx_buffer));
nr_samples = no_bytes / 6;
//printf("nr_samples %d sample: %d %d %d %d %d %d\n",nr_samples, (int)rx_buffer[0],(int)rx_buffer[1],(int)rx_buffer[2],(int)rx_buffer[3],(int)rx_buffer[4],(int)rx_buffer[5]);
if(streamFormat == RADIOBERRY_SDR_CF32)
if (ptr->get_stream_format() == RADIOBERRY_SDR_CF32)
{
for (int i = 0; i < no_bytes; i += 6) {
left_sample = (int32_t)((signed char) rx_buffer[i]) << 16;
@ -155,7 +187,7 @@ int SoapyRadioberry::readStream(
target_buffer[iq++] = (float)right_sample / 8388608.0; // 24 bit sample
}
}
if (streamFormat == RADIOBERRY_SDR_CS16)
if (ptr->get_stream_format() == RADIOBERRY_SDR_CS16)
{
for (int i = 0; i < no_bytes; i += 6) {
left_sample = (int32_t)((signed char) rx_buffer[i]) << 16;
@ -181,8 +213,6 @@ union uTxBuffer
unsigned char i8TxBuffer[4];
};
uTxBuffer tx;
int SoapyRadioberry::writeStream(SoapySDR::Stream *stream, const void * const *buffs, const size_t numElems, int &flags, const long long timeNs, const long timeoutUs)
{
int iq = 0;
@ -192,8 +222,10 @@ int SoapyRadioberry::writeStream(SoapySDR::Stream *stream, const void * const *b
void const *buff_base = buffs[0];
float *target_buffer = (float *) buff_base;
int16_t *itarget_buffer = (int16_t *) buff_base;
uTxBuffer tx;
sdr_stream *ptr = (sdr_stream *)stream;
if (streamFormat == RADIOBERRY_SDR_CF32)
if (ptr->get_stream_format() == RADIOBERRY_SDR_CF32)
{
for (int ii = 0; ii < numElems; ii++)
{
@ -202,7 +234,7 @@ int SoapyRadioberry::writeStream(SoapySDR::Stream *stream, const void * const *b
ret = write(fd_rb, &tx, 4 * sizeof(uint8_t));
}
}
if (streamFormat == RADIOBERRY_SDR_CS16)
if (ptr->get_stream_format() == RADIOBERRY_SDR_CS16)
{
int j = 0;