kopia lustrzana https://github.com/pa3gsb/Radioberry-2.x
Merge pull request #26 from paulh002/master
update TX sampling rate and fix thread issuepull/27/head
commit
c2d5c83ad4
|
@ -8,7 +8,8 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <mutex>
|
||||||
#include "radioberry_ioctl.h"
|
#include "radioberry_ioctl.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
|
@ -137,12 +138,13 @@ class SoapyRadioberry : public SoapySDR::Device{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int fd_rb;
|
int fd_rb;
|
||||||
int sample_rate;
|
double sample_rate;
|
||||||
int rx_frequency;
|
int rx_frequency;
|
||||||
int no_channels;
|
int no_channels;
|
||||||
struct rb_info_arg_t rb_control;
|
struct rb_info_arg_t rb_control;
|
||||||
std::unique_ptr<rpihw::driver::i2c> i2c_ptr;
|
std::unique_ptr<rpihw::driver::i2c> i2c_ptr;
|
||||||
bool i2c_available = false;
|
bool i2c_available = false;
|
||||||
radioberrysdrStreamFormat streamFormat;
|
radioberrysdrStreamFormat streamFormat;
|
||||||
|
std::mutex send_command;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#include "SoapyRadioberry.hpp"
|
#include "SoapyRadioberry.hpp"
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#define RADIOBERRY_BUFFER_SIZE 4096
|
#define RADIOBERRY_BUFFER_SIZE 4096
|
||||||
|
|
||||||
|
@ -7,7 +10,8 @@
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
SoapyRadioberry::SoapyRadioberry( const SoapySDR::Kwargs &args ){
|
SoapyRadioberry::SoapyRadioberry( const SoapySDR::Kwargs &args ){
|
||||||
|
|
||||||
|
SoapySDR_setLogLevel(SOAPY_SDR_INFO);
|
||||||
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::SoapyRadioberry constructor called");
|
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::SoapyRadioberry constructor called");
|
||||||
|
|
||||||
no_channels = 1;
|
no_channels = 1;
|
||||||
|
@ -21,7 +25,7 @@ SoapyRadioberry::SoapyRadioberry( const SoapySDR::Kwargs &args ){
|
||||||
{
|
{
|
||||||
printf("I2c not found %s", s.c_str());
|
printf("I2c not found %s", s.c_str());
|
||||||
i2c_available = false;
|
i2c_available = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SoapyRadioberry::~SoapyRadioberry(void){
|
SoapyRadioberry::~SoapyRadioberry(void){
|
||||||
|
@ -32,7 +36,8 @@ SoapyRadioberry::~SoapyRadioberry(void){
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoapyRadioberry::controlRadioberry(uint32_t command, uint32_t command_data) {
|
void SoapyRadioberry::controlRadioberry(uint32_t command, uint32_t command_data) {
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> soapy_lock(send_command);
|
||||||
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::controlRadioberry called");
|
SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::controlRadioberry called");
|
||||||
|
|
||||||
uint32_t CWX =0;
|
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.rb_command = 0x04 | (((CWX << 1) & 0x02) | (running & 0x01));
|
||||||
rb_control.command = command;
|
rb_control.command = command;
|
||||||
rb_control.command_data = command_data;
|
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) {
|
if (ioctl(fd_rb, RADIOBERRY_IOC_COMMAND, &rb_control) == -1) {
|
||||||
SoapySDR_log(SOAPY_SDR_INFO, "Could not sent command to radioberry device.");
|
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_log(SOAPY_SDR_INFO, "SoapyRadioberry::getHardwareInfo called");
|
||||||
|
|
||||||
SoapySDR::Kwargs info;
|
SoapySDR::Kwargs info;
|
||||||
|
int count = 0;
|
||||||
struct rb_info_arg_t rb_info;
|
struct rb_info_arg_t rb_info;
|
||||||
|
|
||||||
if (ioctl(fd_rb, RADIOBERRY_IOC_COMMAND, &rb_info) == -1) {
|
do
|
||||||
rb_info.major = 0;
|
{
|
||||||
rb_info.minor = 0;
|
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;
|
unsigned int major, minor;
|
||||||
major = rb_info.major;
|
major = rb_info.major;
|
||||||
|
@ -256,7 +268,7 @@ void SoapyRadioberry::setFrequency( const int direction, const size_t channel,
|
||||||
uint32_t command = 0;
|
uint32_t command = 0;
|
||||||
|
|
||||||
if(direction==SOAPY_SDR_RX) command = 4;
|
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;
|
uint32_t command_data = (uint32_t) frequency;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
#include "SoapyRadioberry.hpp"
|
#include "SoapyRadioberry.hpp"
|
||||||
|
|
||||||
void SoapyRadioberry::setSampleRate( const int direction, const size_t channel, const double rate ) {
|
void SoapyRadioberry::setSampleRate( const int direction, const size_t channel, const double rate ) {
|
||||||
|
@ -13,25 +14,22 @@
|
||||||
int irate = floor(rate);
|
int irate = floor(rate);
|
||||||
uint32_t ucom =0x00000004;
|
uint32_t ucom =0x00000004;
|
||||||
uint32_t command = 0;
|
uint32_t command = 0;
|
||||||
|
|
||||||
if (direction == SOAPY_SDR_TX)
|
if (direction == SOAPY_SDR_TX)
|
||||||
{
|
command = 0x1;
|
||||||
command = 1;
|
if (direction == SOAPY_SDR_RX)
|
||||||
ucom = 0x00000004;
|
sample_rate = rate;
|
||||||
}
|
|
||||||
else
|
// incase of transmit still the receive samplerate need to be send
|
||||||
{
|
if (sample_rate < 48001.0)
|
||||||
if (rate < 48001.0)
|
ucom = 0x00000004;
|
||||||
ucom = 0x00000004;
|
if (sample_rate > 48000.0 && sample_rate < 96001.0)
|
||||||
if (rate > 48000.0 && rate < 96001.0)
|
ucom = 0x01000004;
|
||||||
ucom = 0x01000004;
|
if (sample_rate > 96000.0 && sample_rate < 192001.0)
|
||||||
if (rate > 96000.0 && rate < 192001.0)
|
ucom = 0x02000004;
|
||||||
ucom = 0x02000004;
|
if (sample_rate > 192000.0)
|
||||||
if (rate > 192000.0)
|
ucom = 0x03000004;
|
||||||
ucom = 0x03000004;
|
this->SoapyRadioberry::controlRadioberry(command, ucom);
|
||||||
}
|
|
||||||
|
|
||||||
this->SoapyRadioberry::controlRadioberry(command, ucom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SoapySDR::RangeList SoapyRadioberry::getSampleRateRange(const int direction, const size_t channel) const
|
SoapySDR::RangeList SoapyRadioberry::getSampleRateRange(const int direction, const size_t channel) const
|
||||||
|
@ -128,25 +126,23 @@ int SoapyRadioberry::readStream(
|
||||||
long long &timeNs,
|
long long &timeNs,
|
||||||
const long timeoutUs )
|
const long timeoutUs )
|
||||||
{
|
{
|
||||||
int i;
|
int nr_samples, no_bytes, iq=0;
|
||||||
int iq = 0;
|
|
||||||
int nr_samples;
|
|
||||||
|
|
||||||
void *buff_base = buffs[0];
|
void *buff_base = buffs[0];
|
||||||
float *target_buffer = (float *) buff_base;
|
float *target_buffer = (float *) buff_base;
|
||||||
int16_t *itarget_buffer = (int16_t *) buff_base;
|
int16_t *itarget_buffer = (int16_t *) buff_base;
|
||||||
|
int32_t left_sample;
|
||||||
|
int32_t right_sample;
|
||||||
|
|
||||||
char rx_buffer[512];
|
char rx_buffer[512];
|
||||||
for(int ii = 0 ; ii < npackages ; ii++)
|
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]);
|
//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(streamFormat == RADIOBERRY_SDR_CF32)
|
||||||
{
|
{
|
||||||
int32_t left_sample;
|
for (int i = 0; i < no_bytes; i += 6) {
|
||||||
int32_t right_sample;
|
|
||||||
|
|
||||||
for (i = 0; i < nr_samples; i += 6) {
|
|
||||||
left_sample = (int32_t)((signed char) rx_buffer[i]) << 16;
|
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 + 1]) << 8) & 0xFF00);
|
||||||
left_sample |= (int32_t)((unsigned char)rx_buffer[i + 2] & 0xFF);
|
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)left_sample / 8388608.0; // 24 bit sample
|
||||||
target_buffer[iq++] = (float)right_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)
|
if (streamFormat == RADIOBERRY_SDR_CS16)
|
||||||
{
|
{
|
||||||
int32_t left_sample;
|
for (int i = 0; i < no_bytes; i += 6) {
|
||||||
int32_t right_sample;
|
|
||||||
|
|
||||||
for (i = 0; i < nr_samples; i += 6) {
|
|
||||||
left_sample = (int32_t)((signed char) rx_buffer[i]) << 16;
|
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 + 1]) << 8) & 0xFF00);
|
||||||
left_sample |= (int32_t)((unsigned char)rx_buffer[i + 2] & 0xFF);
|
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
|
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
|
union uTxBuffer
|
||||||
{
|
{
|
||||||
std::uint16_t i16TxBuffer[2];
|
std::uint16_t i16TxBuffer[2];
|
||||||
unsigned char i8TxBuffer[4];
|
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 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;
|
int iq = 0;
|
||||||
size_t ret;
|
size_t ret;
|
||||||
int left_sample;
|
|
||||||
int right_sample;
|
|
||||||
int nr_samples;
|
int nr_samples;
|
||||||
|
|
||||||
void const *buff_base = buffs[0];
|
void const *buff_base = buffs[0];
|
||||||
float *target_buffer = (float *) buff_base;
|
float *target_buffer = (float *) buff_base;
|
||||||
int16_t *itarget_buffer = (int16_t *) buff_base;
|
int16_t *itarget_buffer = (int16_t *) buff_base;
|
||||||
|
|
||||||
|
|
||||||
uTxBuffer tx;
|
|
||||||
|
|
||||||
if (streamFormat == RADIOBERRY_SDR_CF32)
|
if (streamFormat == RADIOBERRY_SDR_CF32)
|
||||||
{
|
{
|
||||||
for (int ii = 0; ii < numElems; ii++)
|
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[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));
|
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;
|
int j = 0;
|
||||||
|
|
||||||
//printf("SoapySDR send %d elements count %d\n", numElems, m_count);
|
|
||||||
for (int ii = 0; ii < numElems; ii++)
|
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[0] = (unsigned char)((itarget_buffer[j] & 0xff00) >> 8);
|
||||||
tx.i8TxBuffer[1] = (unsigned char)(itarget_buffer[j] & 0xff);
|
tx.i8TxBuffer[1] = (unsigned char)(itarget_buffer[j] & 0xff);
|
||||||
tx.i8TxBuffer[2] = (unsigned char)(((-1 * itarget_buffer[j + 1]) & 0xff00) >> 8);
|
tx.i8TxBuffer[2] = (unsigned char)(((-1 * itarget_buffer[j + 1]) & 0xff00) >> 8);
|
||||||
tx.i8TxBuffer[3] = (unsigned char)((-1 * itarget_buffer[j + 1]) & 0xff);
|
tx.i8TxBuffer[3] = (unsigned char)((-1 * itarget_buffer[j + 1]) & 0xff);
|
||||||
|
|
||||||
ret = write(fd_rb, &tx, sizeof(uint32_t));
|
ret = write(fd_rb, &tx, sizeof(uint32_t));
|
||||||
j += 2;
|
j += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
SoapySDR_log(SOAPY_SDR_ERROR, "Write error to radioberry driver");
|
||||||
return numElems;
|
return numElems;
|
||||||
}
|
}
|
Ładowanie…
Reference in New Issue