added synchronous api for reading and writing in cpp api

changed internal complexint to std::complex<short>
fixing_gr_cariboulite
David Michaeli 2024-01-29 22:08:04 +02:00
rodzic 43c505db2d
commit 8ca8b6ac9f
3 zmienionych plików z 158 dodań i 31 usunięć

Wyświetl plik

@ -105,9 +105,15 @@ public:
IntSync = 3,
Int = 4,
};
enum ApiType
{
Async = 0,
Sync = 1,
};
public:
CaribouLiteRadio(const cariboulite_radio_state_st* radio, RadioType type, const CaribouLite* parent = NULL);
CaribouLiteRadio(const cariboulite_radio_state_st* radio, RadioType type, ApiType api_type = Async, const CaribouLite* parent = NULL);
virtual ~CaribouLiteRadio();
// Gain
@ -164,8 +170,9 @@ public:
// Activation
void StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<float>*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk = 0);
void StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<float>*, size_t)> on_data_ready, size_t samples_per_chunk = 0);
void StartReceiving(std::function<void(CaribouLiteRadio*, const CaribouLiteComplexInt*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk = 0);
void StartReceiving(std::function<void(CaribouLiteRadio*, const CaribouLiteComplexInt*, size_t)> on_data_ready, size_t samples_per_chunk = 0);
void StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<short>*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk = 0);
void StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<short>*, size_t)> on_data_ready, size_t samples_per_chunk = 0);
void StartReceiving();
void StartReceivingInternal(size_t samples_per_chunk);
void StopReceiving(void);
void StartTransmitting(std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> on_data_request, size_t samples_per_chunk);
@ -175,6 +182,12 @@ public:
bool GetIsTransmittingLo(void);
bool GetIsTransmittingCw(void);
// Synchronous Reading and Writing
int ReadSamples(std::complex<float>* samples, size_t num_to_read);
int ReadSamples(std::complex<short>* samples, size_t num_to_read);
int WriteSamples(std::complex<float>* samples, size_t num_to_write);
int WriteSamples(std::complex<short>* samples, size_t num_to_write);
// General
size_t GetNativeMtuSample(void);
std::string GetRadioName(void);
@ -190,10 +203,11 @@ private:
std::thread *_rx_thread;
std::function<void(CaribouLiteRadio*, const std::complex<float>*, CaribouLiteMeta*, size_t)> _on_data_ready_fm;
std::function<void(CaribouLiteRadio*, const std::complex<float>*, size_t)> _on_data_ready_f;
std::function<void(CaribouLiteRadio*, const CaribouLiteComplexInt*, CaribouLiteMeta*, size_t)> _on_data_ready_im;
std::function<void(CaribouLiteRadio*, const CaribouLiteComplexInt*, size_t)> _on_data_ready_i;
std::function<void(CaribouLiteRadio*, const std::complex<short>*, CaribouLiteMeta*, size_t)> _on_data_ready_im;
std::function<void(CaribouLiteRadio*, const std::complex<short>*, size_t)> _on_data_ready_i;
size_t _rx_samples_per_chunk;
RxCbType _rxCallbackType;
ApiType _api_type;
bool _tx_thread_running;
bool _tx_is_active;
@ -201,6 +215,10 @@ private:
std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> _on_data_request;
size_t _tx_samples_per_chunk;
// buffers
cariboulite_sample_complex_int16 *_read_samples;
cariboulite_sample_meta* _read_metadata;
private:
static void CaribouLiteRxThread(CaribouLiteRadio* radio);
static void CaribouLiteTxThread(CaribouLiteRadio* radio);
@ -227,7 +245,7 @@ public:
};
protected:
CaribouLite(bool forceFpgaProg = false, LogLevel logLvl = LogLevel::None);
CaribouLite(bool asyncApi = true, bool forceFpgaProg = false, LogLevel logLvl = LogLevel::None);
CaribouLite(const CaribouLite& o) = delete;
void operator=(const CaribouLite&) = delete;
void ReleaseResources(void);
@ -247,7 +265,7 @@ public:
void RegisterSignalHandler(std::function<void(int)> on_signal_caught);
// Static detection and factory
static CaribouLite &GetInstance(bool forceFpgaProg = false, LogLevel logLvl = LogLevel::None);
static CaribouLite &GetInstance(bool asyncApi = true, bool forceFpgaProg = false, LogLevel logLvl = LogLevel::None);
static bool DetectBoard(SysVersion *sysVer, std::string& name, std::string& guid);
static void DefaultSignalHandler(void* context, int signal_number, siginfo_t *si);

Wyświetl plik

@ -37,7 +37,7 @@ bool CaribouLite::DetectBoard(SysVersion *sysVer, std::string& name, std::string
}
//==================================================================
CaribouLite &CaribouLite::GetInstance(bool forceFpgaProg, LogLevel logLvl)
CaribouLite &CaribouLite::GetInstance(bool asyncApi, bool forceFpgaProg, LogLevel logLvl)
{
SysVersion ver;
std::string name, guid;
@ -51,7 +51,7 @@ CaribouLite &CaribouLite::GetInstance(bool forceFpgaProg, LogLevel logLvl)
{
try
{
_instance = std::shared_ptr<CaribouLite>(new CaribouLite(forceFpgaProg, logLvl));
_instance = std::shared_ptr<CaribouLite>(new CaribouLite(forceFpgaProg, asyncApi, logLvl));
}
catch (std::exception& e)
{
@ -62,7 +62,7 @@ CaribouLite &CaribouLite::GetInstance(bool forceFpgaProg, LogLevel logLvl)
}
//==================================================================
CaribouLite::CaribouLite(bool forceFpgaProg, LogLevel logLvl)
CaribouLite::CaribouLite(bool asyncApi, bool forceFpgaProg, LogLevel logLvl)
{
if (cariboulite_init(forceFpgaProg, (cariboulite_log_level_en)logLvl) != 0)
{
@ -75,13 +75,15 @@ CaribouLite::CaribouLite(bool forceFpgaProg, LogLevel logLvl)
// get information
DetectBoard(&_systemVersion, _productName, _productGuid);
CaribouLiteRadio::ApiType api_type = asyncApi ? CaribouLiteRadio::ApiType::Async : CaribouLiteRadio::ApiType::Sync;
// populate the radio devices
cariboulite_radio_state_st *radio_s1g = cariboulite_get_radio(cariboulite_channel_s1g);
CaribouLiteRadio* radio_s1g_int = new CaribouLiteRadio(radio_s1g, CaribouLiteRadio::RadioType::S1G, this);
CaribouLiteRadio* radio_s1g_int = new CaribouLiteRadio(radio_s1g, CaribouLiteRadio::RadioType::S1G, api_type, this);
_channels.push_back(radio_s1g_int);
cariboulite_radio_state_st *radio_hif = cariboulite_get_radio(cariboulite_channel_hif);
CaribouLiteRadio* radio_hif_int = new CaribouLiteRadio(radio_hif, CaribouLiteRadio::RadioType::HiF, this);
CaribouLiteRadio* radio_hif_int = new CaribouLiteRadio(radio_hif, CaribouLiteRadio::RadioType::HiF, api_type, this);
_channels.push_back(radio_hif_int);
}

Wyświetl plik

@ -4,7 +4,7 @@
void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio)
{
size_t mtu_size = radio->GetNativeMtuSample();
CaribouLiteComplexInt* rx_buffer = new CaribouLiteComplexInt[mtu_size];
std::complex<short>* rx_buffer = new std::complex<short>[mtu_size];
CaribouLiteMeta* rx_meta_buffer = new CaribouLiteMeta[mtu_size];
std::complex<float>* rx_copmlex_data = new std::complex<float>[mtu_size];
@ -36,8 +36,8 @@ void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio)
{
for (int i = 0; i < ret; i ++)
{
rx_copmlex_data[i].real(rx_buffer[i].i / 4096.0);
rx_copmlex_data[i].imag(rx_buffer[i].q / 4096.0);
rx_copmlex_data[i].real(rx_buffer[i].real() / 4096.0);
rx_copmlex_data[i].imag(rx_buffer[i].imag() / 4096.0);
}
}
@ -65,6 +65,62 @@ void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio)
delete[]rx_copmlex_data;
}
//==================================================================
int CaribouLiteRadio::ReadSamples(std::complex<float>* samples, size_t num_to_read)
{
int ret = ReadSamples((std::complex<short>*)NULL, num_to_read);
if (ret <= 0)
{
return ret;
}
if (samples)
{
for (size_t i = 0; i < (size_t)ret; i++)
{
samples[i] = {((float)_read_samples[i].i) / 4096.0f, ((float)_read_samples[i].q) / 4096.0f};
}
}
return ret;
}
//==================================================================
int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_read)
{
int ret = cariboulite_radio_read_samples((cariboulite_radio_state_st*)_radio,
_read_samples,
_read_metadata,
num_to_read);
if (ret <= 0)
{
return ret;
}
if (samples)
{
for (size_t i = 0; i < (size_t)ret; i++)
{
samples[i] = {_read_samples[i].i, _read_samples[i].q};
}
}
return ret;
}
//==================================================================
int CaribouLiteRadio::WriteSamples(std::complex<float>* samples, size_t num_to_write)
{
return 0;
}
//==================================================================
int CaribouLiteRadio::WriteSamples(std::complex<short>* samples, size_t num_to_write)
{
return cariboulite_radio_write_samples((cariboulite_radio_state_st*)_radio,
(cariboulite_sample_complex_int16*)samples,
num_to_write);
}
//==================================================================
void CaribouLiteRadio::CaribouLiteTxThread(CaribouLiteRadio* radio)
{
@ -80,14 +136,29 @@ void CaribouLiteRadio::CaribouLiteTxThread(CaribouLiteRadio* radio)
}
//==================================================================
CaribouLiteRadio::CaribouLiteRadio(const cariboulite_radio_state_st* radio, RadioType type, const CaribouLite* parent)
: _radio(radio), _device(parent), _type(type), _rxCallbackType(RxCbType::None)
CaribouLiteRadio::CaribouLiteRadio( const cariboulite_radio_state_st* radio,
RadioType type,
ApiType api_type,
const CaribouLite* parent)
: _radio(radio), _device(parent), _type(type), _rxCallbackType(RxCbType::None), _api_type(api_type)
{
_rx_thread_running = true;
_rx_thread = new std::thread(CaribouLiteRadio::CaribouLiteRxThread, this);
_tx_thread_running = true;
_tx_thread = new std::thread(CaribouLiteRadio::CaribouLiteTxThread, this);
if (_api_type == Async)
{
_rx_thread_running = true;
_rx_thread = new std::thread(CaribouLiteRadio::CaribouLiteRxThread, this);
_tx_thread_running = true;
_tx_thread = new std::thread(CaribouLiteRadio::CaribouLiteTxThread, this);
}
else
{
_read_samples = NULL;
_read_metadata = NULL;
size_t mtu_size = GetNativeMtuSample();
// allocate internal buffers
_read_samples = new cariboulite_sample_complex_int16[mtu_size];
_read_metadata = new cariboulite_sample_meta[mtu_size];
}
}
//==================================================================
@ -97,13 +168,21 @@ CaribouLiteRadio::~CaribouLiteRadio()
StopReceiving();
StopTransmitting();
_rx_thread_running = false;
_rx_thread->join();
if (_rx_thread) delete _rx_thread;
_tx_thread_running = false;
_tx_thread->join();
if (_tx_thread) delete _tx_thread;
if (_api_type == Async)
{
_rx_thread_running = false;
_rx_thread->join();
if (_rx_thread) delete _rx_thread;
_tx_thread_running = false;
_tx_thread->join();
if (_tx_thread) delete _tx_thread;
}
else
{
if (_read_samples) delete [] _read_samples;
if (_read_metadata) delete [] _read_metadata;
}
}
// Gain
@ -426,6 +505,11 @@ void CaribouLiteRadio::StartReceivingInternal(size_t samples_per_chunk)
//==================================================================
void CaribouLiteRadio::StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<float>*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk)
{
if (_api_type == CaribouLiteRadio::ApiType::Sync)
{
StartReceiving();
return;
}
_on_data_ready_fm = on_data_ready;
_rxCallbackType = RxCbType::FloatSync;
StartReceivingInternal(samples_per_chunk);
@ -434,27 +518,50 @@ void CaribouLiteRadio::StartReceiving(std::function<void(CaribouLiteRadio*, cons
//==================================================================
void CaribouLiteRadio::StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<float>*, size_t)> on_data_ready, size_t samples_per_chunk)
{
if (_api_type == CaribouLiteRadio::ApiType::Sync)
{
StartReceiving();
return;
}
_on_data_ready_f = on_data_ready;
_rxCallbackType = RxCbType::Float;
StartReceivingInternal(samples_per_chunk);
}
//==================================================================
void CaribouLiteRadio::StartReceiving(std::function<void(CaribouLiteRadio*, const CaribouLiteComplexInt*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk)
void CaribouLiteRadio::StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<short>*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk)
{
if (_api_type == CaribouLiteRadio::ApiType::Sync)
{
StartReceiving();
return;
}
_on_data_ready_im = on_data_ready;
_rxCallbackType = RxCbType::IntSync;
StartReceivingInternal(samples_per_chunk);
}
//==================================================================
void CaribouLiteRadio::StartReceiving(std::function<void(CaribouLiteRadio*, const CaribouLiteComplexInt*, size_t)> on_data_ready, size_t samples_per_chunk)
void CaribouLiteRadio::StartReceiving(std::function<void(CaribouLiteRadio*, const std::complex<short>*, size_t)> on_data_ready, size_t samples_per_chunk)
{
if (_api_type == CaribouLiteRadio::ApiType::Sync)
{
StartReceiving();
return;
}
_on_data_ready_i = on_data_ready;
_rxCallbackType = RxCbType::Int;
StartReceivingInternal(samples_per_chunk);
}
//==================================================================
void CaribouLiteRadio::StartReceiving()
{
_on_data_ready_im = nullptr;
_rxCallbackType = RxCbType::None;
StartReceivingInternal(0);
}
//==================================================================
void CaribouLiteRadio::StopReceiving()
{