2023-10-01 18:39:04 +00:00
|
|
|
/**
|
|
|
|
* @file CaribouLite.hpp
|
|
|
|
* @author David Michaeli
|
|
|
|
* @date September 2023
|
|
|
|
* @brief Main Init/Close API
|
|
|
|
*
|
|
|
|
* A high level CPP API for CaribouLite
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef __CARIBOULITE_HPP__
|
|
|
|
#define __CARIBOULITE_HPP__
|
|
|
|
|
|
|
|
#include <cariboulite.h>
|
|
|
|
#include <cariboulite_radio.h>
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <complex>
|
|
|
|
#include <cstddef>
|
|
|
|
#include <ostream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <thread>
|
2023-10-21 10:34:18 +00:00
|
|
|
#include <memory>
|
2023-10-01 18:39:04 +00:00
|
|
|
#include <mutex>
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
#if __cplusplus <= 199711L
|
|
|
|
#error This file needs at least a C++11 compliant compiler, try using:
|
|
|
|
#error $ g++ -std=c++11 ..
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief CaribouLite API Version
|
|
|
|
*/
|
|
|
|
class CaribouLiteVersion
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CaribouLiteVersion(int v, int sv, int rev) {_ver.major_version = v; _ver.minor_version = sv; _ver.revision = rev;}
|
|
|
|
virtual ~CaribouLiteVersion() {}
|
|
|
|
|
|
|
|
friend std::ostream& operator<<(std::ostream& os, const CaribouLiteVersion& c)
|
|
|
|
{
|
|
|
|
os << c._ver.major_version << '.' << c._ver.minor_version << '/' << c._ver.revision;
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
cariboulite_lib_version_st _ver;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief CaribouLite Frequency Range
|
|
|
|
*/
|
|
|
|
class CaribouLiteFreqRange
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CaribouLiteFreqRange(float min_hz, float max_hz) : _fMin(min_hz), _fMax(max_hz) {}
|
|
|
|
virtual ~CaribouLiteFreqRange() {}
|
|
|
|
friend std::ostream& operator<<(std::ostream& os, const CaribouLiteFreqRange& r)
|
|
|
|
{
|
|
|
|
os << "[" << r._fMin << ',' << r._fMax << ']';
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
float _fMin, _fMax;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief CaribouLite Radio Channel
|
|
|
|
*/
|
2023-10-01 22:55:52 +00:00
|
|
|
#pragma pack(1)
|
|
|
|
struct CaribouLiteComplexInt
|
|
|
|
{
|
|
|
|
int16_t i;
|
|
|
|
int16_t q;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CaribouLiteMeta
|
|
|
|
{
|
|
|
|
uint8_t sync;
|
|
|
|
};
|
|
|
|
#pragma pack()
|
|
|
|
|
2023-10-01 18:39:04 +00:00
|
|
|
class CaribouLite;
|
|
|
|
class CaribouLiteRadio
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum RadioType
|
|
|
|
{
|
|
|
|
S1G = 0,
|
|
|
|
HiF = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum RadioDir
|
|
|
|
{
|
|
|
|
Rx = 0,
|
|
|
|
Tx = 1,
|
|
|
|
};
|
|
|
|
|
2023-10-01 22:55:52 +00:00
|
|
|
enum RxCbType
|
|
|
|
{
|
|
|
|
None = 0,
|
|
|
|
FloatSync = 1,
|
|
|
|
Float = 2,
|
|
|
|
IntSync = 3,
|
|
|
|
Int = 4,
|
|
|
|
};
|
|
|
|
|
2023-10-01 18:39:04 +00:00
|
|
|
public:
|
|
|
|
CaribouLiteRadio(const cariboulite_radio_state_st* radio, RadioType type, const CaribouLite* parent = NULL);
|
|
|
|
virtual ~CaribouLiteRadio();
|
|
|
|
|
|
|
|
// Gain
|
|
|
|
void SetAgc(bool agc_on);
|
|
|
|
bool GetAgc(void);
|
|
|
|
float GetRxGainMin(void);
|
|
|
|
float GetRxGainMax(void);
|
|
|
|
float GetRxGainSteps(void);
|
|
|
|
void SetRxGain(float gain);
|
|
|
|
float GetRxGain(void);
|
|
|
|
|
|
|
|
// Tx Power
|
|
|
|
float GetTxPowerMin(void);
|
|
|
|
float GetTxPowerMax(void);
|
|
|
|
float GetTxPowerStep(void);
|
|
|
|
void SetTxPower(float pwr_dBm);
|
|
|
|
float GetTxPower(void);
|
|
|
|
|
|
|
|
// Rx Bandwidth
|
|
|
|
float GetRxBandwidthMin(void);
|
|
|
|
float GetRxBandwidthMax(void);
|
|
|
|
void SetRxBandwidth(float bw_hz);
|
|
|
|
float GetRxBandwidth(void);
|
|
|
|
|
|
|
|
// Tx Bandwidth
|
|
|
|
float GetTxBandwidthMin(void);
|
|
|
|
float GetTxBandwidthMax(void);
|
|
|
|
void SetTxBandwidth(float bw_hz);
|
|
|
|
float GetTxBandwidth(void);
|
|
|
|
|
|
|
|
// Rx Sample Rate
|
|
|
|
float GetRxSampleRateMin(void);
|
|
|
|
float GetRxSampleRateMax(void);
|
|
|
|
void SetRxSampleRate(float sr_hz);
|
|
|
|
float GetRxSampleRate(void);
|
|
|
|
|
|
|
|
// Tx Sample Rate
|
|
|
|
float GetTxSampleRateMin(void);
|
|
|
|
float GetTxSampleRateMax(void);
|
|
|
|
void SetTxSampleRate(float sr_hz);
|
|
|
|
float GetTxSampleRate(void);
|
|
|
|
|
|
|
|
// RSSI and Rx Power and others
|
|
|
|
float GetRssi(void);
|
|
|
|
float GetEnergyDet(void);
|
|
|
|
unsigned char GetTrueRandVal(void);
|
|
|
|
|
|
|
|
// Frequency Control
|
|
|
|
void SetFrequency(float freq_hz);
|
|
|
|
float GetFrequency(void);
|
|
|
|
std::vector<CaribouLiteFreqRange> GetFrequencyRange(void);
|
|
|
|
float GetFrequencyResolution(void);
|
|
|
|
|
|
|
|
// Activation
|
2023-10-01 23:19:11 +00:00
|
|
|
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);
|
2023-10-01 22:55:52 +00:00
|
|
|
void StartReceivingInternal(size_t samples_per_chunk);
|
2023-10-01 18:39:04 +00:00
|
|
|
void StopReceiving(void);
|
|
|
|
void StartTransmitting(std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> on_data_request, size_t samples_per_chunk);
|
|
|
|
void StartTransmittingLo(void);
|
|
|
|
void StartTransmittingCw(void);
|
|
|
|
void StopTransmitting(void);
|
|
|
|
bool GetIsTransmittingLo(void);
|
2024-01-21 12:09:51 +00:00
|
|
|
bool GetIsTransmittingCw(void);
|
2023-10-01 18:39:04 +00:00
|
|
|
|
|
|
|
// General
|
|
|
|
size_t GetNativeMtuSample(void);
|
|
|
|
std::string GetRadioName(void);
|
2024-01-21 12:09:51 +00:00
|
|
|
void FlushBuffers(void);
|
2023-10-01 18:39:04 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
const cariboulite_radio_state_st* _radio;
|
|
|
|
const CaribouLite* _device;
|
|
|
|
const RadioType _type;
|
|
|
|
|
|
|
|
bool _rx_thread_running;
|
|
|
|
bool _rx_is_active;
|
|
|
|
std::thread *_rx_thread;
|
2023-10-01 22:55:52 +00:00
|
|
|
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;
|
2023-10-01 18:39:04 +00:00
|
|
|
size_t _rx_samples_per_chunk;
|
2023-10-01 22:55:52 +00:00
|
|
|
RxCbType _rxCallbackType;
|
2023-10-01 18:39:04 +00:00
|
|
|
|
|
|
|
bool _tx_thread_running;
|
|
|
|
bool _tx_is_active;
|
|
|
|
std::thread *_tx_thread;
|
|
|
|
std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> _on_data_request;
|
|
|
|
size_t _tx_samples_per_chunk;
|
|
|
|
|
|
|
|
private:
|
|
|
|
static void CaribouLiteRxThread(CaribouLiteRadio* radio);
|
|
|
|
static void CaribouLiteTxThread(CaribouLiteRadio* radio);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief CaribouLite Device
|
|
|
|
*/
|
|
|
|
class CaribouLite
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum LogLevel
|
|
|
|
{
|
|
|
|
Verbose,
|
|
|
|
Info,
|
|
|
|
None,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum SysVersion
|
|
|
|
{
|
|
|
|
Unknown = 0,
|
|
|
|
CaribouLiteFull = 1,
|
|
|
|
CaribouLiteISM = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
CaribouLite(bool forceFpgaProg = false, LogLevel logLvl = LogLevel::None);
|
|
|
|
CaribouLite(const CaribouLite& o) = delete;
|
|
|
|
void operator=(const CaribouLite&) = delete;
|
2023-10-01 22:55:52 +00:00
|
|
|
void ReleaseResources(void);
|
2023-10-01 18:39:04 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
~CaribouLite();
|
|
|
|
bool IsInitialized(void);
|
|
|
|
CaribouLiteVersion GetApiVersion(void);
|
|
|
|
unsigned int GetHwSerialNumber(void);
|
|
|
|
SysVersion GetSystemVersion(void);
|
|
|
|
std::string GetSystemVersionStr(void);
|
|
|
|
static std::string GetSystemVersionStr(SysVersion v);
|
|
|
|
std::string GetHwGuid(void);
|
|
|
|
CaribouLiteRadio* GetRadioChannel(CaribouLiteRadio::RadioType ch);
|
|
|
|
|
2024-01-29 14:24:13 +00:00
|
|
|
// Signal Handler
|
|
|
|
void RegisterSignalHandler(std::function<void(int)> on_signal_caught);
|
|
|
|
|
2024-01-29 13:50:45 +00:00
|
|
|
// Static detection and factory
|
2023-10-01 18:39:04 +00:00
|
|
|
static CaribouLite &GetInstance(bool forceFpgaProg = false, LogLevel logLvl = LogLevel::None);
|
|
|
|
static bool DetectBoard(SysVersion *sysVer, std::string& name, std::string& guid);
|
2023-10-01 22:55:52 +00:00
|
|
|
static void DefaultSignalHandler(void* context, int signal_number, siginfo_t *si);
|
2023-10-01 18:39:04 +00:00
|
|
|
|
2024-01-29 08:50:06 +00:00
|
|
|
// IO Control
|
|
|
|
void SetLed0States (bool state);
|
|
|
|
bool GetLed0States (void);
|
|
|
|
void SetLed1States (bool state);
|
|
|
|
bool GetLed1States (void);
|
|
|
|
bool GetButtonState (void);
|
|
|
|
void SetPmodState (uint8_t val);
|
|
|
|
uint8_t GetPmodState (void);
|
|
|
|
|
2023-10-01 18:39:04 +00:00
|
|
|
private:
|
2024-01-29 14:24:13 +00:00
|
|
|
std::function<void(int)> _on_signal_caught;
|
2023-10-01 18:39:04 +00:00
|
|
|
std::vector<CaribouLiteRadio*> _channels;
|
|
|
|
SysVersion _systemVersion;
|
|
|
|
std::string _productName;
|
|
|
|
std::string _productGuid;
|
|
|
|
|
|
|
|
static std::shared_ptr<CaribouLite> _instance;
|
|
|
|
static std::mutex _instMutex;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // __CARIBOULITE_HPP__
|