kopia lustrzana https://github.com/cariboulabs/cariboulite
Porównaj commity
No commits in common. "5af8e900e794cb929767f4512f6b2e7bc8bbc05d" and "0967d6029802510f4925b6b13037d6e5f5f38464" have entirely different histories.
5af8e900e7
...
0967d60298
|
@ -17,12 +17,6 @@ CaribouLite is an affordable, educational, open-source SDR evaluation platform a
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
## NOTE: No Support for RPI-5
|
||||
Due to the architectural changes in RPI5 - the new I/O controller called "RP1" chip, CaribouLite is not supported on RPI5. We assume that the reason is the removal of the SMI interface altogether from the external interfaces by Broadcomm's team.
|
||||
So, if you intend to use CaribouLite on RPI5 please don't - it won't work. Why was the SMI interface deprecated by Broadcomm (either from its hardware or kernel SW support)? Most probably due to the same reason this interface was not documented in the first place - no interest in supporting a high-speed external interface within the 40-pin connector.
|
||||
|
||||
Edit: The workaround we are working to support RPI5 anyway - trying to utilize the Display and Camera I/O pins from the 40-pin connector to stream information - FPGA + Kernel module adaptation.
|
||||
|
||||
# Getting Started & Installation
|
||||
Use the following steps to install the CaribouLite on your choice of RPI board
|
||||
1. Mount the CaribouLite on a **un-powered** RPI device using the 40-pin header.
|
||||
|
|
|
@ -81,10 +81,6 @@ struct bcm2835_smi_dev_instance
|
|||
// address related
|
||||
unsigned int cur_address;
|
||||
int address_changed;
|
||||
|
||||
// flags
|
||||
int invalidate_rx_buffers;
|
||||
int invalidate_tx_buffers;
|
||||
|
||||
struct task_struct *reader_thread;
|
||||
struct task_struct *writer_thread;
|
||||
|
@ -507,12 +503,18 @@ static long smi_stream_ioctl(struct file *file, unsigned int cmd, unsigned long
|
|||
}
|
||||
break;
|
||||
}
|
||||
//-------------------------------
|
||||
//-------------------------------
|
||||
case SMI_STREAM_IOC_FLUSH_FIFO:
|
||||
{
|
||||
// moved to read file operation
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
return -EINTR;
|
||||
}
|
||||
kfifo_reset_out(&inst->rx_fifo);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
//-------------------------------
|
||||
default:
|
||||
dev_err(inst->dev, "invalid ioctl cmd: %d", cmd);
|
||||
|
@ -567,6 +569,7 @@ static void stream_smi_dma_callback_user_copy(void *param)
|
|||
{
|
||||
/* Notify the bottom half that a chunk is ready for user copy */
|
||||
struct bcm2835_smi_instance *inst = (struct bcm2835_smi_instance *)param;
|
||||
|
||||
up(&inst->bounce.callback_sem);
|
||||
}
|
||||
|
||||
|
@ -601,7 +604,7 @@ ssize_t stream_smi_user_dma( struct bcm2835_smi_instance *inst,
|
|||
spin_unlock(&inst->transaction_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
dma_async_issue_pending(inst->dma_chan);
|
||||
|
||||
if (dma_dir == DMA_DEV_TO_MEM)
|
||||
|
@ -782,9 +785,8 @@ int reader_thread_stream_function(void *pv)
|
|||
{
|
||||
int count = 0;
|
||||
int current_dma_buffer = 0;
|
||||
int buffer_ready[2] = {0, 0}; // does a certain buffer contain actual data
|
||||
struct bcm2835_smi_bounce_info *bounce = NULL;
|
||||
|
||||
|
||||
ktime_t start;
|
||||
s64 t1, t2, t3;
|
||||
|
||||
|
@ -796,22 +798,10 @@ int reader_thread_stream_function(void *pv)
|
|||
// check if the streaming state is on, if not, sleep and check again
|
||||
if (inst->state != smi_stream_rx_channel_0 && inst->state != smi_stream_rx_channel_1)
|
||||
{
|
||||
msleep(2);
|
||||
// invalidate both buffers integrity
|
||||
buffer_ready[0] = 0;
|
||||
buffer_ready[1] = 0;
|
||||
current_dma_buffer = 0;
|
||||
msleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inst->invalidate_rx_buffers)
|
||||
{
|
||||
inst->invalidate_rx_buffers = 0;
|
||||
buffer_ready[0] = 0;
|
||||
buffer_ready[1] = 0;
|
||||
current_dma_buffer = 0;
|
||||
}
|
||||
|
||||
start = ktime_get();
|
||||
// sync smi address
|
||||
if (inst->address_changed)
|
||||
|
@ -823,14 +813,13 @@ int reader_thread_stream_function(void *pv)
|
|||
//--------------------------------------------------------
|
||||
// try setup a new DMA transfer into dma bounce buffer
|
||||
// bounce will hold the current transfers state
|
||||
buffer_ready[current_dma_buffer] = 0;
|
||||
count = stream_smi_user_dma(inst->smi_inst, DMA_DEV_TO_MEM, &bounce, current_dma_buffer);
|
||||
if (count != DMA_BOUNCE_BUFFER_SIZE || bounce == NULL)
|
||||
{
|
||||
dev_err(inst->dev, "stream_smi_user_dma returned illegal count = %d, buff_num = %d", count, current_dma_buffer);
|
||||
//spin_lock(&inst->smi_inst->transaction_lock);
|
||||
//dmaengine_terminate_all(inst->smi_inst->dma_chan);
|
||||
//spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
spin_lock(&inst->smi_inst->transaction_lock);
|
||||
dmaengine_terminate_all(inst->smi_inst->dma_chan);
|
||||
spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -838,25 +827,20 @@ int reader_thread_stream_function(void *pv)
|
|||
|
||||
//--------------------------------------------------------
|
||||
// Don't wait for the buffer to fill in, copy the "other"
|
||||
// previously filled up buffer into the kfifo - only if
|
||||
// buffer is valid
|
||||
// previously filled up buffer into the kfifo
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
start = ktime_get();
|
||||
|
||||
if (buffer_ready[1-current_dma_buffer] && !inst->invalidate_rx_buffers)
|
||||
{
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
//return -EINTR;
|
||||
continue;
|
||||
}
|
||||
|
||||
kfifo_in(&inst->rx_fifo, bounce->buffer[1-current_dma_buffer], DMA_BOUNCE_BUFFER_SIZE);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
|
||||
// for the polling mechanism
|
||||
inst->readable = true;
|
||||
wake_up_interruptible(&inst->poll_event);
|
||||
}
|
||||
kfifo_in(&inst->rx_fifo, bounce->buffer[1-current_dma_buffer], DMA_BOUNCE_BUFFER_SIZE);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
|
||||
// for the polling mechanism
|
||||
inst->readable = true;
|
||||
wake_up_interruptible(&inst->poll_event);
|
||||
|
||||
t2 = ktime_to_ns(ktime_sub(ktime_get(), start));
|
||||
|
||||
|
@ -882,14 +866,13 @@ int reader_thread_stream_function(void *pv)
|
|||
if (inst->state == smi_stream_idle)
|
||||
{
|
||||
dev_info(inst->dev, "Reader state became idle, terminating dma");
|
||||
//spin_lock(&inst->smi_inst->transaction_lock);
|
||||
//dmaengine_terminate_all(inst->smi_inst->dma_chan);
|
||||
//spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
spin_lock(&inst->smi_inst->transaction_lock);
|
||||
dmaengine_terminate_all(inst->smi_inst->dma_chan);
|
||||
spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Switch the buffers
|
||||
buffer_ready[current_dma_buffer] = 1;
|
||||
current_dma_buffer = 1-current_dma_buffer;
|
||||
}
|
||||
inst->reader_waiting_sema = false;
|
||||
|
@ -1108,28 +1091,17 @@ static int smi_stream_release(struct inode *inode, struct file *file)
|
|||
static ssize_t smi_stream_read_file_fifo(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int copied = 0;
|
||||
unsigned int copied;
|
||||
size_t num_bytes = 0;
|
||||
unsigned int count_actual = count;
|
||||
|
||||
if (buf == NULL)
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
//dev_info(inst->dev, "Flushing internal rx_kfifo");
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
return -EINTR;
|
||||
}
|
||||
kfifo_reset_out(&inst->rx_fifo);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
inst->invalidate_rx_buffers = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
return -EINTR;
|
||||
}
|
||||
ret = kfifo_to_user(&inst->rx_fifo, buf, count, &copied);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
}
|
||||
return -EINTR;
|
||||
}
|
||||
ret = kfifo_to_user(&inst->rx_fifo, buf, count, &copied);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
|
||||
return ret < 0 ? ret : (ssize_t)copied;
|
||||
}
|
||||
|
||||
|
@ -1376,8 +1348,6 @@ static int smi_stream_dev_probe(struct platform_device *pdev)
|
|||
// Streaming instance initializations
|
||||
inst->reader_thread = NULL;
|
||||
inst->writer_thread = NULL;
|
||||
inst->invalidate_rx_buffers = 0;
|
||||
inst->invalidate_tx_buffers = 0;
|
||||
init_waitqueue_head(&inst->poll_event);
|
||||
inst->readable = false;
|
||||
inst->writeable = false;
|
||||
|
|
|
@ -109,7 +109,7 @@ int main ()
|
|||
try
|
||||
{
|
||||
s1g->SetFrequency(900000000);
|
||||
//s1g->FlushBuffers();
|
||||
s1g->FlushBuffers();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -125,7 +125,7 @@ int main ()
|
|||
try
|
||||
{
|
||||
hif->SetFrequency(2400000000);
|
||||
//hif->FlushBuffers();
|
||||
hif->FlushBuffers();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -133,7 +133,7 @@ int main ()
|
|||
}
|
||||
hif->SetRxGain(0);
|
||||
hif->SetAgc(false);
|
||||
hif->StartReceiving(receivedSamples);
|
||||
hif->StartReceiving(receivedSamples, 20000);
|
||||
|
||||
getchar();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,13 @@ sudo apt-get -y install swig avahi-daemon libavahi-client-dev python3-distutils
|
|||
if grep -iq "NAME=\"Ubuntu\"" /etc/os-release; then
|
||||
sudo apt-get install rpi.gpio-common
|
||||
echo "Adding user `whoami` to dialout, root groups"
|
||||
sudo usermod -aG dialout,root "${USER}"
|
||||
|
||||
if [[ "`groups ``whoami`" == *`whoami`* ]]; then
|
||||
echo "` User already in the group`"
|
||||
else
|
||||
sudo usermod -aG dialout, root "${USER}"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
sudo depmod -a
|
||||
|
|
|
@ -33,6 +33,23 @@ options:
|
|||
state: enabled
|
||||
|
||||
blocks:
|
||||
- name: blocks_null_sink_0
|
||||
id: blocks_null_sink
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
bus_structure_sink: '[[0,],]'
|
||||
comment: ''
|
||||
num_inputs: '1'
|
||||
type: complex
|
||||
vlen: '1'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [624, 256.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: caribouLite_caribouLiteSource_0
|
||||
id: caribouLite_caribouLiteSource
|
||||
parameters:
|
||||
|
@ -40,8 +57,8 @@ blocks:
|
|||
alias: ''
|
||||
channel: '0'
|
||||
comment: ''
|
||||
enable_agc: 'True'
|
||||
freq: '905000000.0'
|
||||
enable_agc: 'False'
|
||||
freq: '900000000.0'
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
rx_bw: '2500000.0'
|
||||
|
@ -54,50 +71,9 @@ blocks:
|
|||
coordinate: [296, 212.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: lora_sdr_fft_demod_0
|
||||
id: lora_sdr_fft_demod
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
comment: ''
|
||||
max_log_approx: 'True'
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
soft_decoding: soft_decoding
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [904, 252.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: lora_sdr_frame_sync_0
|
||||
id: lora_sdr_frame_sync
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
bandwidth: '500000'
|
||||
center_freq: '0'
|
||||
comment: ''
|
||||
impl_head: 'True'
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
os_factor: '4'
|
||||
preamb_len: '8'
|
||||
sf: '5'
|
||||
show_log_port: 'True'
|
||||
sync_word: '18'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [696, 236.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
|
||||
connections:
|
||||
- [caribouLite_caribouLiteSource_0, '0', lora_sdr_frame_sync_0, '0']
|
||||
- [lora_sdr_frame_sync_0, '0', lora_sdr_fft_demod_0, '0']
|
||||
- [caribouLite_caribouLiteSource_0, '0', blocks_null_sink_0, '0']
|
||||
|
||||
metadata:
|
||||
file_format: 1
|
||||
|
|
|
@ -7,7 +7,7 @@ templates:
|
|||
imports:
|
||||
from gnuradio import caribouLite
|
||||
make:
|
||||
caribouLite.caribouLiteSource(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq}, ${provide_meta})
|
||||
caribouLite.caribouLiteSource(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq})
|
||||
|
||||
parameters:
|
||||
- id: channel
|
||||
|
@ -40,17 +40,10 @@ parameters:
|
|||
dtype: float
|
||||
default: 900000000.0
|
||||
|
||||
- id: provide_meta
|
||||
label: output meta data
|
||||
dtype: enum
|
||||
options: ['True', 'False']
|
||||
hide: part
|
||||
default: 'False'
|
||||
|
||||
cpp_templates:
|
||||
includes: ['#include <gnuradio/caribouLite/caribouLiteSource.h>']
|
||||
declarations: 'caribouLite::caribouLiteSource::sptr ${id};'
|
||||
make: 'this->${id} = caribouLite::caribouLiteSource::make(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq}, ${provide_meta});'
|
||||
make: 'this->${id} = caribouLite::caribouLiteSource::make(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq});'
|
||||
packages: ['gnuradio-caribouLite']
|
||||
link: ['gnuradio::gnuradio-caribouLite']
|
||||
translations:
|
||||
|
@ -64,9 +57,4 @@ outputs:
|
|||
domain: stream
|
||||
dtype: complex
|
||||
|
||||
- label: meta
|
||||
domain: stream
|
||||
dtype: byte
|
||||
hide: ${False if str(provide_meta)=='True' else True}
|
||||
|
||||
file_format: 1
|
||||
|
|
|
@ -32,13 +32,7 @@ namespace gr {
|
|||
* class. caribouLite::caribouLiteSource::make is the public interface for
|
||||
* creating new instances.
|
||||
*/
|
||||
static sptr make(int channel=0,
|
||||
bool enable_agc=false,
|
||||
float rx_gain=40,
|
||||
float rx_bw=2500000,
|
||||
float sample_rate=4000000,
|
||||
float freq=900000000,
|
||||
bool provide_meta = false);
|
||||
static sptr make(int channel=0, bool enable_agc=false, float rx_gain=40, float rx_bw=2500000, float sample_rate=4000000, float freq=900000000);
|
||||
};
|
||||
|
||||
} // namespace caribouLite
|
||||
|
|
|
@ -9,7 +9,13 @@
|
|||
#include "caribouLiteSource_impl.h"
|
||||
|
||||
namespace gr {
|
||||
namespace caribouLite {
|
||||
namespace caribouLite {
|
||||
|
||||
#define NUM_NATIVE_MTUS_PER_QUEUE ( 10 )
|
||||
#define USE_ASYNC_OVERRIDE_WRITES ( true )
|
||||
#define USE_ASYNC_BLOCK_READS ( true )
|
||||
|
||||
using output_type = gr_complex;
|
||||
|
||||
void detectBoard()
|
||||
{
|
||||
|
@ -28,37 +34,18 @@ namespace gr {
|
|||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------
|
||||
caribouLiteSource::sptr caribouLiteSource::make(int channel,
|
||||
bool enable_agc,
|
||||
float rx_gain,
|
||||
float rx_bw,
|
||||
float sample_rate,
|
||||
float freq,
|
||||
bool provide_meta)
|
||||
caribouLiteSource::sptr caribouLiteSource::make(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq)
|
||||
{
|
||||
return gnuradio::make_block_sptr<caribouLiteSource_impl>(channel,
|
||||
enable_agc,
|
||||
rx_gain,
|
||||
rx_bw,
|
||||
sample_rate,
|
||||
freq,
|
||||
provide_meta);
|
||||
return gnuradio::make_block_sptr<caribouLiteSource_impl>(channel, enable_agc, rx_gain, rx_bw, sample_rate, freq);
|
||||
}
|
||||
|
||||
|
||||
// public constructor
|
||||
//-------------------------------------------------------------------------------------------------------------
|
||||
caribouLiteSource_impl::caribouLiteSource_impl(int channel,
|
||||
bool enable_agc,
|
||||
float rx_gain,
|
||||
float rx_bw,
|
||||
float sample_rate,
|
||||
float freq,
|
||||
bool provide_meta)
|
||||
caribouLiteSource_impl::caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq)
|
||||
: gr::sync_block("caribouLiteSource",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(1, 2, {sizeof(gr_complex), sizeof(uint8_t)})
|
||||
)
|
||||
gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type)))
|
||||
{
|
||||
detectBoard();
|
||||
|
||||
|
@ -68,11 +55,10 @@ namespace gr {
|
|||
_rx_bw = rx_bw;
|
||||
_sample_rate = sample_rate;
|
||||
_frequency = freq;
|
||||
_provide_meta = provide_meta;
|
||||
|
||||
CaribouLite &cl = CaribouLite::GetInstance(false);
|
||||
_cl = &cl;
|
||||
_radio = cl.GetRadioChannel(_channel);
|
||||
|
||||
_mtu_size = _radio->GetNativeMtuSample();
|
||||
|
||||
// setup parameters
|
||||
|
@ -98,15 +84,8 @@ namespace gr {
|
|||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
auto out_samples = static_cast<gr_complex*>(output_items[0]);
|
||||
auto out_meta = _provide_meta == true ? static_cast<uint8_t*>(output_items[1]) : (uint8_t*) NULL ;
|
||||
int ret = _radio->ReadSamples(out_samples, static_cast<size_t>(noutput_items), out_meta);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
auto out = static_cast<output_type*>(output_items[0]);
|
||||
return _radio->ReadSamples(out, static_cast<size_t>(noutput_items));
|
||||
}
|
||||
|
||||
} /* namespace caribouLite */
|
||||
|
|
|
@ -27,20 +27,12 @@ namespace gr
|
|||
float _sample_rate;
|
||||
float _frequency;
|
||||
size_t _mtu_size;
|
||||
bool _provide_meta;
|
||||
|
||||
cariboulite_sample_meta* _metadata;
|
||||
|
||||
CaribouLite* _cl;
|
||||
CaribouLiteRadio *_radio;
|
||||
|
||||
public:
|
||||
caribouLiteSource_impl(int channel,
|
||||
bool enable_agc,
|
||||
float rx_gain,
|
||||
float rx_bw,
|
||||
float sample_rate,
|
||||
float freq,
|
||||
bool provide_meta);
|
||||
caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq);
|
||||
~caribouLiteSource_impl();
|
||||
|
||||
int work(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2024 Free Software Foundation, Inc.
|
||||
* Copyright 2023 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
|
@ -14,7 +14,7 @@
|
|||
/* BINDTOOL_GEN_AUTOMATIC(0) */
|
||||
/* BINDTOOL_USE_PYGCCXML(0) */
|
||||
/* BINDTOOL_HEADER_FILE(caribouLiteSource.h) */
|
||||
/* BINDTOOL_HEADER_FILE_HASH(2af106876738c9927aadb177d064272d) */
|
||||
/* BINDTOOL_HEADER_FILE_HASH(9ce2846f2939a8b8e624a4612154ad52) */
|
||||
/***********************************************************************************/
|
||||
|
||||
#include <pybind11/complex.h>
|
||||
|
@ -30,26 +30,30 @@ namespace py = pybind11;
|
|||
void bind_caribouLiteSource(py::module& m)
|
||||
{
|
||||
|
||||
using caribouLiteSource = ::gr::caribouLite::caribouLiteSource;
|
||||
using caribouLiteSource = gr::caribouLite::caribouLiteSource;
|
||||
|
||||
|
||||
py::class_<caribouLiteSource,
|
||||
gr::sync_block,
|
||||
gr::block,
|
||||
gr::basic_block,
|
||||
std::shared_ptr<caribouLiteSource>>(
|
||||
m, "caribouLiteSource", D(caribouLiteSource))
|
||||
py::class_<caribouLiteSource, gr::sync_block, gr::block, gr::basic_block,
|
||||
std::shared_ptr<caribouLiteSource>>(m, "caribouLiteSource", D(caribouLiteSource))
|
||||
|
||||
.def(py::init(&caribouLiteSource::make),
|
||||
py::arg("channel") = 0,
|
||||
py::arg("enable_agc") = false,
|
||||
py::arg("rx_gain") = 40,
|
||||
py::arg("rx_bw") = 2500000,
|
||||
py::arg("sample_rate") = 4000000,
|
||||
py::arg("freq") = 900000000,
|
||||
py::arg("provide_meta") = false,
|
||||
D(caribouLiteSource, make))
|
||||
D(caribouLiteSource,make)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2024 Free Software Foundation, Inc.
|
||||
* Copyright 2023 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
|
@ -15,10 +15,13 @@
|
|||
*/
|
||||
|
||||
|
||||
static const char* __doc_gr_caribouLite_caribouLiteSource = R"doc()doc";
|
||||
|
||||
static const char *__doc_gr_caribouLite_caribouLiteSource = R"doc()doc";
|
||||
|
||||
|
||||
static const char* __doc_gr_caribouLite_caribouLiteSource_caribouLiteSource = R"doc()doc";
|
||||
static const char *__doc_gr_caribouLite_caribouLiteSource_caribouLiteSource = R"doc()doc";
|
||||
|
||||
|
||||
static const char* __doc_gr_caribouLite_caribouLiteSource_make = R"doc()doc";
|
||||
static const char *__doc_gr_caribouLite_caribouLiteSource_make = R"doc()doc";
|
||||
|
||||
|
||||
|
|
|
@ -183,8 +183,8 @@ public:
|
|||
bool GetIsTransmittingCw(void);
|
||||
|
||||
// Synchronous Reading and Writing
|
||||
int ReadSamples(std::complex<float>* samples, size_t num_to_read, uint8_t* meta = NULL);
|
||||
int ReadSamples(std::complex<short>* samples, size_t num_to_read, uint8_t* meta = NULL);
|
||||
int ReadSamples(std::complex<float>* samples, size_t num_to_read);
|
||||
int ReadSamples(std::complex<short>* samples, size_t num_to_read);
|
||||
int WriteSamples(std::complex<float>* samples, size_t num_to_write);
|
||||
int WriteSamples(std::complex<short>* samples, size_t num_to_write);
|
||||
|
||||
|
|
|
@ -1,116 +1,16 @@
|
|||
#include <exception>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "CaribouLite.hpp"
|
||||
|
||||
std::shared_ptr<CaribouLite> CaribouLite::_instance = nullptr;
|
||||
std::mutex CaribouLite::_instMutex;
|
||||
|
||||
//==================================================================
|
||||
static const char* decode_si_code(int signo, int si_code)
|
||||
{
|
||||
switch (signo) {
|
||||
case SIGILL:
|
||||
switch (si_code) {
|
||||
case ILL_ILLOPC: return "Illegal opcode";
|
||||
case ILL_ILLOPN: return "Illegal operand";
|
||||
case ILL_ILLADR: return "Illegal addressing mode";
|
||||
case ILL_ILLTRP: return "Illegal trap";
|
||||
case ILL_PRVOPC: return "Privileged opcode";
|
||||
case ILL_PRVREG: return "Privileged register";
|
||||
case ILL_COPROC: return "Coprocessor error";
|
||||
case ILL_BADSTK: return "Internal stack error";
|
||||
default: return "Unknown SIGILL code";
|
||||
}
|
||||
case SIGFPE:
|
||||
switch (si_code) {
|
||||
case FPE_INTDIV: return "Integer divide-by-zero";
|
||||
case FPE_INTOVF: return "Integer overflow";
|
||||
case FPE_FLTDIV: return "Floating point divide-by-zero";
|
||||
case FPE_FLTOVF: return "Floating point overflow";
|
||||
case FPE_FLTUND: return "Floating point underflow";
|
||||
case FPE_FLTRES: return "Floating point inexact result";
|
||||
case FPE_FLTINV: return "Invalid floating point operation";
|
||||
case FPE_FLTSUB: return "Subscript out of range";
|
||||
default: return "Unknown SIGFPE code";
|
||||
}
|
||||
case SIGSEGV:
|
||||
switch (si_code) {
|
||||
case SEGV_MAPERR: return "Address not mapped";
|
||||
case SEGV_ACCERR: return "Invalid permissions";
|
||||
default: return "Unknown SIGSEGV code";
|
||||
}
|
||||
case SIGBUS:
|
||||
switch (si_code) {
|
||||
case BUS_ADRALN: return "Invalid address alignment";
|
||||
case BUS_ADRERR: return "Non-existent physical address";
|
||||
case BUS_OBJERR: return "Object-specific hardware error";
|
||||
default: return "Unknown SIGBUS code";
|
||||
}
|
||||
case SIGTRAP:
|
||||
switch (si_code) {
|
||||
case TRAP_BRKPT: return "Process breakpoint";
|
||||
case TRAP_TRACE: return "Process trace trap";
|
||||
default: return "Unknown SIGTRAP code";
|
||||
}
|
||||
case SIGCHLD:
|
||||
switch (si_code) {
|
||||
case CLD_EXITED: return "Child has exited";
|
||||
case CLD_KILLED: return "Child has terminated abnormally and did not create a core file";
|
||||
case CLD_DUMPED: return "Child has terminated abnormally and created a core file";
|
||||
case CLD_TRAPPED: return "Traced child has trapped";
|
||||
case CLD_STOPPED: return "Child has stopped";
|
||||
case CLD_CONTINUED: return "Stopped child has continued";
|
||||
default: return "Unknown SIGCHLD code";
|
||||
}
|
||||
case SIGPOLL:
|
||||
switch (si_code) {
|
||||
case POLL_IN: return "Data input available";
|
||||
case POLL_OUT: return "Output buffers available";
|
||||
case POLL_MSG: return "Input message available";
|
||||
case POLL_ERR: return "I/O error";
|
||||
case POLL_PRI: return "High priority input available";
|
||||
case POLL_HUP: return "Device disconnected";
|
||||
default: return "Unknown SIGPOLL/SIGIO code";
|
||||
}
|
||||
default:
|
||||
switch(si_code)
|
||||
{
|
||||
case SI_USER: return "Signal sent by kill()";
|
||||
case SI_QUEUE: return "Signal was sent by sigqueue()";
|
||||
case SI_TIMER: return "Signal was generated by expiration of a timer set by timer_settimer()";
|
||||
case SI_ASYNCIO: return "Signal was generated by completion of an asynchronous I/O request";
|
||||
case SI_MESGQ: return "Signal was generated by arrival of a message on an empty message queue.";
|
||||
default: return "Unknown General code";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
static void print_siginfo(const siginfo_t *si)
|
||||
{
|
||||
printf(" Signal Number: %d\n", si->si_signo);
|
||||
printf(" Signal Code: %d (%s)\n", si->si_code, decode_si_code(si->si_signo, si->si_code));
|
||||
printf(" Signal Value (int): %d\n", si->si_value.sival_int);
|
||||
printf(" Signal Value (ptr): %p\n", si->si_value.sival_ptr);
|
||||
printf(" Error Number: %d => '%s'\n", si->si_errno, strerror(errno));
|
||||
printf(" Sending Process ID: %d\n", si->si_pid);
|
||||
printf(" User ID: %d\n", si->si_uid);
|
||||
printf(" Faulting Instruction Address: %p\n", si->si_addr);
|
||||
printf(" Exit Value or Signal: %d\n", si->si_status);
|
||||
printf(" Band Event for SIGPOLL: %ld\n", si->si_band);
|
||||
}
|
||||
//==================================================================
|
||||
void CaribouLite::DefaultSignalHandler(void* context, int signal_number, siginfo_t *si)
|
||||
{
|
||||
CaribouLite* cl = (CaribouLite*)context;
|
||||
printf(">> DefaultSignalHandler: Signal caught (sig %d), additional information: \n", signal_number);
|
||||
print_siginfo(si);
|
||||
fflush(stdout);
|
||||
std::cout << " >> Signal caught: " << signal_number << std::endl << std::flush;
|
||||
|
||||
if (cl->_on_signal_caught) cl->_on_signal_caught(signal_number);
|
||||
|
||||
exit(-1);
|
||||
//cl->ReleaseResources();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "CaribouLite.hpp"
|
||||
#include <string.h>
|
||||
|
||||
//=================================================================
|
||||
void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio)
|
||||
|
@ -69,16 +68,9 @@ void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio)
|
|||
}
|
||||
|
||||
//==================================================================
|
||||
int CaribouLiteRadio::ReadSamples(std::complex<float>* samples, size_t num_to_read, uint8_t* meta)
|
||||
int CaribouLiteRadio::ReadSamples(std::complex<float>* samples, size_t num_to_read)
|
||||
{
|
||||
if (samples == NULL)
|
||||
{
|
||||
printf("samples_is_null=%d", _read_samples==NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = ReadSamples((std::complex<short>*)NULL, num_to_read, meta);
|
||||
//printf("ret = %d\n", ret);
|
||||
int ret = ReadSamples((std::complex<short>*)NULL, num_to_read);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return ret;
|
||||
|
@ -95,15 +87,8 @@ int CaribouLiteRadio::ReadSamples(std::complex<float>* samples, size_t num_to_re
|
|||
}
|
||||
|
||||
//==================================================================
|
||||
int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_read, uint8_t* meta)
|
||||
int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_read)
|
||||
{
|
||||
if (!_rx_is_active || _read_samples == NULL || _read_metadata == NULL || num_to_read == 0)
|
||||
{
|
||||
printf("reading from closed stream: rx_active = %d, _read_samples_is_null=%d, _read_metadata_is_null=%d, num_to_read=%ld\n",
|
||||
_rx_is_active, _read_samples==NULL, _read_metadata==NULL, num_to_read);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = cariboulite_radio_read_samples((cariboulite_radio_state_st*)_radio,
|
||||
_read_samples,
|
||||
_read_metadata,
|
||||
|
@ -120,11 +105,6 @@ int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_re
|
|||
samples[i] = {_read_samples[i].i, _read_samples[i].q};
|
||||
}
|
||||
}
|
||||
|
||||
if (meta)
|
||||
{
|
||||
memcpy(meta, _read_metadata, (size_t)ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -205,9 +185,7 @@ CaribouLiteRadio::~CaribouLiteRadio()
|
|||
else
|
||||
{
|
||||
if (_read_samples) delete [] _read_samples;
|
||||
_read_samples = NULL;
|
||||
if (_read_metadata) delete [] _read_metadata;
|
||||
_read_metadata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ static void caribou_smi_print_smi_settings(caribou_smi_st* dev, struct smi_setti
|
|||
printf(" dma enable: %c, passthru enable: %c\n", settings->dma_enable ? 'Y':'N', settings->dma_passthrough_enable ? 'Y':'N');
|
||||
printf(" dma threshold read: %d, write: %d\n", settings->dma_read_thresh, settings->dma_write_thresh);
|
||||
printf(" dma panic threshold read: %d, write: %d\n", settings->dma_panic_read_thresh, settings->dma_panic_write_thresh);
|
||||
printf(" native kernel chunk size: %d bytes\n", dev->native_batch_len);
|
||||
printf(" native kernel chunk size: %ld bytes\n", dev->native_batch_len);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
@ -237,11 +237,10 @@ static int caribou_smi_find_buffer_offset(caribou_smi_st* dev, uint8_t *buffer,
|
|||
size_t offs = 0;
|
||||
bool found = false;
|
||||
|
||||
if (len <= (CARIBOU_SMI_BYTES_PER_SAMPLE*4))
|
||||
if (len <= 4)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//smi_utils_dump_hex(buffer, 16);
|
||||
|
||||
if (dev->debug_mode == caribou_smi_none)
|
||||
{
|
||||
|
@ -284,7 +283,6 @@ static int caribou_smi_find_buffer_offset(caribou_smi_st* dev, uint8_t *buffer,
|
|||
|
||||
if (found == false)
|
||||
{
|
||||
smi_utils_dump_hex(buffer, 16);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -625,7 +623,7 @@ static int caribou_smi_calc_read_timeout(uint32_t sample_rate, size_t len)
|
|||
{
|
||||
uint32_t to_millisec = (2 * len * 1000) / sample_rate;
|
||||
if (to_millisec < 1) to_millisec = 1;
|
||||
return to_millisec * 2;
|
||||
return to_millisec;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
@ -664,7 +662,7 @@ int caribou_smi_read(caribou_smi_st* dev, caribou_smi_channel_en channel,
|
|||
int data_affset = caribou_smi_rx_data_analyze(dev, channel, dev->read_temp_buffer, ret, sample_offset, meta_offset);
|
||||
if (data_affset < 0)
|
||||
{
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// A special functionality for debug modes
|
||||
|
@ -765,7 +763,7 @@ int caribou_smi_flush_fifo(caribou_smi_st* dev)
|
|||
{
|
||||
if (!dev) return -1;
|
||||
if (!dev->initialized) return -1;
|
||||
int ret = read(dev->filedesc, NULL, 0);
|
||||
int ret = ioctl(dev->filedesc, SMI_STREAM_IOC_FLUSH_FIFO, 1);
|
||||
if (ret != 0)
|
||||
{
|
||||
ZF_LOGE("failed flushing driver fifos");
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -1237,10 +1237,7 @@ int cariboulite_radio_read_samples(cariboulite_radio_state_st* radio,
|
|||
if (ret < 0)
|
||||
{
|
||||
// -2 reserved for debug mode
|
||||
if (ret == -1) {ZF_LOGE("SMI reading operation failed");}
|
||||
else if (ret == -2) {}
|
||||
else if (ret == -3) {ZF_LOGE("SMI data synchronization failed");}
|
||||
|
||||
if (ret == -1) ZF_LOGE("SMI reading operation failed");
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
|
|
Ładowanie…
Reference in New Issue