kopia lustrzana https://github.com/cariboulabs/cariboulite
Porównaj commity
11 Commity
c0a3daf595
...
ffbd7afee8
Autor | SHA1 | Data |
---|---|---|
David Michaeli | ffbd7afee8 | |
David Michaeli | 1b34c568ff | |
David Michaeli | 21a97334a7 | |
David Michaeli | f8793a7ffe | |
David Michaeli | 96828b4bcc | |
David Michaeli | 80faa75c1f | |
matteo serva | 4577e41b61 | |
matteo serva | 26fe48f53d | |
matteo serva | baccfb4805 | |
matteo serva | 7c6f853dc1 | |
matteo serva | 75d25800bc |
|
@ -15,7 +15,7 @@ USERSPACE_SMI_DIR="../software/libcariboulite/src/caribou_smi/kernel"
|
|||
|
||||
## FUNCTIONS
|
||||
install() {
|
||||
local mtu_mult=${1:-6}
|
||||
local mtu_mult=${1:-16}
|
||||
local dir_offs=${2:-2}
|
||||
local ch_offs=${3:-3}
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -12,30 +12,30 @@ int main ()
|
|||
// board detection
|
||||
bool detected = cariboulite_detect_connected_board(&hw_ver, hw_name, hw_uuid);
|
||||
if (detected) printf("Detection: %d, HWVer: %d, HWName: %s, UUID: %s\n", detected, hw_ver, hw_name, hw_uuid);
|
||||
else
|
||||
else
|
||||
{
|
||||
printf("No board detection, Exiting\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// library version
|
||||
cariboulite_get_lib_version(&version);
|
||||
printf("Version: %02d.%02d.%02d\n", version.major_version, version.minor_version, version.revision);
|
||||
|
||||
|
||||
// init
|
||||
cariboulite_init(false, cariboulite_log_level_none);
|
||||
|
||||
cariboulite_init(false, cariboulite_log_level_none);
|
||||
|
||||
// board serial number
|
||||
serial_number = cariboulite_get_sn();
|
||||
printf("Serial Number: %08X\n", serial_number);
|
||||
|
||||
|
||||
// channels names and freqs
|
||||
char ch_name[64];
|
||||
int ch_num_ranges;
|
||||
float low_freq_vec[3]; // the actual size determined by ch_num_ranges but here we just statically allocated
|
||||
float high_freq_vec[3];
|
||||
int channels[2] = {cariboulite_channel_s1g, cariboulite_channel_hif};
|
||||
|
||||
|
||||
for (int ch_ind = 0; ch_ind < 2; ch_ind ++)
|
||||
{
|
||||
cariboulite_get_channel_name(channels[ch_ind], ch_name, sizeof(ch_name));
|
||||
|
@ -43,11 +43,10 @@ int main ()
|
|||
printf("Channel: %d, Name: %s, Num. Freq. Ranges: %d\n", channels[ch_ind], ch_name, ch_num_ranges);
|
||||
cariboulite_get_frequency_limits(channels[ch_ind], low_freq_vec, high_freq_vec, NULL);
|
||||
for (int i = 0; i < ch_num_ranges; i++)
|
||||
{
|
||||
{
|
||||
printf(" Range %d: [%.2f, %.2f]\n", i, low_freq_vec[i], high_freq_vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
cariboulite_close();
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
|
@ -21,7 +21,7 @@ void detectBoard()
|
|||
CaribouLite::SysVersion ver;
|
||||
std::string name;
|
||||
std::string guid;
|
||||
|
||||
|
||||
if (CaribouLite::DetectBoard(&ver, name, guid))
|
||||
{
|
||||
std::cout << "Detected Version: " << CaribouLite::GetSystemVersionStr(ver) << ", Name: " << name << ", GUID: " << guid << std::endl;
|
||||
|
@ -29,21 +29,21 @@ void detectBoard()
|
|||
else
|
||||
{
|
||||
std::cout << "Undetected CaribouLite!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the RSSI
|
||||
float RSSI(const std::complex<float>* signal, size_t num_of_samples)
|
||||
{
|
||||
if (num_of_samples == 0)
|
||||
if (num_of_samples == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float sum_of_squares = 0.0f;
|
||||
for (size_t i = 0; i < num_of_samples && i < num_of_samples; ++i)
|
||||
for (size_t i = 0; i < num_of_samples && i < num_of_samples; ++i)
|
||||
{
|
||||
float vrms = std::norm(signal[i]);
|
||||
float vrms = std::norm(signal[i]);
|
||||
sum_of_squares += vrms * vrms / 100.0;
|
||||
}
|
||||
|
||||
|
@ -61,10 +61,9 @@ void receivedSamples(CaribouLiteRadio* radio, const std::complex<float>* samples
|
|||
std::cout << "[" << samples[i].real() << ", " << samples[i].imag() << "]";
|
||||
}
|
||||
std::cout << std::endl;*/
|
||||
|
||||
|
||||
std::cout << "Radio: " << radio->GetRadioName() << " Received " << std::dec << num_samples << " samples"
|
||||
<< "RSSI: " << RSSI(samples, num_samples) << " dBm" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,21 +72,21 @@ int main ()
|
|||
{
|
||||
// try detecting the board before getting the instance
|
||||
detectBoard();
|
||||
|
||||
|
||||
// get driver instance - use "CaribouLite&" rather than "CaribouLite" (ref)
|
||||
CaribouLite &cl = CaribouLite::GetInstance();
|
||||
|
||||
|
||||
// print the info after connecting
|
||||
printInfo(cl);
|
||||
|
||||
|
||||
// get the radios
|
||||
CaribouLiteRadio *s1g = cl.GetRadioChannel(CaribouLiteRadio::RadioType::S1G);
|
||||
CaribouLiteRadio *hif = cl.GetRadioChannel(CaribouLiteRadio::RadioType::HiF);
|
||||
|
||||
|
||||
// write radio information
|
||||
std::cout << "First Radio Name: " << s1g->GetRadioName() << " MtuSize: " << std::dec << s1g->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
std::cout << "First Radio Name: " << hif->GetRadioName() << " MtuSize: " << std::dec << hif->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
|
||||
|
||||
std::vector<CaribouLiteFreqRange> range_s1g = s1g->GetFrequencyRange();
|
||||
std::vector<CaribouLiteFreqRange> range_hif = hif->GetFrequencyRange();
|
||||
std::cout << "S1G Frequency Regions:" << std::endl;
|
||||
|
@ -95,13 +94,13 @@ int main ()
|
|||
{
|
||||
std::cout << " " << i << ": " << range_s1g[i] << std::endl;
|
||||
}
|
||||
|
||||
|
||||
std::cout << "HiF Frequency Regions:" << std::endl;
|
||||
for (int i = 0; i < range_hif.size(); i++)
|
||||
{
|
||||
std::cout << " " << i << ": " << range_hif[i] << std::endl;
|
||||
}
|
||||
|
||||
|
||||
// start receiving until enter pressed on 900MHz
|
||||
int num = 2;
|
||||
while (num --)
|
||||
|
@ -115,13 +114,12 @@ int main ()
|
|||
{
|
||||
std::cout << "The specified freq couldn't be used" << std::endl;
|
||||
}
|
||||
|
||||
s1g->SetRxGain(0);
|
||||
s1g->SetAgc(false);
|
||||
s1g->StartReceiving(receivedSamples);
|
||||
|
||||
getchar();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
hif->SetFrequency(2400000000);
|
||||
|
@ -134,11 +132,10 @@ int main ()
|
|||
hif->SetRxGain(0);
|
||||
hif->SetAgc(false);
|
||||
hif->StartReceiving(receivedSamples);
|
||||
|
||||
|
||||
getchar();
|
||||
}
|
||||
|
||||
hif->StopReceiving();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
project(test_app)
|
||||
|
||||
# Find the package using pkg-config
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CARIBOULITE REQUIRED cariboulite)
|
||||
|
||||
# Add the executable
|
||||
add_executable(test_app main.cpp)
|
||||
|
||||
# Include directories from the cariboulite package
|
||||
target_include_directories(test_app PRIVATE ${CARIBOULITE_INCLUDE_DIRS})
|
||||
|
||||
# Link against the cariboulite library
|
||||
target_link_libraries(test_app PRIVATE ${CARIBOULITE_LIBRARIES} -lcariboulite pthread)
|
|
@ -0,0 +1,165 @@
|
|||
#ifndef __CIRC_BUFFER_H__
|
||||
#define __CIRC_BUFFER_H__
|
||||
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
|
||||
#define IS_POWER_OF_2(x) (!((x) == 0) && !((x) & ((x) - 1)))
|
||||
#define MIN(x,y) ((x)>(y)?(y):(x))
|
||||
|
||||
|
||||
template <class T>
|
||||
class circular_buffer {
|
||||
public:
|
||||
circular_buffer(size_t size, bool override_write = true, bool block_read = true)
|
||||
{
|
||||
max_size_ = size;
|
||||
if (!IS_POWER_OF_2(max_size_))
|
||||
{
|
||||
max_size_ = next_power_of_2(max_size_);
|
||||
}
|
||||
buf_ = new T[max_size_];
|
||||
override_write_ = override_write;
|
||||
block_read_ = block_read;
|
||||
}
|
||||
|
||||
~circular_buffer()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
delete []buf_;
|
||||
}
|
||||
|
||||
size_t put(const T *data, size_t length)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if ((max_size_ - size()) < length && override_write_)
|
||||
{
|
||||
// pop the amount of data the is needed
|
||||
tail_ += length - (max_size_ - size());
|
||||
}
|
||||
|
||||
size_t len = MIN(length, max_size_ - head_ + tail_);
|
||||
auto l = MIN(len, max_size_ - (head_ & (max_size_ - 1)));
|
||||
|
||||
memcpy(buf_ + (head_ & (max_size_ - 1)), data, l * sizeof(T));
|
||||
memcpy(buf_, data + l, (len - l) * sizeof(T));
|
||||
|
||||
head_ += len;
|
||||
|
||||
if (block_read_)
|
||||
{
|
||||
cond_var_.notify_one();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t get(T *data, size_t length, int timeout_us = 100000)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
|
||||
if (block_read_)
|
||||
{
|
||||
cond_var_.wait_for(lock, std::chrono::microseconds(timeout_us), [&]()
|
||||
{
|
||||
// Acquire the lock only if
|
||||
// we got enough items
|
||||
return size() >= length;
|
||||
});
|
||||
|
||||
if (size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t len = MIN(length, head_ - tail_);
|
||||
auto l = MIN(len, max_size_ - (tail_ & (max_size_ - 1)));
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
memcpy(data, buf_ + (tail_ & (max_size_ - 1)), l * sizeof(T));
|
||||
memcpy(data + l, buf_, (len - l) * sizeof(T));
|
||||
}
|
||||
tail_ += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
void put(T item)
|
||||
{
|
||||
put(&item, 1);
|
||||
}
|
||||
|
||||
T get()
|
||||
{
|
||||
T item;
|
||||
get(&item, 1);
|
||||
return item;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
head_ = tail_ = 0;
|
||||
}
|
||||
|
||||
inline bool empty()
|
||||
{
|
||||
return head_ == tail_;
|
||||
}
|
||||
|
||||
inline bool full()
|
||||
{
|
||||
return size() == capacity();
|
||||
}
|
||||
|
||||
inline size_t capacity() const
|
||||
{
|
||||
return max_size_;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return (head_ - tail_);
|
||||
}
|
||||
|
||||
void print_buffer()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
size_t t = tail_;
|
||||
int i = 0;
|
||||
while (t < head_)
|
||||
{
|
||||
printf("%d => %d\n", i++, (int)buf_[t++&(max_size_-1)]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t next_power_of_2 (uint32_t x)
|
||||
{
|
||||
uint32_t power = 1;
|
||||
while(power < x)
|
||||
{
|
||||
power <<= 1;
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_var_;
|
||||
|
||||
T* buf_;
|
||||
size_t head_ = 0;
|
||||
size_t tail_ = 0;
|
||||
size_t max_size_;
|
||||
bool override_write_;
|
||||
bool block_read_;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,247 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
|
||||
#include <CaribouLite.hpp> // CPP API for CaribouLite
|
||||
#include "circular_buffer.hpp" // for circular sample buffer
|
||||
|
||||
#define SAMPLE_RATE (4000000)
|
||||
#define SAMPLE_RATE_CLOSEST (4194304)
|
||||
#define MAX_FIFO_SECONDS (2)
|
||||
#define MAX_FIFO_SIZE (SAMPLE_RATE_CLOSEST * MAX_FIFO_SECONDS)
|
||||
#define TIME_BETWEEN_EPOCHS (5)
|
||||
#define TIME_OF_SAMPLING (1)
|
||||
#define RX_CHUNK_SAMPLES (8192)
|
||||
|
||||
// ==========================================================================================
|
||||
// The Application context
|
||||
// ==========================================================================================
|
||||
|
||||
typedef enum
|
||||
{
|
||||
app_state_setup = 0,
|
||||
app_state_sampling = 1,
|
||||
app_state_sleeping = 2,
|
||||
} appState_en;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// device
|
||||
CaribouLite* cl;
|
||||
CaribouLiteRadio* radio;
|
||||
|
||||
// operational parameters
|
||||
bool running;
|
||||
float freq;
|
||||
float gain;
|
||||
size_t num_samples_read_so_far;
|
||||
size_t epoch;
|
||||
appState_en state;
|
||||
bool requested_to_quit;
|
||||
|
||||
// buffers & threads
|
||||
circular_buffer<std::complex<float>> *rx_fifo;
|
||||
std::thread *dsp_thread;
|
||||
} appContext_st;
|
||||
|
||||
static appContext_st app = {0};
|
||||
|
||||
// ==========================================================================================
|
||||
// General printing and detection of the board
|
||||
// ==========================================================================================
|
||||
void printInfo(CaribouLite& cl)
|
||||
{
|
||||
std::cout << "Initialized CaribouLite: " << cl.IsInitialized() << std::endl;
|
||||
std::cout << "API Versions: " << cl.GetApiVersion() << std::endl;
|
||||
std::cout << "Hardware Serial Number: " << std::hex << cl.GetHwSerialNumber() << std::endl;
|
||||
std::cout << "System Type: " << cl.GetSystemVersionStr() << std::endl;
|
||||
std::cout << "Hardware Unique ID: " << cl.GetHwGuid() << std::endl;
|
||||
}
|
||||
|
||||
// Detect boards
|
||||
void detectBoard()
|
||||
{
|
||||
CaribouLite::SysVersion ver;
|
||||
std::string name;
|
||||
std::string guid;
|
||||
|
||||
if (CaribouLite::DetectBoard(&ver, name, guid))
|
||||
{
|
||||
std::cout << "Detected Version: " << CaribouLite::GetSystemVersionStr(ver) << ", Name: " << name << ", GUID: " << guid << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Undetected CaribouLite!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Print radio information
|
||||
void printRadioInformation(CaribouLiteRadio* radio)
|
||||
{
|
||||
std::cout << "Radio Name: " << radio->GetRadioName() << " MtuSize: " << std::dec << radio->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
|
||||
std::vector<CaribouLiteFreqRange> range = radio->GetFrequencyRange();
|
||||
std::cout << "Frequency Regions:" << std::endl;
|
||||
for (int i = 0; i < range.size(); i++)
|
||||
{
|
||||
std::cout << " " << i << ": " << range[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================================
|
||||
// DSP Thread - The thread that processes data whenever it is available and its
|
||||
// helper sub-functions
|
||||
// ==========================================================================================
|
||||
|
||||
// Helper DSP function example: calculate the RSSI
|
||||
float RSSI(const std::complex<float>* signal, size_t num_of_samples)
|
||||
{
|
||||
if (num_of_samples == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float sum_of_squares = 0.0f;
|
||||
for (size_t i = 0; i < num_of_samples && i < num_of_samples; ++i)
|
||||
{
|
||||
float vrms = std::norm(signal[i]);
|
||||
sum_of_squares += vrms * vrms / 100.0;
|
||||
}
|
||||
|
||||
float mean_of_squares = sum_of_squares / num_of_samples;
|
||||
|
||||
// Convert RMS value to dBm
|
||||
return 10 * log10(mean_of_squares);
|
||||
}
|
||||
|
||||
// Consumer (parallel DSP) thread
|
||||
void dataConsumerThread(appContext_st* app)
|
||||
{
|
||||
std::cout << "Data consumer thread started" << std::endl;
|
||||
std::complex<float> local_dsp_buffer[RX_CHUNK_SAMPLES * 4];
|
||||
|
||||
|
||||
while (app->running)
|
||||
{
|
||||
// get the number of elements in the fifo
|
||||
size_t num_lements = app->rx_fifo->size();
|
||||
if (num_lements == 0)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t actual_read = app->rx_fifo->get(local_dsp_buffer, (num_lements>(RX_CHUNK_SAMPLES*4)) ? (RX_CHUNK_SAMPLES * 4) : num_lements);
|
||||
if (actual_read)
|
||||
{
|
||||
// here goes the DSP
|
||||
app->num_samples_read_so_far += actual_read;
|
||||
float rssi = RSSI(local_dsp_buffer, actual_read);
|
||||
printf("DSP EPOCH: %ld, NUM_READ: %ld, RSSI: %.3f\n", app->epoch, app->num_samples_read_so_far, rssi);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Data consumer thread exitting" << std::endl;
|
||||
}
|
||||
|
||||
// ==========================================================================================
|
||||
// Asynchronous API for receiving data and managing data flow in RX
|
||||
// ==========================================================================================
|
||||
// Rx Callback (async)
|
||||
void receivedSamples(CaribouLiteRadio* radio, const std::complex<float>* samples, CaribouLiteMeta* sync, size_t num_samples)
|
||||
{
|
||||
for (int i = 0; i < 6; i ++)
|
||||
{
|
||||
std::cout << "[" << samples[i].real() << ", " << samples[i].imag() << "]";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// push the received samples in the fifo
|
||||
app.rx_fifo->put(samples, num_samples);
|
||||
}
|
||||
|
||||
// ==========================================================================================
|
||||
// A simple asynchronous DSP flow
|
||||
// ==========================================================================================
|
||||
int main ()
|
||||
{
|
||||
// try detecting the board before getting the instance
|
||||
detectBoard();
|
||||
CaribouLite &cl = CaribouLite::GetInstance();
|
||||
printInfo(cl);
|
||||
|
||||
// get the radios
|
||||
CaribouLiteRadio *s1g = cl.GetRadioChannel(CaribouLiteRadio::RadioType::S1G);
|
||||
printRadioInformation(s1g);
|
||||
|
||||
// create the application context
|
||||
app.cl = &cl;
|
||||
app.radio = s1g;
|
||||
app.freq = 900000000;
|
||||
app.gain = 69;
|
||||
app.rx_fifo = new circular_buffer<std::complex<float>>(MAX_FIFO_SIZE);
|
||||
app.num_samples_read_so_far = 0;
|
||||
app.state = app_state_sampling;
|
||||
app.epoch = 0;
|
||||
app.requested_to_quit = false;
|
||||
app.running = true;
|
||||
app.dsp_thread = new std::thread(dataConsumerThread, &app);
|
||||
|
||||
// time management
|
||||
while (1)
|
||||
{
|
||||
switch(app.state)
|
||||
{
|
||||
//----------------------------------------------
|
||||
case app_state_setup:
|
||||
std::cout << "Starting Epoch " << app.epoch << std::endl;
|
||||
// an example periodic radio setup stage
|
||||
app.radio->SetRxGain(app.gain);
|
||||
app.radio->SetFrequency(app.freq);
|
||||
app.num_samples_read_so_far = 0;
|
||||
|
||||
// and now go directly to the next sampling stage
|
||||
app.state = app_state_sampling;
|
||||
break;
|
||||
|
||||
//----------------------------------------------
|
||||
case app_state_sampling:
|
||||
// start receiving
|
||||
app.radio->StartReceiving(receivedSamples, RX_CHUNK_SAMPLES);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(TIME_OF_SAMPLING * 1000));
|
||||
|
||||
// stop receiving
|
||||
app.radio->StopReceiving();
|
||||
app.state = app_state_sleeping;
|
||||
break;
|
||||
|
||||
//----------------------------------------------
|
||||
case app_state_sleeping:
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(TIME_BETWEEN_EPOCHS * 1000));
|
||||
app.epoch ++;
|
||||
|
||||
// reset the fifo
|
||||
app.rx_fifo->reset();
|
||||
|
||||
// either go the next epoch or quit the program
|
||||
// this is an example flow but other possibilities exist
|
||||
if (!app.requested_to_quit) app.state = app_state_setup;
|
||||
else break;
|
||||
break;
|
||||
|
||||
//----------------------------------------------
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup - done by the creator
|
||||
app.running = false;
|
||||
app.dsp_thread->join();
|
||||
delete app.dsp_thread;
|
||||
delete app.rx_fifo;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
project(test_app)
|
||||
|
||||
# Find the package using pkg-config
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CARIBOULITE REQUIRED cariboulite)
|
||||
|
||||
# Add the executable
|
||||
add_executable(test_app main.cpp)
|
||||
|
||||
# Include directories from the cariboulite package
|
||||
target_include_directories(test_app PRIVATE ${CARIBOULITE_INCLUDE_DIRS})
|
||||
|
||||
# Link against the cariboulite library
|
||||
target_link_libraries(test_app PRIVATE ${CARIBOULITE_LIBRARIES} -lcariboulite)
|
|
@ -0,0 +1,150 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <CaribouLite.hpp>
|
||||
#include <thread>
|
||||
#include <complex>
|
||||
#include <unistd.h>
|
||||
#include <cmath>
|
||||
|
||||
// Print Board Information
|
||||
void printInfo(CaribouLite& cl)
|
||||
{
|
||||
std::cout << "Initialized CaribouLite: " << cl.IsInitialized() << std::endl;
|
||||
std::cout << "API Versions: " << cl.GetApiVersion() << std::endl;
|
||||
std::cout << "Hardware Serial Number: " << std::hex << cl.GetHwSerialNumber() << std::endl;
|
||||
std::cout << "System Type: " << cl.GetSystemVersionStr() << std::endl;
|
||||
std::cout << "Hardware Unique ID: " << cl.GetHwGuid() << std::endl;
|
||||
}
|
||||
|
||||
// Detect the board before instantiating it
|
||||
void detectBoard()
|
||||
{
|
||||
CaribouLite::SysVersion ver;
|
||||
std::string name;
|
||||
std::string guid;
|
||||
|
||||
if (CaribouLite::DetectBoard(&ver, name, guid))
|
||||
{
|
||||
std::cout << "Detected Version: " << CaribouLite::GetSystemVersionStr(ver) << ", Name: " << name << ", GUID: " << guid << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Undetected CaribouLite!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the RSSI
|
||||
float RSSI(const std::complex<float>* signal, size_t num_of_samples)
|
||||
{
|
||||
if (num_of_samples == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float sum_of_squares = 0.0f;
|
||||
for (size_t i = 0; i < num_of_samples; ++i)
|
||||
{
|
||||
float vrmsp2 = (signal[i].real() * signal[i].real()) + (signal[i].imag() * signal[i].imag());
|
||||
sum_of_squares += vrmsp2 / 100.0;
|
||||
}
|
||||
|
||||
float mean_of_squares = sum_of_squares / num_of_samples;
|
||||
|
||||
// Convert RMS value to dBm
|
||||
return 10 * log10(mean_of_squares);
|
||||
}
|
||||
|
||||
// Rx Callback (async)
|
||||
void receivedSamples(CaribouLiteRadio* radio, const std::complex<float>* samples, CaribouLiteMeta* sync, size_t num_samples)
|
||||
{
|
||||
std::cout << "Radio: " << radio->GetRadioName() << " Received " << std::dec << num_samples << " samples"
|
||||
<< "RSSI: " << RSSI(samples, num_samples) << " dBm" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Main entry
|
||||
int main ()
|
||||
{
|
||||
std::complex<float>* samples = new std::complex<float>[128*1024];
|
||||
|
||||
// try detecting the board before getting the instance
|
||||
detectBoard();
|
||||
|
||||
// get driver instance - use "CaribouLite&" rather than "CaribouLite" (ref)
|
||||
// get a "synchronous" api instance
|
||||
CaribouLite &cl = CaribouLite::GetInstance(false);
|
||||
|
||||
// print the info after connecting
|
||||
printInfo(cl);
|
||||
|
||||
// get the radios
|
||||
CaribouLiteRadio *s1g = cl.GetRadioChannel(CaribouLiteRadio::RadioType::S1G);
|
||||
CaribouLiteRadio *hif = cl.GetRadioChannel(CaribouLiteRadio::RadioType::HiF);
|
||||
|
||||
// write radio information
|
||||
std::cout << "First Radio Name: " << s1g->GetRadioName() << " MtuSize: " << std::dec << s1g->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
std::cout << "First Radio Name: " << hif->GetRadioName() << " MtuSize: " << std::dec << hif->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
|
||||
std::vector<CaribouLiteFreqRange> range_s1g = s1g->GetFrequencyRange();
|
||||
std::vector<CaribouLiteFreqRange> range_hif = hif->GetFrequencyRange();
|
||||
std::cout << "S1G Frequency Regions:" << std::endl;
|
||||
for (int i = 0; i < range_s1g.size(); i++)
|
||||
{
|
||||
std::cout << " " << i << ": " << range_s1g[i] << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "HiF Frequency Regions:" << std::endl;
|
||||
for (int i = 0; i < range_hif.size(); i++)
|
||||
{
|
||||
std::cout << " " << i << ": " << range_hif[i] << std::endl;
|
||||
}
|
||||
|
||||
// Receive Synchrnonously
|
||||
try
|
||||
{
|
||||
hif->SetFrequency(2490000000);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "The specified freq couldn't be used" << std::endl;
|
||||
}
|
||||
hif->SetRxGain(69);
|
||||
hif->SetAgc(false);
|
||||
hif->SetRxSampleRate(4000000);
|
||||
//hif->StartReceiving();
|
||||
|
||||
s1g->SetRxGain(69);
|
||||
s1g->SetAgc(false);
|
||||
s1g->SetRxSampleRate(2000000);
|
||||
s1g->StartReceiving();
|
||||
|
||||
int num_buffers = 10;
|
||||
while (num_buffers--)
|
||||
{
|
||||
//s1g->FlushBuffers();
|
||||
int ret = s1g->ReadSamples(samples, (1<<16));
|
||||
if (ret > 0)
|
||||
{
|
||||
std::cout << "Radio: " << hif->GetRadioName() << " Received " << std::dec << ret << " samples"
|
||||
<< "RSSI: " << RSSI(samples, ret) << " dBm" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*try
|
||||
{
|
||||
s1g->SetFrequency(900100000);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "The specified freq couldn't be used" << std::endl;
|
||||
}
|
||||
s1g->SetRxGain(69);
|
||||
s1g->SetRxBandwidth(2500e3);
|
||||
s1g->SetAgc(false);
|
||||
s1g->StartReceiving(receivedSamples);*/
|
||||
|
||||
delete []samples;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
project(test_app)
|
||||
|
||||
# Find the package using pkg-config
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CARIBOULITE REQUIRED cariboulite)
|
||||
|
||||
# Add the executable
|
||||
add_executable(test_app main.cpp)
|
||||
|
||||
# Include directories from the cariboulite package
|
||||
target_include_directories(test_app PRIVATE ${CARIBOULITE_INCLUDE_DIRS})
|
||||
|
||||
# Link against the cariboulite library
|
||||
target_link_libraries(test_app PRIVATE ${CARIBOULITE_LIBRARIES} -lcariboulite)
|
|
@ -0,0 +1,141 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <CaribouLite.hpp>
|
||||
#include <thread>
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
|
||||
// Print Board Information
|
||||
void printInfo(CaribouLite& cl)
|
||||
{
|
||||
std::cout << "Initialized CaribouLite: " << cl.IsInitialized() << std::endl;
|
||||
std::cout << "API Versions: " << cl.GetApiVersion() << std::endl;
|
||||
std::cout << "Hardware Serial Number: " << std::hex << cl.GetHwSerialNumber() << std::endl;
|
||||
std::cout << "System Type: " << cl.GetSystemVersionStr() << std::endl;
|
||||
std::cout << "Hardware Unique ID: " << cl.GetHwGuid() << std::endl;
|
||||
}
|
||||
|
||||
// Detect the board before instantiating it
|
||||
void detectBoard()
|
||||
{
|
||||
CaribouLite::SysVersion ver;
|
||||
std::string name;
|
||||
std::string guid;
|
||||
|
||||
if (CaribouLite::DetectBoard(&ver, name, guid))
|
||||
{
|
||||
std::cout << "Detected Version: " << CaribouLite::GetSystemVersionStr(ver) << ", Name: " << name << ", GUID: " << guid << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Undetected CaribouLite!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Rx Callback (async)
|
||||
void receivedSamples(CaribouLiteRadio* radio, const std::complex<float>* samples, CaribouLiteMeta* sync, size_t num_samples)
|
||||
{
|
||||
std::cout << "Radio: " << radio->GetRadioName() << " Received " << std::dec << num_samples << " samples" << std::endl;
|
||||
}
|
||||
|
||||
// Tx buffer generation
|
||||
void generateCwWave(float freq, float sample_rate, std::complex<float>* samples, size_t num_samples)
|
||||
{
|
||||
// angular frequency
|
||||
float omega = 2.0f * M_PI * freq;
|
||||
|
||||
for (int i = 0; i < num_samples; ++i)
|
||||
{
|
||||
float t = (float)(i) / sample_rate;
|
||||
float I = cos(omega * t);
|
||||
float Q = sin(omega * t);
|
||||
samples[i] = std::complex<float>(I, Q);
|
||||
}
|
||||
}
|
||||
|
||||
// Main entry
|
||||
int main ()
|
||||
{
|
||||
// try detecting the board before getting the instance
|
||||
detectBoard();
|
||||
|
||||
// get driver instance - use "CaribouLite&" rather than "CaribouLite" (ref)
|
||||
CaribouLite &cl = CaribouLite::GetInstance();
|
||||
|
||||
// print the info after connecting
|
||||
printInfo(cl);
|
||||
|
||||
// get the radios
|
||||
CaribouLiteRadio *s1g = cl.GetRadioChannel(CaribouLiteRadio::RadioType::S1G);
|
||||
CaribouLiteRadio *hif = cl.GetRadioChannel(CaribouLiteRadio::RadioType::HiF);
|
||||
|
||||
// write radio information
|
||||
std::cout << "First Radio Name: " << s1g->GetRadioName() << " MtuSize: " << std::dec << s1g->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
std::cout << "First Radio Name: " << hif->GetRadioName() << " MtuSize: " << std::dec << hif->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
|
||||
std::vector<CaribouLiteFreqRange> range_s1g = s1g->GetFrequencyRange();
|
||||
std::vector<CaribouLiteFreqRange> range_hif = hif->GetFrequencyRange();
|
||||
std::cout << "S1G Frequency Regions:" << std::endl;
|
||||
for (int i = 0; i < range_s1g.size(); i++)
|
||||
{
|
||||
std::cout << " " << i << ": " << range_s1g[i] << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "HiF Frequency Regions:" << std::endl;
|
||||
for (int i = 0; i < range_hif.size(); i++)
|
||||
{
|
||||
std::cout << " " << i << ": " << range_hif[i] << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************************/
|
||||
/* TRANSMITTING CW */
|
||||
/********************************************************************************/
|
||||
/*try
|
||||
{
|
||||
s1g->SetFrequency(900000000);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "The specified freq couldn't be used" << std::endl;
|
||||
}
|
||||
s1g->SetTxPower(0);
|
||||
s1g->SetTxBandwidth(1e6);
|
||||
s1g->SetTxSampleRate(4e6);
|
||||
s1g->StartTransmittingCw();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
||||
s1g->StopTransmitting();*/
|
||||
|
||||
/********************************************************************************/
|
||||
/* TRANSMITTING */
|
||||
/********************************************************************************/
|
||||
std::complex<float>* samples = new std::complex<float>[s1g->GetNativeMtuSample()];
|
||||
generateCwWave(500e3, 4e6, samples, s1g->GetNativeMtuSample());
|
||||
|
||||
try
|
||||
{
|
||||
s1g->SetFrequency(900000000);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "The specified freq couldn't be used" << std::endl;
|
||||
}
|
||||
s1g->SetTxPower(0);
|
||||
s1g->SetTxBandwidth(1e6);
|
||||
s1g->SetTxSampleRate(4e6);
|
||||
s1g->StartTransmitting();
|
||||
|
||||
for (int i = 0; i < 18; i++)
|
||||
{
|
||||
printf("buffer #%d\n", i);
|
||||
s1g->WriteSamples(samples, s1g->GetNativeMtuSample());
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
|
||||
|
||||
s1g->StopTransmitting();
|
||||
|
||||
delete [] samples;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -20,7 +20,7 @@ void detectBoard()
|
|||
CaribouLite::SysVersion ver;
|
||||
std::string name;
|
||||
std::string guid;
|
||||
|
||||
|
||||
if (CaribouLite::DetectBoard(&ver, name, guid))
|
||||
{
|
||||
std::cout << "Detected Version: " << CaribouLite::GetSystemVersionStr(ver) << ", Name: " << name << ", GUID: " << guid << std::endl;
|
||||
|
@ -28,14 +28,13 @@ void detectBoard()
|
|||
else
|
||||
{
|
||||
std::cout << "Undetected CaribouLite!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rx Callback (async)
|
||||
void receivedSamples(CaribouLiteRadio* radio, const std::complex<float>* samples, CaribouLiteMeta* sync, size_t num_samples)
|
||||
{
|
||||
std::cout << "Radio: " << radio->GetRadioName() << " Received " << std::dec << num_samples << " samples" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,21 +43,21 @@ int main ()
|
|||
{
|
||||
// try detecting the board before getting the instance
|
||||
detectBoard();
|
||||
|
||||
|
||||
// get driver instance - use "CaribouLite&" rather than "CaribouLite" (ref)
|
||||
CaribouLite &cl = CaribouLite::GetInstance();
|
||||
|
||||
|
||||
// print the info after connecting
|
||||
printInfo(cl);
|
||||
|
||||
|
||||
// get the radios
|
||||
CaribouLiteRadio *s1g = cl.GetRadioChannel(CaribouLiteRadio::RadioType::S1G);
|
||||
CaribouLiteRadio *hif = cl.GetRadioChannel(CaribouLiteRadio::RadioType::HiF);
|
||||
|
||||
|
||||
// write radio information
|
||||
std::cout << "First Radio Name: " << s1g->GetRadioName() << " MtuSize: " << std::dec << s1g->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
std::cout << "First Radio Name: " << hif->GetRadioName() << " MtuSize: " << std::dec << hif->GetNativeMtuSample() << " Samples" << std::endl;
|
||||
|
||||
|
||||
// start receiving until enter pressed on 900MHz
|
||||
s1g->SetFrequency(900000000);
|
||||
s1g->SetRxGain(50);
|
||||
|
@ -66,11 +65,11 @@ int main ()
|
|||
s1g->StartReceiving(receivedSamples);
|
||||
|
||||
getchar();
|
||||
|
||||
|
||||
hif->SetFrequency(900000000);
|
||||
hif->StartReceiving(receivedSamples, 20000);
|
||||
|
||||
|
||||
getchar();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -5,7 +5,7 @@ pcf_file = ./io.pcf
|
|||
top.bin:
|
||||
yosys -p 'synth_ice40 -top top -json $(filename).json -blif $(filename).blif' -p 'ice40_opt' -p 'fsm_opt' $(filename).v
|
||||
#nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc
|
||||
nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 64 --parallel-refine --opt-timing --timing-allow-fail
|
||||
nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 80 --parallel-refine --opt-timing --seed 5 --timing-allow-fail
|
||||
#nextpnr-ice40 --json blinky.json --pcf blinky.pcf --asc blinky.asc --gui
|
||||
icepack $(filename).asc $(filename).bin
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -15,7 +15,7 @@ module io_ctrl
|
|||
input [3:0] i_config,
|
||||
output o_led0,
|
||||
output o_led1,
|
||||
output [7:0] o_pmod,
|
||||
output [3:0] o_pmod,
|
||||
|
||||
// Analog interfaces
|
||||
output o_mixer_fm,
|
||||
|
@ -26,7 +26,7 @@ module io_ctrl
|
|||
output o_tr_vc2,
|
||||
output o_shdn_tx_lna,
|
||||
output o_shdn_rx_lna,
|
||||
output o_mixer_en
|
||||
output o_mixer_en
|
||||
);
|
||||
|
||||
|
||||
|
@ -73,7 +73,7 @@ module io_ctrl
|
|||
reg led0_state;
|
||||
reg led1_state;
|
||||
reg [7:0] pmod_dir_state;
|
||||
reg [7:0] pmod_state;
|
||||
reg [3:0] pmod_state;
|
||||
reg [7:0] rf_pin_state;
|
||||
reg mixer_en_state;
|
||||
|
||||
|
@ -146,7 +146,8 @@ module io_ctrl
|
|||
|
||||
//----------------------------------------------
|
||||
ioc_pmod_val: begin
|
||||
o_data_out <= pmod_state;
|
||||
o_data_out[3:0] <= pmod_state;
|
||||
o_data_out[7:4] <= 4'b0000;
|
||||
end
|
||||
|
||||
//----------------------------------------------
|
||||
|
@ -191,7 +192,7 @@ module io_ctrl
|
|||
|
||||
//----------------------------------------------
|
||||
ioc_pmod_val: begin
|
||||
pmod_state <= i_data_in;
|
||||
pmod_state[3:0] <= i_data_in[3:0];
|
||||
end
|
||||
|
||||
//----------------------------------------------
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
module lvds_tx (
|
||||
input i_rst_b,
|
||||
input i_ddr_clk,
|
||||
input i_rst_b,
|
||||
input i_ddr_clk,
|
||||
output reg[1:0] o_ddr_data,
|
||||
|
||||
input i_fifo_empty,
|
||||
output o_fifo_read_clk,
|
||||
input i_fifo_empty,
|
||||
output o_fifo_read_clk,
|
||||
output o_fifo_pull,
|
||||
input [31:0] i_fifo_data,
|
||||
input [31:0] i_fifo_data,
|
||||
input [3:0] i_sample_gap,
|
||||
input i_tx_state,
|
||||
input i_sync_input,
|
||||
input i_tx_state,
|
||||
input i_sync_input,
|
||||
input i_debug_lb,
|
||||
output o_tx_state_bit,
|
||||
output o_sync_state_bit,
|
||||
|
@ -17,28 +17,29 @@ module lvds_tx (
|
|||
|
||||
// STATES and PARAMS
|
||||
localparam
|
||||
tx_state_sync = 1'b0,
|
||||
tx_state_tx = 1'b1;
|
||||
tx_state_sync = 1'b0,
|
||||
tx_state_tx = 1'b1;
|
||||
localparam sync_duration_frames = 4'd10; // at least 2.5usec
|
||||
localparam zero_frame = 32'b00000000_00000000_00000000_00000000;
|
||||
localparam lb_frame = 32'b10000100_00000011_01110000_01001000;
|
||||
// Internal Registers
|
||||
|
||||
// Internal Registers
|
||||
reg [3:0] r_sync_count;
|
||||
wire frame_pull_clock;
|
||||
wire frame_assign_clock;
|
||||
reg r_state;
|
||||
reg [3:0] r_phase_count;
|
||||
reg [31:0] r_fifo_data;
|
||||
reg [31:0] r_fifo_data;
|
||||
reg r_pulled;
|
||||
reg r_schedule_zero_frame;
|
||||
|
||||
// Initial conditions
|
||||
initial begin
|
||||
// Initial conditions
|
||||
initial begin
|
||||
r_phase_count = 4'd15;
|
||||
r_fifo_data <= zero_frame;
|
||||
end
|
||||
end
|
||||
|
||||
assign o_fifo_read_clk = i_ddr_clk;
|
||||
assign o_fifo_read_clk = i_ddr_clk;
|
||||
assign o_tx_state_bit = r_state;
|
||||
assign o_sync_state_bit = 1'b0;
|
||||
assign o_fifo_pull = r_pulled;
|
||||
|
@ -52,15 +53,17 @@ module lvds_tx (
|
|||
r_phase_count <= r_phase_count - 1;
|
||||
end
|
||||
end
|
||||
|
||||
// SYNC AND MANAGEMENT
|
||||
always @(posedge i_ddr_clk) begin
|
||||
if (i_rst_b == 1'b0) begin
|
||||
always @(posedge i_ddr_clk)
|
||||
begin
|
||||
if (i_rst_b == 1'b0) begin
|
||||
r_state <= tx_state_sync;
|
||||
r_pulled <= 1'b0;
|
||||
r_fifo_data <= zero_frame;
|
||||
r_sync_count <= sync_duration_frames;
|
||||
r_schedule_zero_frame <= 1'b0;
|
||||
end else begin
|
||||
end else begin
|
||||
case (r_state)
|
||||
//----------------------------------------------
|
||||
tx_state_sync:
|
||||
|
@ -83,14 +86,15 @@ module lvds_tx (
|
|||
r_state <= tx_state_sync;
|
||||
r_fifo_data <= zero_frame;
|
||||
end
|
||||
end else begin
|
||||
end else begin
|
||||
r_sync_count <= r_sync_count - 1;
|
||||
r_schedule_zero_frame <= 1'b1;
|
||||
//r_fifo_data <= zero_frame;
|
||||
r_state <= tx_state_sync;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//----------------------------------------------
|
||||
tx_state_tx:
|
||||
begin
|
||||
|
@ -106,7 +110,7 @@ module lvds_tx (
|
|||
r_sync_count <= sync_duration_frames;
|
||||
r_fifo_data <= zero_frame;
|
||||
r_state <= tx_state_sync;
|
||||
end else begin
|
||||
end else begin
|
||||
r_fifo_data <= i_fifo_data;
|
||||
if (i_sample_gap > 0) begin
|
||||
r_sync_count <= i_sample_gap;
|
||||
|
@ -115,11 +119,11 @@ module lvds_tx (
|
|||
r_state <= tx_state_tx;
|
||||
end
|
||||
end
|
||||
|
||||
r_pulled <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -29,7 +29,7 @@ module smi_ctrl
|
|||
output o_smi_write_req,
|
||||
input i_smi_test,
|
||||
output o_channel,
|
||||
output o_dir,
|
||||
output o_dir,
|
||||
|
||||
// TX CONDITIONAL
|
||||
output reg o_cond_tx,
|
||||
|
@ -171,7 +171,7 @@ module smi_ctrl
|
|||
tx_state_third = 2'b10,
|
||||
tx_state_fourth = 2'b11;
|
||||
|
||||
reg [4:0] int_cnt_tx;
|
||||
reg [12:0] int_cnt_tx;
|
||||
reg [31:0] r_fifo_pushed_data;
|
||||
reg [1:0] tx_reg_state;
|
||||
reg modem_tx_ctrl;
|
||||
|
@ -194,7 +194,11 @@ module smi_ctrl
|
|||
r_fifo_pushed_data <= 32'h00000000;
|
||||
modem_tx_ctrl <= 1'b0;
|
||||
cond_tx_ctrl <= 1'b0;
|
||||
//cnt <= 0;
|
||||
|
||||
// DEBUG
|
||||
int_cnt_tx <= 0;
|
||||
// END_DEBUG
|
||||
|
||||
end else begin
|
||||
case (tx_reg_state)
|
||||
//----------------------------------------------
|
||||
|
@ -247,10 +251,11 @@ module smi_ctrl
|
|||
begin
|
||||
if (i_smi_data_in[7] == 1'b0) begin
|
||||
o_tx_fifo_pushed_data <= {r_fifo_pushed_data[31:8], i_smi_data_in[6:0], 1'b0};
|
||||
|
||||
//o_tx_fifo_pushed_data <= {i_smi_data_in[6:0], 1'b0, r_fifo_pushed_data[15:8], r_fifo_pushed_data[23:16], r_fifo_pushed_data[31:24]};
|
||||
//o_tx_fifo_pushed_data <= {2'b10, cnt, 1'b1, 2'b01, 13'h3F, 1'b0};
|
||||
//o_tx_fifo_pushed_data <= {cnt, cnt, 6'b111111};
|
||||
//cnt <= cnt + 1024;
|
||||
o_tx_fifo_pushed_data <= {2'b10, int_cnt_tx, 1'b1, 2'b01, 13'h3F, 1'b0};
|
||||
int_cnt_tx <= int_cnt_tx + 512;
|
||||
|
||||
w_fifo_push_trigger <= 1'b1;
|
||||
o_cond_tx <= cond_tx_ctrl;
|
||||
end else begin
|
||||
|
|
|
@ -16,6 +16,16 @@ module sys_ctrl
|
|||
output o_debug_smi_test,
|
||||
output o_debug_loopback_tx,
|
||||
output [3:0] o_tx_sample_gap,
|
||||
|
||||
output o_rx_sync_type09,
|
||||
output o_rx_sync_type24,
|
||||
output o_tx_sync_type09,
|
||||
output o_tx_sync_type24,
|
||||
|
||||
output o_rx_sync_09,
|
||||
output o_rx_sync_24,
|
||||
output o_tx_sync_09,
|
||||
output o_tx_sync_24,
|
||||
);
|
||||
|
||||
// MODULE SPECIFIC IOC LIST
|
||||
|
@ -26,7 +36,8 @@ module sys_ctrl
|
|||
ioc_manu_id = 5'b00010, // read only
|
||||
ioc_error_state = 5'b00011, // read only
|
||||
ioc_debug_modes = 5'b00101, // write only
|
||||
ioc_tx_sample_gap = 5'b00110; // read / write
|
||||
ioc_tx_sample_gap = 5'b00110, // read / write
|
||||
ioc_soft_sync = 5'b00111; // write only
|
||||
|
||||
// MODULE SPECIFIC PARAMS
|
||||
// ----------------------
|
||||
|
@ -40,12 +51,32 @@ module sys_ctrl
|
|||
reg debug_fifo_push;
|
||||
reg debug_fifo_pull;
|
||||
reg debug_smi_test;
|
||||
reg debug_loopback_tx;
|
||||
reg [3:0] tx_sample_gap;
|
||||
reg debug_loopback_tx;
|
||||
reg [3:0] tx_sample_gap;
|
||||
|
||||
reg rx_sync_type09;
|
||||
reg rx_sync_type24;
|
||||
reg tx_sync_type09;
|
||||
reg tx_sync_type24;
|
||||
|
||||
reg rx_sync_09;
|
||||
reg rx_sync_24;
|
||||
reg tx_sync_09;
|
||||
reg tx_sync_24;
|
||||
|
||||
assign o_debug_fifo_push = debug_fifo_push;
|
||||
assign o_debug_fifo_pull = debug_fifo_pull;
|
||||
assign o_debug_smi_test = debug_smi_test;
|
||||
assign o_rx_sync_type09 = rx_sync_type09;
|
||||
assign o_tx_sync_type09 = tx_sync_type09;
|
||||
assign o_rx_sync_type24 = rx_sync_type24;
|
||||
assign o_tx_sync_type24 = tx_sync_type24;
|
||||
|
||||
assign o_rx_sync_09 = rx_sync_09;
|
||||
assign o_tx_sync_09 = tx_sync_09;
|
||||
assign o_rx_sync_24 = rx_sync_24;
|
||||
assign o_tx_sync_24 = tx_sync_24;
|
||||
|
||||
|
||||
// MODULE MAIN PROCESS
|
||||
// -------------------
|
||||
|
@ -58,6 +89,17 @@ module sys_ctrl
|
|||
debug_smi_test <= 1'b0;
|
||||
debug_loopback_tx <= 1'b0;
|
||||
tx_sample_gap <= 4'd0;
|
||||
|
||||
rx_sync_type09 <= 1'b0;
|
||||
rx_sync_type24 <= 1'b0;
|
||||
tx_sync_type09 <= 1'b0;
|
||||
tx_sync_type24 <= 1'b0;
|
||||
|
||||
rx_sync_09 <= 1'b0;
|
||||
tx_sync_09 <= 1'b0;
|
||||
rx_sync_24 <= 1'b0;
|
||||
tx_sync_24 <= 1'b0;
|
||||
|
||||
end else if (i_cs == 1'b1) begin
|
||||
//=============================================
|
||||
// READ OPERATIONS
|
||||
|
@ -70,7 +112,10 @@ module sys_ctrl
|
|||
//----------------------------------------------
|
||||
ioc_tx_sample_gap: begin
|
||||
o_data_out[3:0] <= tx_sample_gap;
|
||||
o_data_out[7:4] <= 4'd0;
|
||||
o_data_out[4] <= rx_sync_type09;
|
||||
o_data_out[5] <= rx_sync_type24;
|
||||
o_data_out[6] <= tx_sync_type09;
|
||||
o_data_out[7] <= tx_sync_type24;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
@ -89,6 +134,17 @@ module sys_ctrl
|
|||
//----------------------------------------------
|
||||
ioc_tx_sample_gap: begin
|
||||
tx_sample_gap <= i_data_in[3:0];
|
||||
rx_sync_type09 <= i_data_in[4];
|
||||
rx_sync_type24 <= i_data_in[5];
|
||||
tx_sync_type09 <= i_data_in[6];
|
||||
tx_sync_type24 <= i_data_in[7];
|
||||
end
|
||||
//----------------------------------------------
|
||||
ioc_soft_sync: begin
|
||||
rx_sync_09 <= i_data_in[0];
|
||||
tx_sync_09 <= i_data_in[1];
|
||||
rx_sync_24 <= i_data_in[2];
|
||||
tx_sync_24 <= i_data_in[3];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
|
21323
firmware/top.asc
21323
firmware/top.asc
Plik diff jest za duży
Load Diff
BIN
firmware/top.bin
BIN
firmware/top.bin
Plik binarny nie jest wyświetlany.
7025
firmware/top.blif
7025
firmware/top.blif
Plik diff jest za duży
Load Diff
36681
firmware/top.json
36681
firmware/top.json
Plik diff jest za duży
Load Diff
131
firmware/top.v
131
firmware/top.v
|
@ -50,27 +50,28 @@ module top (
|
|||
//
|
||||
// RPI PIN | FPGA TOP-LEVEL SIGNAL
|
||||
// ------------------------------------------------------------------------
|
||||
// GPIO2_SA3 | i_smi_a[2] - RX09 / RX24 channel select
|
||||
// GPIO3_SA2 | i_smi_a[1] - Tx SMI (0) / Rx SMI (1) select
|
||||
// GPIO4_SA1 | i_smi_a[0] - used as a sys async reset (GBIN1)
|
||||
// GPIO2_SA3 | i_smi_a3 - RX09 / RX24 channel select
|
||||
// GPIO3_SA2 | i_smi_a2 - Tx SMI (0) / Rx SMI (1) select
|
||||
// GPIO4_SA1 | i_rst_b - used as a sys async reset (GBIN1)
|
||||
// GPIO5_SA0 | Not connected to FPGA (MixerRst)
|
||||
//
|
||||
// In order to perform SMI data bus direction selection (highZ / PushPull)
|
||||
// signal a[0] was chosen, while the '0' level (default) denotes RPI => FPGA
|
||||
// direction, and the DATA bus is highZ (recessive mode).
|
||||
// The signal a[2] selects the RX source (900 MHZ or 2.4GHz)
|
||||
// The signal a[1] can be used in the future for other purposes
|
||||
// The signal i_smi_a2 selects Tx(0) or Rx(1) direction
|
||||
// The signal i_smi_a3 selects the RX source (900 MHZ or 2.4GHz)
|
||||
|
||||
//
|
||||
// Description | a[2] (SA3)| a[1] (SA2) |
|
||||
// -------------|------------|---------------|
|
||||
// | 0 | 0 |
|
||||
// TX |------------| RPI => FPGA |
|
||||
// | 1 | Data HighZ |
|
||||
// -------------|------------|---------------|
|
||||
// RX09 | 0 | 1 |
|
||||
// -------------|------------| FPGA => RPI |
|
||||
// RX24 | 1 | Data PushPull |
|
||||
// -------------|------------|---------------|
|
||||
// Description | a2 (SA2) | a3 (SA3) |
|
||||
// -------------|---------------|------------|
|
||||
// | 0 | 0 |
|
||||
// TX | RPI => FPGA |------------|
|
||||
// | Data HighZ | 1 |
|
||||
// -------------|---------------|------------|
|
||||
// RX09 | 1 | 0 |
|
||||
// -------------| FPGA => RPI |------------|
|
||||
// RX24 | Data PushPull | 1 |
|
||||
// -------------|---------------|------------|
|
||||
input i_smi_a2,
|
||||
input i_smi_a3,
|
||||
|
||||
|
@ -105,6 +106,26 @@ module top (
|
|||
wire [7:0] w_tx_data_io;
|
||||
wire [7:0] w_tx_data_smi;
|
||||
|
||||
wire w_rx_sync_type_09;
|
||||
wire w_rx_sync_type_24;
|
||||
wire w_tx_sync_type_09;
|
||||
wire w_tx_sync_type_24;
|
||||
|
||||
wire w_rx_sync_09;
|
||||
wire w_rx_sync_24;
|
||||
wire w_tx_sync_09;
|
||||
wire w_tx_sync_24;
|
||||
|
||||
wire w_rx_sync_input_09;
|
||||
wire w_rx_sync_input_24;
|
||||
wire w_tx_sync_input_09;
|
||||
wire w_tx_sync_input_24;
|
||||
|
||||
assign w_rx_sync_input_09 = (w_rx_sync_type_09) ? io_pmod[7] : w_rx_sync_09;
|
||||
assign w_rx_sync_input_24 = (w_rx_sync_type_24) ? io_pmod[6] : w_rx_sync_24;
|
||||
assign w_tx_sync_input_09 = (w_tx_sync_type_09) ? io_pmod[5] : w_tx_sync_09;
|
||||
assign w_tx_sync_input_24 = (w_tx_sync_type_24) ? io_pmod[4] : w_tx_sync_24;
|
||||
|
||||
//=========================================================================
|
||||
// INSTANCES
|
||||
//=========================================================================
|
||||
|
@ -138,11 +159,22 @@ module top (
|
|||
.i_cs(w_cs[0]),
|
||||
.i_fetch_cmd(w_fetch),
|
||||
.i_load_cmd(w_load),
|
||||
|
||||
.o_debug_fifo_push(),
|
||||
.o_debug_fifo_pull(),
|
||||
.o_debug_smi_test(),
|
||||
.o_debug_loopback_tx(w_debug_lb_tx),
|
||||
.o_tx_sample_gap(tx_sample_gap),
|
||||
|
||||
.o_rx_sync_type09(w_rx_sync_type_09),
|
||||
.o_rx_sync_type24(w_rx_sync_type_24),
|
||||
.o_tx_sync_type09(w_tx_sync_type_09),
|
||||
.o_tx_sync_type24(w_tx_sync_type_24),
|
||||
|
||||
.o_rx_sync_09(w_rx_sync_09),
|
||||
.o_rx_sync_24(w_rx_sync_24),
|
||||
.o_tx_sync_09(w_tx_sync_09),
|
||||
.o_tx_sync_24(w_tx_sync_24)
|
||||
);
|
||||
|
||||
wire w_debug_fifo_push;
|
||||
|
@ -165,9 +197,9 @@ module top (
|
|||
// Digital interfaces
|
||||
.i_button(i_button),
|
||||
.i_config(i_config),
|
||||
.o_led0 (/*o_led0*/),
|
||||
.o_led1 (/*o_led1*/),
|
||||
.o_pmod (),
|
||||
.o_led0 (o_led0),
|
||||
.o_led1 (o_led1),
|
||||
.o_pmod (/*io_pmod[3:0]*/),
|
||||
|
||||
// Analog interfaces
|
||||
.o_mixer_fm(/*o_mixer_fm*/),
|
||||
|
@ -181,6 +213,11 @@ module top (
|
|||
.o_mixer_en(/*o_mixer_en*/)
|
||||
);
|
||||
|
||||
assign io_pmod[0] = ~lvds_clock_buf;
|
||||
assign io_pmod[1] = w_lvds_tx_d0;
|
||||
assign io_pmod[2] = w_lvds_tx_d1;
|
||||
assign io_pmod[3] = i_smi_swe_srw;
|
||||
|
||||
//=========================================================================
|
||||
// CONBINATORIAL ASSIGNMENTS
|
||||
//=========================================================================
|
||||
|
@ -266,31 +303,49 @@ module top (
|
|||
|
||||
// Non-inverting, P-side of pair
|
||||
SB_IO #(
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_INPUT_REGISTER }
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_OUTPUT_REGISTER }
|
||||
.IO_STANDARD("SB_LVCMOS"),
|
||||
) iq_tx_p (
|
||||
.PACKAGE_PIN(o_iq_tx_p),
|
||||
.OUTPUT_CLK(lvds_clock_buf),
|
||||
.OUTPUT_CLK(~lvds_clock_buf),
|
||||
.D_OUT_0(~w_lvds_tx_d0),
|
||||
.D_OUT_1(~w_lvds_tx_d1)
|
||||
);
|
||||
|
||||
// Inverting, N-side of pair
|
||||
SB_IO #(
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_INPUT_REGISTER }
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_OUTPUT_REGISTER }
|
||||
.IO_STANDARD("SB_LVCMOS"),
|
||||
) iq_tx_n (
|
||||
.PACKAGE_PIN(o_iq_tx_n),
|
||||
.OUTPUT_CLK(lvds_clock_buf),
|
||||
.OUTPUT_CLK(~lvds_clock_buf),
|
||||
.D_OUT_0(w_lvds_tx_d0),
|
||||
.D_OUT_1(w_lvds_tx_d1)
|
||||
);
|
||||
|
||||
// Non-inverting, P-side clock
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b011001),
|
||||
.IO_STANDARD("SB_LVCMOS")
|
||||
) iq_tx_clk_p (
|
||||
.PACKAGE_PIN(o_iq_tx_clk_p),
|
||||
.D_OUT_0(lvds_clock_buf),
|
||||
);
|
||||
|
||||
// Inverting, N-side clock
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b011001),
|
||||
.IO_STANDARD("SB_LVCMOS")
|
||||
) iq_tx_clk_n (
|
||||
.PACKAGE_PIN(o_iq_tx_clk_n),
|
||||
.D_OUT_0(~lvds_clock_buf),
|
||||
);
|
||||
|
||||
|
||||
// Logic on a clock signal is very bad - try to use a dedicated
|
||||
// SB_IO
|
||||
assign o_iq_tx_clk_p = lvds_clock_buf;
|
||||
assign o_iq_tx_clk_n = ~lvds_clock_buf;
|
||||
//assign o_iq_tx_clk_p = lvds_clock_buf;
|
||||
//assign o_iq_tx_clk_n = ~lvds_clock_buf;
|
||||
|
||||
//=========================================================================
|
||||
// LVDS RX SIGNAL FROM MODEM
|
||||
|
@ -318,7 +373,7 @@ module top (
|
|||
.o_fifo_push(w_rx_09_fifo_push),
|
||||
|
||||
.o_fifo_data (w_rx_09_fifo_data),
|
||||
.i_sync_input (1'b0),
|
||||
.i_sync_input (w_rx_sync_input_09),
|
||||
.o_debug_state()
|
||||
);
|
||||
|
||||
|
@ -333,7 +388,7 @@ module top (
|
|||
.o_fifo_push(w_rx_24_fifo_push),
|
||||
|
||||
.o_fifo_data (w_rx_24_fifo_data),
|
||||
.i_sync_input (1'b0),
|
||||
.i_sync_input (w_rx_sync_input_24),
|
||||
.o_debug_state()
|
||||
);
|
||||
|
||||
|
@ -344,9 +399,6 @@ module top (
|
|||
wire [31:0] w_rx_fifo_pulled_data;
|
||||
wire w_rx_fifo_full;
|
||||
wire w_rx_fifo_empty;
|
||||
wire channel;
|
||||
|
||||
assign channel = i_smi_a3;
|
||||
|
||||
complex_fifo #(
|
||||
.ADDR_WIDTH(10), // 1024 samples
|
||||
|
@ -382,12 +434,12 @@ module top (
|
|||
.i_fifo_data(w_tx_fifo_pulled_data),
|
||||
.i_sample_gap(tx_sample_gap),
|
||||
.i_tx_state(~w_smi_data_direction),
|
||||
.i_sync_input(1'b0),
|
||||
.i_sync_input(w_tx_sync_input_09),
|
||||
.i_debug_lb(w_debug_lb_tx),
|
||||
.o_tx_state_bit(),
|
||||
.o_sync_state_bit(),
|
||||
);
|
||||
|
||||
|
||||
wire w_tx_fifo_full;
|
||||
wire w_tx_fifo_empty;
|
||||
wire w_tx_fifo_read_clk;
|
||||
|
@ -418,6 +470,11 @@ module top (
|
|||
.debug_push(1'b0)
|
||||
);
|
||||
|
||||
wire channel;
|
||||
wire w_smi_data_direction;
|
||||
//assign channel = i_smi_a3;
|
||||
//assign w_smi_data_direction = i_smi_a2;
|
||||
|
||||
smi_ctrl smi_ctrl_ins (
|
||||
.i_rst_b(i_rst_b),
|
||||
.i_sys_clk(w_clock_sys),
|
||||
|
@ -445,8 +502,8 @@ module top (
|
|||
.i_smi_data_in(w_smi_data_input),
|
||||
.o_smi_read_req(w_smi_read_req),
|
||||
.o_smi_write_req(w_smi_write_req),
|
||||
.o_channel(/*channel*/),
|
||||
.o_dir (/*w_smi_data_direction*/),
|
||||
.o_channel(channel),
|
||||
.o_dir (w_smi_data_direction),
|
||||
.i_smi_test(1'b0/*w_debug_smi_test*/),
|
||||
.o_cond_tx(),
|
||||
.o_address_error()
|
||||
|
@ -456,7 +513,6 @@ module top (
|
|||
wire [7:0] w_smi_data_input;
|
||||
wire w_smi_read_req;
|
||||
wire w_smi_write_req;
|
||||
wire w_smi_data_direction;
|
||||
|
||||
// the "Writing" flag indicates that the data[7:0] direction (inout)
|
||||
// from the FPGA's SMI module should be "output". This happens when the
|
||||
|
@ -464,7 +520,6 @@ module top (
|
|||
// The address has the MSB '1' when in RX mode. otherwise (when IDLE or TX)
|
||||
// the data is high-z, which is the more "recessive" mode
|
||||
|
||||
assign w_smi_data_direction = i_smi_a2;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b1010_01),
|
||||
.PULLUP (1'b0)
|
||||
|
@ -538,12 +593,10 @@ module top (
|
|||
.D_IN_0(w_smi_data_input[7])
|
||||
);
|
||||
|
||||
// We need the 'o_smi_write_req' to be 1 only when the direction is TX
|
||||
// (w_smi_data_direction == 0) and the write fifo is not full
|
||||
assign o_smi_read_req = (w_smi_data_direction) ? w_smi_read_req : w_smi_write_req;
|
||||
assign o_smi_write_req = 1'bZ;
|
||||
|
||||
assign o_led0 = w_smi_data_direction;
|
||||
assign o_led1 = channel;
|
||||
//assign o_led0 = w_smi_data_direction;
|
||||
//assign o_led1 = channel;
|
||||
|
||||
endmodule // top
|
||||
|
|
|
@ -175,7 +175,7 @@ public:
|
|||
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);
|
||||
void StartTransmitting(void);
|
||||
void StartTransmittingLo(void);
|
||||
void StartTransmittingCw(void);
|
||||
void StopTransmitting(void);
|
||||
|
@ -198,6 +198,7 @@ private:
|
|||
const CaribouLite* _device;
|
||||
const RadioType _type;
|
||||
|
||||
// Rx information
|
||||
bool _rx_thread_running;
|
||||
bool _rx_is_active;
|
||||
std::thread *_rx_thread;
|
||||
|
@ -209,14 +210,12 @@ private:
|
|||
RxCbType _rxCallbackType;
|
||||
ApiType _api_type;
|
||||
|
||||
bool _tx_thread_running;
|
||||
// Tx information
|
||||
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;
|
||||
|
||||
// buffers
|
||||
cariboulite_sample_complex_int16 *_read_samples;
|
||||
std::complex<short> *_write_samples;
|
||||
cariboulite_sample_meta* _read_metadata;
|
||||
|
||||
private:
|
||||
|
|
|
@ -132,7 +132,32 @@ int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_re
|
|||
//==================================================================
|
||||
int CaribouLiteRadio::WriteSamples(std::complex<float>* samples, size_t num_to_write)
|
||||
{
|
||||
return 0;
|
||||
// fill in the _write_samples internal buffer
|
||||
size_t written_so_far = 0;
|
||||
size_t left_to_write = num_to_write;
|
||||
size_t mtu_size = GetNativeMtuSample();
|
||||
|
||||
while (written_so_far < num_to_write)
|
||||
{
|
||||
size_t current_write = left_to_write;
|
||||
size_t k = written_so_far;
|
||||
if (current_write > mtu_size) current_write = mtu_size;
|
||||
|
||||
for (size_t i = 0; i < current_write; i++, k++)
|
||||
{
|
||||
_write_samples[i].real((uint16_t)(samples[k].real() * 4096));
|
||||
_write_samples[i].imag((uint16_t)(samples[k].imag() * 4096));
|
||||
}
|
||||
int ret = WriteSamples(_write_samples, current_write);
|
||||
if (ret <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
written_so_far += ret;
|
||||
left_to_write -= ret;
|
||||
}
|
||||
|
||||
return written_so_far;
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
|
@ -143,20 +168,6 @@ int CaribouLiteRadio::WriteSamples(std::complex<short>* samples, size_t num_to_w
|
|||
num_to_write);
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
void CaribouLiteRadio::CaribouLiteTxThread(CaribouLiteRadio* radio)
|
||||
{
|
||||
while (radio->_tx_thread_running)
|
||||
{
|
||||
if (!radio->_tx_is_active)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(4));
|
||||
continue;
|
||||
}
|
||||
// TBD
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
CaribouLiteRadio::CaribouLiteRadio( const cariboulite_radio_state_st* radio,
|
||||
RadioType type,
|
||||
|
@ -164,25 +175,26 @@ CaribouLiteRadio::CaribouLiteRadio( const cariboulite_radio_state_st* radio,
|
|||
const CaribouLite* parent)
|
||||
: _radio(radio), _device(parent), _type(type), _rxCallbackType(RxCbType::None), _api_type(api_type)
|
||||
{
|
||||
size_t mtu_size = GetNativeMtuSample();
|
||||
if (_api_type == Async)
|
||||
{
|
||||
//printf("Creating Radio Type %d ASYNC\n", 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("Creating Radio Type %d SYNC\n", type);
|
||||
_read_samples = NULL;
|
||||
_read_metadata = NULL;
|
||||
size_t mtu_size = GetNativeMtuSample();
|
||||
|
||||
// allocate internal buffers
|
||||
_read_samples = new cariboulite_sample_complex_int16[mtu_size];
|
||||
_read_samples = new cariboulite_sample_complex_int16[mtu_size];
|
||||
_read_metadata = new cariboulite_sample_meta[mtu_size];
|
||||
}
|
||||
|
||||
_write_samples = NULL;
|
||||
_write_samples = new std::complex<short>[mtu_size];
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
|
@ -197,18 +209,18 @@ CaribouLiteRadio::~CaribouLiteRadio()
|
|||
_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;
|
||||
_read_samples = NULL;
|
||||
|
||||
if (_read_metadata) delete [] _read_metadata;
|
||||
_read_metadata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (_write_samples) delete [] _write_samples;
|
||||
_write_samples = NULL;
|
||||
}
|
||||
|
||||
// Gain
|
||||
|
@ -596,11 +608,9 @@ void CaribouLiteRadio::StopReceiving()
|
|||
}
|
||||
|
||||
//==================================================================
|
||||
void CaribouLiteRadio::StartTransmitting(std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> on_data_request, size_t samples_per_chunk)
|
||||
void CaribouLiteRadio::StartTransmitting()
|
||||
{
|
||||
_rx_is_active = false;
|
||||
_on_data_request = on_data_request;
|
||||
_tx_samples_per_chunk = samples_per_chunk;
|
||||
cariboulite_radio_activate_channel((cariboulite_radio_state_st*)_radio, cariboulite_channel_dir_rx, false);
|
||||
cariboulite_radio_set_cw_outputs((cariboulite_radio_state_st*)_radio, false, false);
|
||||
cariboulite_radio_activate_channel((cariboulite_radio_state_st*)_radio, cariboulite_channel_dir_tx, true);
|
||||
|
|
|
@ -90,10 +90,6 @@ typedef enum
|
|||
at86rf215_radio_rx_bw_BW1250KHZ_IF2000KHZ = 0x9, // at86rf215_radio_rx_f_cut_0_75_half_fs
|
||||
at86rf215_radio_rx_bw_BW1600KHZ_IF2000KHZ = 0xA, // at86rf215_radio_rx_f_cut_half_fs
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IF2000KHZ = 0xB, // at86rf215_radio_rx_f_cut_half_fs
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFCCKHZ = 0xC, // **
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFDDHZ = 0xD, // **
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFEEKHZ = 0xE, // **
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFFFKHZ = 0xF, // **
|
||||
} at86rf215_radio_rx_bw_en;
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -13,13 +13,14 @@
|
|||
//--------------------------------------------------------------
|
||||
// Static Definitions
|
||||
//--------------------------------------------------------------
|
||||
#define IOC_MOD_VER 0
|
||||
#define IOC_SYS_CTRL_SYS_VERSION 1
|
||||
#define IOC_SYS_CTRL_MANU_ID 2
|
||||
#define IOC_SYS_CTRL_SYS_ERR_STAT 3
|
||||
#define IOC_SYS_CTRL_SYS_SOFT_RST 4
|
||||
#define IOC_SYS_CTRL_DEBUG_MODES 5
|
||||
#define IOC_SYS_CTRL_SYS_TX_SAMPLE_GAP 6
|
||||
#define IOC_MOD_VER 0
|
||||
#define IOC_SYS_CTRL_SYS_VERSION 1
|
||||
#define IOC_SYS_CTRL_MANU_ID 2
|
||||
#define IOC_SYS_CTRL_SYS_ERR_STAT 3
|
||||
#define IOC_SYS_CTRL_SYS_SOFT_RST 4
|
||||
#define IOC_SYS_CTRL_DEBUG_MODES 5
|
||||
#define IOC_SYS_CTRL_TX_SAMPLE_GAP 6
|
||||
#define IOC_SYS_CTRL_SOFT_SYNC 7
|
||||
|
||||
#define IOC_IO_CTRL_MODE 1
|
||||
#define IOC_IO_CTRL_DIG_PIN 2
|
||||
|
@ -31,7 +32,7 @@
|
|||
|
||||
#define IOC_SMI_CTRL_FIFO_STATUS 1
|
||||
#define IOC_SMI_CHANNEL_SELECT 2
|
||||
#define IOC_SMI_CTRL_DIR_SELECT 3
|
||||
#define IOC_SMI_CTRL_DIR_SELECT 3
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Internal Data-Types
|
||||
|
@ -380,21 +381,42 @@ int caribou_fpga_get_errors (caribou_fpga_st* dev, uint8_t *err_map)
|
|||
.ioc = IOC_SYS_CTRL_SYS_ERR_STAT
|
||||
};
|
||||
|
||||
*err_map = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), err_map);
|
||||
if (err_map)
|
||||
{
|
||||
*err_map = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), err_map);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_set_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t gap)
|
||||
{
|
||||
uint8_t actual_val = 0;
|
||||
uint8_t actual_gap = 0;
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_sys_ctrl_tx_sample_gap");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_write,
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_SYS_TX_SAMPLE_GAP,
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP,
|
||||
};
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &gap);
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_val);
|
||||
if (ret != 0) return -1;
|
||||
|
||||
actual_gap = actual_val & 0xF;
|
||||
actual_val &= 0xF0;
|
||||
|
||||
if (gap != actual_gap)
|
||||
{
|
||||
// only if change is needed
|
||||
oc.rw = caribou_fpga_rw_write;
|
||||
actual_val |= (gap & 0xF);
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -406,14 +428,104 @@ int caribou_fpga_get_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t *gap)
|
|||
{
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_SYS_TX_SAMPLE_GAP
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP
|
||||
};
|
||||
|
||||
*gap = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), gap);
|
||||
uint8_t actual_gap = 0;
|
||||
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_gap);
|
||||
|
||||
if (gap) *gap = actual_gap & 0xF;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_set_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en rx_09,
|
||||
caribou_fpga_sync_source_en rx_24,
|
||||
caribou_fpga_sync_source_en tx_09,
|
||||
caribou_fpga_sync_source_en tx_24)
|
||||
{
|
||||
uint8_t actual_val = 0;
|
||||
uint8_t temp = 0;
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_sys_ctrl_sync_source");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP,
|
||||
};
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_val);
|
||||
if (ret != 0) return -1;
|
||||
|
||||
temp = actual_val & 0xF;
|
||||
uint8_t cur_rx_09 = (actual_val >> 4) & 0x1;
|
||||
uint8_t cur_rx_24 = (actual_val >> 5) & 0x1;
|
||||
uint8_t cur_tx_09 = (actual_val >> 6) & 0x1;
|
||||
uint8_t cur_tx_24 = (actual_val >> 7) & 0x1;
|
||||
|
||||
if (rx_09 != caribou_fpga_sync_src_no_change) cur_rx_09 = rx_09 & 0x1;
|
||||
if (rx_24 != caribou_fpga_sync_src_no_change) cur_rx_24 = rx_24 & 0x1;
|
||||
if (tx_09 != caribou_fpga_sync_src_no_change) cur_tx_09 = tx_09 & 0x1;
|
||||
if (tx_24 != caribou_fpga_sync_src_no_change) cur_tx_24 = tx_24 & 0x1;
|
||||
|
||||
temp |= cur_rx_09 << 4;
|
||||
temp |= cur_rx_24 << 5;
|
||||
temp |= cur_tx_09 << 6;
|
||||
temp |= cur_tx_24 << 7;
|
||||
|
||||
oc.rw = caribou_fpga_rw_write;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &temp);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_get_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en *rx_09,
|
||||
caribou_fpga_sync_source_en *rx_24,
|
||||
caribou_fpga_sync_source_en *tx_09,
|
||||
caribou_fpga_sync_source_en *tx_24)
|
||||
{
|
||||
uint8_t temp = 0;
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_get_sys_ctrl_sync_source");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP,
|
||||
};
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &temp);
|
||||
if (ret != 0) return -1;
|
||||
|
||||
if (rx_09) *rx_09 = (temp >> 4) & 0x1;
|
||||
if (rx_24) *rx_24 = (temp >> 5) & 0x1;
|
||||
if (tx_09) *tx_09 = (temp >> 6) & 0x1;
|
||||
if (tx_24) *tx_24 = (temp >> 7) & 0x1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_set_sys_ctrl_soft_sync_value (caribou_fpga_st* dev, uint8_t rx_09,
|
||||
uint8_t rx_24,
|
||||
uint8_t tx_09,
|
||||
uint8_t tx_24)
|
||||
{
|
||||
uint8_t temp = (rx_09 & 0xf) | ((tx_09 & 0xf) << 1) | ((rx_24 & 0xf) << 2) | ((tx_24 & 0xf) << 3);
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_sys_ctrl_soft_sync_value");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_write,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_SOFT_SYNC,
|
||||
};
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &temp);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// I/O Controller
|
||||
int caribou_fpga_set_io_ctrl_mode (caribou_fpga_st* dev, uint8_t debug_mode, caribou_fpga_io_ctrl_rfm_en rfm)
|
||||
{
|
||||
|
@ -445,8 +557,8 @@ int caribou_fpga_get_io_ctrl_mode (caribou_fpga_st* dev, uint8_t* debug_mode, ca
|
|||
uint8_t mode = 0;
|
||||
caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &mode);
|
||||
|
||||
*debug_mode = mode & 0x3;
|
||||
*rfm = (mode >> 2) & 0x7;
|
||||
if (debug_mode) *debug_mode = mode & 0x3;
|
||||
if (rfm) *rfm = (mode >> 2) & 0x7;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -512,8 +624,12 @@ int caribou_fpga_get_io_ctrl_pmod_dir (caribou_fpga_st* dev, uint8_t *dir)
|
|||
.mid = caribou_fpga_mid_io_ctrl,
|
||||
.ioc = IOC_IO_CTRL_PMOD_DIR
|
||||
};
|
||||
*dir = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), dir);
|
||||
if (dir)
|
||||
{
|
||||
*dir = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), dir);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -540,8 +656,12 @@ int caribou_fpga_get_io_ctrl_pmod_val (caribou_fpga_st* dev, uint8_t *val)
|
|||
.mid = caribou_fpga_mid_io_ctrl,
|
||||
.ioc = IOC_IO_CTRL_PMOD_VAL
|
||||
};
|
||||
*val = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), val);
|
||||
if (val)
|
||||
{
|
||||
*val = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), val);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -568,8 +688,12 @@ int caribou_fpga_get_io_ctrl_rf_state (caribou_fpga_st* dev, caribou_fpga_rf_pin
|
|||
.mid = caribou_fpga_mid_io_ctrl,
|
||||
.ioc = IOC_IO_CTRL_RF_PIN
|
||||
};
|
||||
memset(pins, 0, sizeof(caribou_fpga_rf_pin_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)pins);
|
||||
if (pins)
|
||||
{
|
||||
memset(pins, 0, sizeof(caribou_fpga_rf_pin_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)pins);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -583,8 +707,12 @@ int caribou_fpga_get_smi_ctrl_fifo_status (caribou_fpga_st* dev, caribou_fpga_sm
|
|||
.mid = caribou_fpga_mid_smi_ctrl,
|
||||
.ioc = IOC_SMI_CTRL_FIFO_STATUS
|
||||
};
|
||||
memset(status, 0, sizeof(caribou_fpga_smi_fifo_status_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)status);
|
||||
if (status)
|
||||
{
|
||||
memset(status, 0, sizeof(caribou_fpga_smi_fifo_status_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)status);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
|
|
@ -98,6 +98,20 @@ typedef enum
|
|||
caribou_fpga_smi_channel_1 = 1,
|
||||
} caribou_fpga_smi_channel_en;
|
||||
|
||||
/**
|
||||
* @brief Syncronization bit (metadata) source. Either software
|
||||
* setting using "caribou_fpga_set_sys_ctrl_soft_sync_value"
|
||||
* or by using an external pulse on the PMOD 6/7 pins.
|
||||
* If no change is needed on a specific sync source,
|
||||
* "caribou_fpga_sync_src_no_change" should be used
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
caribou_fpga_sync_src_soft = 0,
|
||||
caribou_fpga_sync_src_pmod = 1,
|
||||
caribou_fpga_sync_src_no_change = 2,
|
||||
} caribou_fpga_sync_source_en;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
|
@ -154,6 +168,19 @@ int caribou_fpga_set_debug_modes (caribou_fpga_st* dev, bool dbg_fifo_push, bool
|
|||
int caribou_fpga_set_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t gap);
|
||||
int caribou_fpga_get_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t *gap);
|
||||
|
||||
int caribou_fpga_set_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en rx_09,
|
||||
caribou_fpga_sync_source_en rx_24,
|
||||
caribou_fpga_sync_source_en tx_09,
|
||||
caribou_fpga_sync_source_en tx_24);
|
||||
int caribou_fpga_get_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en *rx_09,
|
||||
caribou_fpga_sync_source_en *rx_24,
|
||||
caribou_fpga_sync_source_en *tx_09,
|
||||
caribou_fpga_sync_source_en *tx_24);
|
||||
|
||||
int caribou_fpga_set_sys_ctrl_soft_sync_value (caribou_fpga_st* dev, uint8_t rx_09,
|
||||
uint8_t rx_24,
|
||||
uint8_t tx_09,
|
||||
uint8_t tx_24);
|
||||
// I/O Controller
|
||||
int caribou_fpga_set_io_ctrl_mode (caribou_fpga_st* dev, uint8_t debug_mode, caribou_fpga_io_ctrl_rfm_en rfm);
|
||||
int caribou_fpga_get_io_ctrl_mode (caribou_fpga_st* dev, uint8_t *debug_mode, caribou_fpga_io_ctrl_rfm_en *rfm);
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -18,12 +18,13 @@
|
|||
#include "cariboulite_events.h"
|
||||
#include "cariboulite_setup.h"
|
||||
|
||||
|
||||
#define GET_MODEM_CH(rad_ch) ((rad_ch)==cariboulite_channel_s1g ? at86rf215_rf_channel_900mhz : at86rf215_rf_channel_2400mhz)
|
||||
#define GET_SMI_CH(rad_ch) ((rad_ch)==cariboulite_channel_s1g ? caribou_smi_channel_900 : caribou_smi_channel_2400)
|
||||
|
||||
static float sample_rate_middles[] = {3000, 1666, 1166, 900, 733, 583, 450};
|
||||
static float rx_bandwidth_middles[] = {225, 281, 356, 450, 562, 706, 893, 1125, 1406, 1781, 2250};
|
||||
static float tx_bandwidth_middles[] = {90, 112, 142, 180, 225, 282, 357, 450, 562, 712, 900};
|
||||
static float sample_rate_middles[] = {3000e3, 1666e3, 1166e3, 900e3, 733e3, 583e3, 450e3};
|
||||
static float rx_bandwidth_middles[] = {225e3, 281e3, 356e3, 450e3, 562e3, 706e3, 893e3, 1125e3, 1406e3, 1781e3, 2250e3};
|
||||
static float tx_bandwidth_middles[] = {90e3, 112e3, 142e3, 180e3, 225e3, 282e3, 357e3, 450e3, 562e3, 712e3, 900e3};
|
||||
|
||||
|
||||
//=========================================================================
|
||||
|
@ -187,8 +188,30 @@ int cariboulite_radio_set_rx_bandwidth(cariboulite_radio_state_st* radio,
|
|||
cariboulite_radio_rx_bw_en rx_bw)
|
||||
{
|
||||
cariboulite_radio_f_cut_en fcut = cariboulite_radio_rx_f_cut_half_fs;
|
||||
|
||||
/*if (rx_bw == cariboulite_radio_rx_bw_2500KHz || rx_bw == cariboulite_radio_rx_bw_2000KHz)
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_half_fs; // 2MHz cuttof
|
||||
}
|
||||
else if (rx_bw == cariboulite_radio_rx_bw_1562KHz ||
|
||||
rx_bw == cariboulite_radio_rx_bw_1250KHz ||
|
||||
rx_bw == cariboulite_radio_rx_bw_1000KHz)
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_0_75_half_fs; // 1.5MHz cuttof
|
||||
}
|
||||
else if (rx_bw == cariboulite_radio_rx_bw_787KHz ||
|
||||
rx_bw == cariboulite_radio_rx_bw_625KHz)
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_0_5_half_fs; // 1MHz cuttof
|
||||
}
|
||||
else
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_0_25_half_fs; // 500kHz cuttof
|
||||
}*/
|
||||
|
||||
|
||||
radio->rx_fcut = fcut;
|
||||
|
||||
|
||||
at86rf215_radio_set_rx_bw_samp_st cfg =
|
||||
{
|
||||
.inverter_sign_if = 0,
|
||||
|
@ -197,8 +220,8 @@ int cariboulite_radio_set_rx_bandwidth(cariboulite_radio_state_st* radio,
|
|||
// to channel scheme. This increases the IF frequency to max 2.5MHz
|
||||
// thus places the internal LO fasr away from the signal => lower noise
|
||||
.bw = (at86rf215_radio_rx_bw_en)rx_bw,
|
||||
.fcut = (at86rf215_radio_f_cut_en)radio->rx_fcut, // keep the same
|
||||
.fs = (at86rf215_radio_sample_rate_en)radio->rx_fs, // keep the same
|
||||
.fcut = (at86rf215_radio_f_cut_en)radio->rx_fcut,
|
||||
.fs = (at86rf215_radio_sample_rate_en)radio->rx_fs,
|
||||
};
|
||||
at86rf215_radio_set_rx_bandwidth_sampling(&radio->sys->modem, GET_MODEM_CH(radio->type), &cfg);
|
||||
radio->rx_bw = rx_bw;
|
||||
|
@ -1053,12 +1076,11 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
|
||||
// then deactivate the modem's stream
|
||||
cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_trx_off);
|
||||
ret = caribou_smi_set_driver_streaming_state(&radio->sys->smi, smi_stream_idle);
|
||||
|
||||
// DEACTIVATION
|
||||
if (!activate)
|
||||
{
|
||||
// if we deactivate, first shut off the smi stream
|
||||
ret = caribou_smi_set_driver_streaming_state(&radio->sys->smi, smi_stream_idle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1088,14 +1110,7 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
// Activate the channel according to the configurations
|
||||
// RX on both channels looks the same
|
||||
if (radio->channel_direction == cariboulite_channel_dir_rx)
|
||||
{
|
||||
// Setup the IQ stream properties
|
||||
smi_stream_state_en smi_state = smi_stream_idle;
|
||||
if (radio->smi_channel_id == caribou_smi_channel_900)
|
||||
smi_state = smi_stream_rx_channel_0;
|
||||
else if (radio->smi_channel_id == caribou_smi_channel_2400)
|
||||
smi_state = smi_stream_rx_channel_1;
|
||||
|
||||
{
|
||||
at86rf215_iq_interface_config_st modem_iq_config = {
|
||||
.loopback_enable = radio->tx_loopback_anabled,
|
||||
.drv_strength = at86rf215_iq_drive_current_4ma,
|
||||
|
@ -1105,11 +1120,29 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
.radio24_mode = at86rf215_iq_if_mode,
|
||||
.clock_skew = at86rf215_iq_clock_data_skew_4_906ns,
|
||||
};
|
||||
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
|
||||
|
||||
|
||||
// Setup the IQ stream properties
|
||||
smi_stream_state_en smi_state = smi_stream_idle;
|
||||
if (radio->smi_channel_id == caribou_smi_channel_900)
|
||||
{
|
||||
modem_iq_config.radio09_mode = at86rf215_iq_if_mode;
|
||||
modem_iq_config.radio24_mode = at86rf215_baseband_mode;
|
||||
modem_iq_config.clock_skew = at86rf215_iq_clock_data_skew_4_906ns;
|
||||
smi_state = smi_stream_rx_channel_0;
|
||||
}
|
||||
else if (radio->smi_channel_id == caribou_smi_channel_2400)
|
||||
{
|
||||
modem_iq_config.radio09_mode = at86rf215_baseband_mode;
|
||||
modem_iq_config.radio24_mode = at86rf215_iq_if_mode;
|
||||
modem_iq_config.clock_skew = at86rf215_iq_clock_data_skew_4_906ns;
|
||||
smi_state = smi_stream_rx_channel_1;
|
||||
}
|
||||
|
||||
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
|
||||
|
||||
// configure FPGA with the correct rx channel
|
||||
caribou_fpga_set_smi_channel (&radio->sys->fpga, radio->type == cariboulite_channel_s1g? caribou_fpga_smi_channel_0 : caribou_fpga_smi_channel_1);
|
||||
//caribou_fpga_set_io_ctrl_dig (&radio->sys->fpga, radio->type == cariboulite_channel_s1g? 0 : 1, 0);
|
||||
caribou_fpga_set_smi_ctrl_data_direction(&radio->sys->fpga, 1);
|
||||
|
||||
// turn on the modem RX
|
||||
cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_rx);
|
||||
|
@ -1135,7 +1168,7 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
.tx_control_with_iq_if = !radio->cw_output,
|
||||
.radio09_mode = at86rf215_iq_if_mode,
|
||||
.radio24_mode = at86rf215_iq_if_mode,
|
||||
.clock_skew = at86rf215_iq_clock_data_skew_4_906ns,
|
||||
.clock_skew = at86rf215_iq_clock_data_skew_2_906ns,
|
||||
};
|
||||
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
|
||||
|
||||
|
@ -1187,6 +1220,7 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
// apply the state
|
||||
caribou_smi_set_driver_streaming_state(&radio->sys->smi, smi_stream_tx_channel);
|
||||
caribou_fpga_set_smi_ctrl_data_direction (&radio->sys->fpga, 0);
|
||||
//cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_tx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,11 +122,13 @@ static void usage(void)
|
|||
"\t[-F force fpga reprogramming (default: '0')]\n"
|
||||
"\t[-M write metadata (default: '0')]\n"
|
||||
"\tfilename ('-' dumps samples to stdout)\n\n"
|
||||
"Example:\n"
|
||||
"\t1. Sample S1G channel at 905MHz into filename capture.bin\n"
|
||||
"\t\tcariboulite_util -c 0 -f 905000000 capture.bin\n"
|
||||
"\t2. Sample S1G channel at 905MHz into filename capture.bin, only 30000 samples\n"
|
||||
"\t\tcariboulite_util -c 0 -f 905000000 -n 30000 capture.bin\n\n");
|
||||
"Example (CS16 files readable by 'inspectrum' analyzer):\n"
|
||||
"\t1. Sample S1G channel at 905MHz into filename capture.cs16\n"
|
||||
"\t\tcariboulite_util -c 0 -f 905000000 capture.cs16\n"
|
||||
"\t2. Sample HiF channel at 2410MHz into filename capture_hif.cs16\n"
|
||||
"\t\tcariboulite_util -c 1 -f 2410000000 capture_hif.cs16\n"
|
||||
"\t3. Sample S1G channel at 905MHz into filename capture.cs16, only 30000 samples\n"
|
||||
"\t\tcariboulite_util -c 0 -f 905000000 -n 30000 capture.cs16\n\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ int rffc507x_init( rffc507x_st* dev,
|
|||
set_RFFC507X_CTMAX(dev, 127);
|
||||
set_RFFC507X_P2CTV(dev, 12);
|
||||
set_RFFC507X_FULLD(dev, 0);*/
|
||||
set_RFFC507X_P2MIXIDD(dev, 4);
|
||||
set_RFFC507X_P2MIXIDD(dev, 5);
|
||||
|
||||
// Others
|
||||
set_RFFC507X_LDEN(dev, 1);
|
||||
|
|
Ładowanie…
Reference in New Issue