/** * @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 #include #include #include #include #include #include #include #include #include #include #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 */ #pragma pack(1) struct CaribouLiteComplexInt { int16_t i; int16_t q; }; struct CaribouLiteMeta { uint8_t sync; }; #pragma pack() class CaribouLite; class CaribouLiteRadio { public: enum RadioType { S1G = 0, HiF = 1, }; enum RadioDir { Rx = 0, Tx = 1, }; enum RxCbType { None = 0, FloatSync = 1, Float = 2, IntSync = 3, Int = 4, }; enum ApiType { Async = 0, Sync = 1, }; public: CaribouLiteRadio(const cariboulite_radio_state_st* radio, RadioType type, ApiType api_type = Async, 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 GetFrequencyRange(void); float GetFrequencyResolution(void); // Activation void StartReceiving(std::function*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk = 0); void StartReceiving(std::function*, size_t)> on_data_ready, size_t samples_per_chunk = 0); void StartReceiving(std::function*, CaribouLiteMeta*, size_t)> on_data_ready, size_t samples_per_chunk = 0); void StartReceiving(std::function*, 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(void); void StartTransmittingLo(void); void StartTransmittingCw(void); void StopTransmitting(void); bool GetIsTransmittingLo(void); bool GetIsTransmittingCw(void); // Synchronous Reading and Writing int ReadSamples(std::complex* samples, size_t num_to_read, uint8_t* meta = NULL); int ReadSamples(std::complex* samples, size_t num_to_read, uint8_t* meta = NULL); int WriteSamples(std::complex* samples, size_t num_to_write); int WriteSamples(std::complex* samples, size_t num_to_write); // General size_t GetNativeMtuSample(void); std::string GetRadioName(void); void FlushBuffers(void); private: const cariboulite_radio_state_st* _radio; const CaribouLite* _device; const RadioType _type; // Rx information bool _rx_thread_running; bool _rx_is_active; std::thread *_rx_thread; std::function*, CaribouLiteMeta*, size_t)> _on_data_ready_fm; std::function*, size_t)> _on_data_ready_f; std::function*, CaribouLiteMeta*, size_t)> _on_data_ready_im; std::function*, size_t)> _on_data_ready_i; size_t _rx_samples_per_chunk; RxCbType _rxCallbackType; ApiType _api_type; // Tx information bool _tx_is_active; // buffers cariboulite_sample_complex_int16 *_read_samples; std::complex *_write_samples; cariboulite_sample_meta* _read_metadata; 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 asyncApi = true, bool forceFpgaProg = false, LogLevel logLvl = LogLevel::None); CaribouLite(const CaribouLite& o) = delete; void operator=(const CaribouLite&) = delete; void ReleaseResources(void); 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); // Signal Handler void RegisterSignalHandler(std::function on_signal_caught); // Static detection and factory 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); // 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); private: std::function _on_signal_caught; std::vector _channels; SysVersion _systemVersion; std::string _productName; std::string _productGuid; static std::shared_ptr _instance; static std::mutex _instMutex; }; #endif // __CARIBOULITE_HPP__