From 769f34a220c8ee50724f786bef7c4ce0ba5e3076 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 2 May 2022 18:05:13 +0200 Subject: [PATCH] update TX sampling rate and fix thread issue --- .../SoapyRadioberrySDR/SoapyRadioberry.hpp | 12 +-- .../SoapyRadioberrySettings.cpp | 34 ++++--- .../SoapyRadioberryStreaming.cpp | 88 ++++++++----------- 3 files changed, 67 insertions(+), 67 deletions(-) diff --git a/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberry.hpp b/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberry.hpp index 5a730c0..29f9ee8 100644 --- a/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberry.hpp +++ b/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberry.hpp @@ -8,7 +8,8 @@ #include #include #include -#include +#include +#include #include "radioberry_ioctl.h" #include "i2c.h" @@ -137,12 +138,13 @@ class SoapyRadioberry : public SoapySDR::Device{ private: - int fd_rb; - int sample_rate; - int rx_frequency; - int no_channels; + int fd_rb; + double sample_rate; + int rx_frequency; + int no_channels; struct rb_info_arg_t rb_control; std::unique_ptr i2c_ptr; bool i2c_available = false; radioberrysdrStreamFormat streamFormat; + std::mutex send_command; }; diff --git a/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberrySettings.cpp b/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberrySettings.cpp index bdb6415..fd1581b 100644 --- a/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberrySettings.cpp +++ b/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberrySettings.cpp @@ -1,4 +1,7 @@ #include "SoapyRadioberry.hpp" +#include +#include +#include #define RADIOBERRY_BUFFER_SIZE 4096 @@ -7,7 +10,8 @@ **********************************************************************/ SoapyRadioberry::SoapyRadioberry( const SoapySDR::Kwargs &args ){ - + + SoapySDR_setLogLevel(SOAPY_SDR_INFO); SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::SoapyRadioberry constructor called"); no_channels = 1; @@ -21,7 +25,7 @@ SoapyRadioberry::SoapyRadioberry( const SoapySDR::Kwargs &args ){ { printf("I2c not found %s", s.c_str()); i2c_available = false; - } + } } SoapyRadioberry::~SoapyRadioberry(void){ @@ -32,7 +36,8 @@ SoapyRadioberry::~SoapyRadioberry(void){ } void SoapyRadioberry::controlRadioberry(uint32_t command, uint32_t command_data) { - + + std::unique_lock soapy_lock(send_command); SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::controlRadioberry called"); uint32_t CWX =0; @@ -41,8 +46,8 @@ void SoapyRadioberry::controlRadioberry(uint32_t command, uint32_t command_data) rb_control.rb_command = 0x04 | (((CWX << 1) & 0x02) | (running & 0x01)); rb_control.command = command; rb_control.command_data = command_data; - - fprintf(stderr, "RB-Command = %02X Command = %02X command_data = %08X\n", rb_control.rb_command, command, command_data); + + fprintf(stderr, "RB-Command = %02X Command = %02X command_data = %08X Mox %d\n", rb_control.rb_command, command >> 1, command_data, command & 0x01); if (ioctl(fd_rb, RADIOBERRY_IOC_COMMAND, &rb_control) == -1) { SoapySDR_log(SOAPY_SDR_INFO, "Could not sent command to radioberry device."); @@ -69,13 +74,20 @@ SoapySDR::Kwargs SoapyRadioberry::getHardwareInfo( void ) const SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getHardwareInfo called"); SoapySDR::Kwargs info; - + int count = 0; struct rb_info_arg_t rb_info; - if (ioctl(fd_rb, RADIOBERRY_IOC_COMMAND, &rb_info) == -1) { - rb_info.major = 0; - rb_info.minor = 0; - } + do + { + std::memset(&rb_info, 0, sizeof(rb_info)); + if (ioctl(fd_rb, RADIOBERRY_IOC_COMMAND, &rb_info) == -1) + { + rb_info.major = 0; + rb_info.minor = 0; + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + count++; + } while ((rb_info.major == 0 || rb_info.major > 128) && count < 20); unsigned int major, minor; major = rb_info.major; @@ -256,7 +268,7 @@ void SoapyRadioberry::setFrequency( const int direction, const size_t channel, uint32_t command = 0; if(direction==SOAPY_SDR_RX) command = 4; - if(direction==SOAPY_SDR_TX) command = 2; + if(direction==SOAPY_SDR_TX) command = 3; uint32_t command_data = (uint32_t) frequency; diff --git a/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberryStreaming.cpp b/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberryStreaming.cpp index 554376b..a77707c 100644 --- a/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberryStreaming.cpp +++ b/SBC/rpi-4/SoapyRadioberrySDR/SoapyRadioberryStreaming.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "SoapyRadioberry.hpp" void SoapyRadioberry::setSampleRate( const int direction, const size_t channel, const double rate ) { @@ -13,25 +14,22 @@ int irate = floor(rate); uint32_t ucom =0x00000004; uint32_t command = 0; - - if (direction == SOAPY_SDR_TX) - { - command = 1; - ucom = 0x00000004; - } - else - { - if (rate < 48001.0) - ucom = 0x00000004; - if (rate > 48000.0 && rate < 96001.0) - ucom = 0x01000004; - if (rate > 96000.0 && rate < 192001.0) - ucom = 0x02000004; - if (rate > 192000.0) - ucom = 0x03000004; - } - - this->SoapyRadioberry::controlRadioberry(command, ucom); + + if (direction == SOAPY_SDR_TX) + command = 0x1; + if (direction == SOAPY_SDR_RX) + sample_rate = rate; + + // incase of transmit still the receive samplerate need to be send + if (sample_rate < 48001.0) + ucom = 0x00000004; + if (sample_rate > 48000.0 && sample_rate < 96001.0) + ucom = 0x01000004; + if (sample_rate > 96000.0 && sample_rate < 192001.0) + ucom = 0x02000004; + if (sample_rate > 192000.0) + ucom = 0x03000004; + this->SoapyRadioberry::controlRadioberry(command, ucom); } SoapySDR::RangeList SoapyRadioberry::getSampleRateRange(const int direction, const size_t channel) const @@ -128,25 +126,23 @@ int SoapyRadioberry::readStream( long long &timeNs, const long timeoutUs ) { - int i; - int iq = 0; - int nr_samples; + int nr_samples, no_bytes, iq=0; void *buff_base = buffs[0]; float *target_buffer = (float *) buff_base; int16_t *itarget_buffer = (int16_t *) buff_base; + int32_t left_sample; + int32_t right_sample; char rx_buffer[512]; for(int ii = 0 ; ii < npackages ; ii++) { - nr_samples = read(fd_rb, rx_buffer, sizeof(rx_buffer)); + 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) { - int32_t left_sample; - int32_t right_sample; - - for (i = 0; i < nr_samples; i += 6) { + for (int i = 0; i < no_bytes; i += 6) { left_sample = (int32_t)((signed char) rx_buffer[i]) << 16; left_sample |= (int32_t)((((unsigned char)rx_buffer[i + 1]) << 8) & 0xFF00); left_sample |= (int32_t)((unsigned char)rx_buffer[i + 2] & 0xFF); @@ -158,14 +154,10 @@ int SoapyRadioberry::readStream( target_buffer[iq++] = (float)left_sample / 8388608.0; // 24 bit sample target_buffer[iq++] = (float)right_sample / 8388608.0; // 24 bit sample } - //printf("nr_samples %d sample: %d %d \n", nr_samples, left_sample, right_sample); } if (streamFormat == RADIOBERRY_SDR_CS16) { - int32_t left_sample; - int32_t right_sample; - - for (i = 0; i < nr_samples; i += 6) { + for (int i = 0; i < no_bytes; i += 6) { left_sample = (int32_t)((signed char) rx_buffer[i]) << 16; left_sample |= (int32_t)((((unsigned char)rx_buffer[i + 1]) << 8) & 0xFF00); left_sample |= (int32_t)((unsigned char)rx_buffer[i + 2] & 0xFF); @@ -178,40 +170,35 @@ int SoapyRadioberry::readStream( itarget_buffer[iq++] = (int16_t)(right_sample >> 8); // 16 bit sample } } + //printf("nr_samples %d sample: %d %d \n", nr_samples, left_sample, right_sample); } - return (npackages * nr_samples / 6); //return the number of IQ samples + return (npackages * nr_samples); //return the number of IQ samples } union uTxBuffer { - std::uint16_t i16TxBuffer[2]; - unsigned char i8TxBuffer[4]; + std::uint16_t i16TxBuffer[2]; + 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; size_t ret; - int left_sample; - int right_sample; int nr_samples; void const *buff_base = buffs[0]; float *target_buffer = (float *) buff_base; int16_t *itarget_buffer = (int16_t *) buff_base; - - - uTxBuffer tx; - + if (streamFormat == RADIOBERRY_SDR_CF32) { for (int ii = 0; ii < numElems; ii++) { - float i, q; - int16_t di, dq; - tx.i16TxBuffer[0] = (int16_t)(target_buffer[iq++] * 16384.0f); - tx.i16TxBuffer[1] = (int16_t)(target_buffer[iq++] * -16384.0f); + tx.i16TxBuffer[1] = (int16_t)(target_buffer[iq++] * 16384.0f); ret = write(fd_rb, &tx, 4 * sizeof(uint8_t)); } } @@ -219,19 +206,18 @@ int SoapyRadioberry::writeStream(SoapySDR::Stream *stream, const void * const *b { int j = 0; - //printf("SoapySDR send %d elements count %d\n", numElems, m_count); for (int ii = 0; ii < numElems; ii++) { - //printf("%x %x %x %x\n", (itarget_buffer[j] & 0xFF00) >> 8, (itarget_buffer[j] & 0x00FF), (itarget_buffer[j+1] & 0xFF00) >> 8, (itarget_buffer[j+1] & 0x00FF)); - tx.i8TxBuffer[0] = (unsigned char)((itarget_buffer[j] & 0xff00) >> 8); tx.i8TxBuffer[1] = (unsigned char)(itarget_buffer[j] & 0xff); tx.i8TxBuffer[2] = (unsigned char)(((-1 * itarget_buffer[j + 1]) & 0xff00) >> 8); - tx.i8TxBuffer[3] = (unsigned char)((-1 * itarget_buffer[j + 1]) & 0xff); - - ret = write(fd_rb, &tx, sizeof(uint32_t)); + tx.i8TxBuffer[3] = (unsigned char)((-1 * itarget_buffer[j + 1]) & 0xff); + + ret = write(fd_rb, &tx, sizeof(uint32_t)); j += 2; } } + if (ret < 0) + SoapySDR_log(SOAPY_SDR_ERROR, "Write error to radioberry driver"); return numElems; } \ No newline at end of file