Porównaj commity

...

18 Commity

Autor SHA1 Wiadomość Data
David Michaeli 5af8e900e7 Merge branch 'main' of https://github.com/cariboulabs/cariboulite 2024-02-06 18:08:22 +02:00
David Michaeli 2c7f8d9cd9 buffer flush improvement 2024-02-06 18:07:39 +02:00
alon ded5339fe6 Merge commit 'b777fb276c9b2cdfe43b1260945753b1602f42d2' 2024-02-06 16:59:40 +02:00
alon b777fb276c fixed bugs. ready to merge 2024-02-06 16:56:44 +02:00
alon cda5be1b0e removed new/delete and made backwards compatible 2024-02-06 16:56:44 +02:00
alon d4cd0f4032 optional sync out 2024-02-06 16:56:44 +02:00
alon 6050cf0627 block compiles 2024-02-06 16:56:44 +02:00
alon b8a9fe8dc0 up 2024-02-06 16:56:44 +02:00
David Michaeli 206e1cbb11 removed unwanted merge artifacts 2024-02-06 16:36:36 +02:00
David Michaeli 8bdaa6336d Merge branch 'main' of https://github.com/cariboulabs/cariboulite 2024-02-06 16:23:28 +02:00
David Michaeli 661c48b198 fixed flushing mechanism - includes double buffer streams that are also flushed 2024-02-06 16:04:18 +02:00
David Michaeli a13b719e52 module changes for flush over rpizero 2024-02-05 19:42:27 +02:00
David Michaeli 61ed2057d5
Update README.md 2024-02-04 02:14:34 +02:00
David Michaeli 793f852579
Merge pull request #183 from cariboulabs/meexmachina-patch-1
Update README.md
2024-02-04 02:06:05 +02:00
David Michaeli e0fcd18036
Update README.md 2024-02-04 02:05:17 +02:00
David Michaeli 19592fe360
Merge pull request #177 from unixpunk/patch-2
Fix issues adding Ubuntu users to dialout, root groups
2024-02-04 01:54:47 +02:00
David Michaeli 93b639da58 frame synchronization on read fix bug (seg fault) 2024-02-03 23:55:46 +02:00
unixpunk 524808c1b4
Fix issues adding Ubuntu users to dialout, root groups
the echo in the first half of 'if' had back-ticks causing execution instead of just text, but the whole statement isn't needed because re-adding the user to the group is a no-op, anyway.  space within the usermod command was causing it to fail also.
2024-01-22 12:17:33 -06:00
17 zmienionych plików z 1760 dodań i 1541 usunięć

Wyświetl plik

@ -17,6 +17,12 @@ 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.

Wyświetl plik

@ -81,6 +81,10 @@ 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;
@ -503,18 +507,12 @@ static long smi_stream_ioctl(struct file *file, unsigned int cmd, unsigned long
}
break;
}
//-------------------------------
//-------------------------------
case SMI_STREAM_IOC_FLUSH_FIFO:
{
if (mutex_lock_interruptible(&inst->read_lock))
{
return -EINTR;
}
kfifo_reset_out(&inst->rx_fifo);
mutex_unlock(&inst->read_lock);
// moved to read file operation
break;
}
}
//-------------------------------
default:
dev_err(inst->dev, "invalid ioctl cmd: %d", cmd);
@ -569,7 +567,6 @@ 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);
}
@ -604,7 +601,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)
@ -785,8 +782,9 @@ 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;
@ -798,10 +796,22 @@ 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(10);
msleep(2);
// invalidate both buffers integrity
buffer_ready[0] = 0;
buffer_ready[1] = 0;
current_dma_buffer = 0;
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)
@ -813,13 +823,14 @@ 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;
}
@ -827,20 +838,25 @@ 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
if (mutex_lock_interruptible(&inst->read_lock))
{
return -EINTR;
}
// previously filled up buffer into the kfifo - only if
// buffer is valid
start = ktime_get();
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);
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);
}
t2 = ktime_to_ns(ktime_sub(ktime_get(), start));
@ -866,13 +882,14 @@ 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;
@ -1091,17 +1108,28 @@ 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;
size_t num_bytes = 0;
unsigned int count_actual = count;
unsigned int copied = 0;
if (mutex_lock_interruptible(&inst->read_lock))
if (buf == NULL)
{
return -EINTR;
}
ret = kfifo_to_user(&inst->rx_fifo, buf, count, &copied);
mutex_unlock(&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 ret < 0 ? ret : (ssize_t)copied;
}
@ -1348,6 +1376,8 @@ 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;

Wyświetl plik

@ -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, 20000);
hif->StartReceiving(receivedSamples);
getchar();
}

Wyświetl plik

@ -35,13 +35,7 @@ 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"
if [[ "`groups ``whoami`" == *`whoami`* ]]; then
echo "` User already in the group`"
else
sudo usermod -aG dialout, root "${USER}"
fi
sudo usermod -aG dialout,root "${USER}"
fi
sudo depmod -a

Wyświetl plik

@ -33,23 +33,6 @@ 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:
@ -57,8 +40,8 @@ blocks:
alias: ''
channel: '0'
comment: ''
enable_agc: 'False'
freq: '900000000.0'
enable_agc: 'True'
freq: '905000000.0'
maxoutbuf: '0'
minoutbuf: '0'
rx_bw: '2500000.0'
@ -71,9 +54,50 @@ 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', blocks_null_sink_0, '0']
- [caribouLite_caribouLiteSource_0, '0', lora_sdr_frame_sync_0, '0']
- [lora_sdr_frame_sync_0, '0', lora_sdr_fft_demod_0, '0']
metadata:
file_format: 1

Wyświetl plik

@ -7,7 +7,7 @@ templates:
imports:
from gnuradio import caribouLite
make:
caribouLite.caribouLiteSource(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq})
caribouLite.caribouLiteSource(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq}, ${provide_meta})
parameters:
- id: channel
@ -40,10 +40,17 @@ 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});'
make: 'this->${id} = caribouLite::caribouLiteSource::make(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq}, ${provide_meta});'
packages: ['gnuradio-caribouLite']
link: ['gnuradio::gnuradio-caribouLite']
translations:
@ -57,4 +64,9 @@ outputs:
domain: stream
dtype: complex
- label: meta
domain: stream
dtype: byte
hide: ${False if str(provide_meta)=='True' else True}
file_format: 1

Wyświetl plik

@ -32,7 +32,13 @@ 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);
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);
};
} // namespace caribouLite

Wyświetl plik

@ -9,13 +9,7 @@
#include "caribouLiteSource_impl.h"
namespace gr {
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;
namespace caribouLite {
void detectBoard()
{
@ -34,18 +28,37 @@ namespace gr {
}
//-------------------------------------------------------------------------------------------------------------
caribouLiteSource::sptr caribouLiteSource::make(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq)
caribouLiteSource::sptr caribouLiteSource::make(int channel,
bool enable_agc,
float rx_gain,
float rx_bw,
float sample_rate,
float freq,
bool provide_meta)
{
return gnuradio::make_block_sptr<caribouLiteSource_impl>(channel, enable_agc, rx_gain, rx_bw, sample_rate, freq);
return gnuradio::make_block_sptr<caribouLiteSource_impl>(channel,
enable_agc,
rx_gain,
rx_bw,
sample_rate,
freq,
provide_meta);
}
// public constructor
//-------------------------------------------------------------------------------------------------------------
caribouLiteSource_impl::caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq)
caribouLiteSource_impl::caribouLiteSource_impl(int channel,
bool enable_agc,
float rx_gain,
float rx_bw,
float sample_rate,
float freq,
bool provide_meta)
: gr::sync_block("caribouLiteSource",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type)))
gr::io_signature::make(1, 2, {sizeof(gr_complex), sizeof(uint8_t)})
)
{
detectBoard();
@ -55,10 +68,11 @@ 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
@ -84,8 +98,15 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
auto out = static_cast<output_type*>(output_items[0]);
return _radio->ReadSamples(out, static_cast<size_t>(noutput_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;
}
} /* namespace caribouLite */

Wyświetl plik

@ -27,12 +27,20 @@ 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);
caribouLiteSource_impl(int channel,
bool enable_agc,
float rx_gain,
float rx_bw,
float sample_rate,
float freq,
bool provide_meta);
~caribouLiteSource_impl();
int work(

Wyświetl plik

@ -1,5 +1,5 @@
/*
* Copyright 2023 Free Software Foundation, Inc.
* Copyright 2024 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(9ce2846f2939a8b8e624a4612154ad52) */
/* BINDTOOL_HEADER_FILE_HASH(2af106876738c9927aadb177d064272d) */
/***********************************************************************************/
#include <pybind11/complex.h>
@ -30,30 +30,26 @@ 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),
D(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))
;
}

Wyświetl plik

@ -1,5 +1,5 @@
/*
* Copyright 2023 Free Software Foundation, Inc.
* Copyright 2024 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@ -15,13 +15,10 @@
*/
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";

Wyświetl plik

@ -183,8 +183,8 @@ public:
bool GetIsTransmittingCw(void);
// Synchronous Reading and Writing
int ReadSamples(std::complex<float>* samples, size_t num_to_read);
int ReadSamples(std::complex<short>* samples, size_t num_to_read);
int 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 WriteSamples(std::complex<float>* samples, size_t num_to_write);
int WriteSamples(std::complex<short>* samples, size_t num_to_write);

Wyświetl plik

@ -1,16 +1,116 @@
#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;
std::cout << " >> Signal caught: " << signal_number << std::endl << std::flush;
printf(">> DefaultSignalHandler: Signal caught (sig %d), additional information: \n", signal_number);
print_siginfo(si);
fflush(stdout);
if (cl->_on_signal_caught) cl->_on_signal_caught(signal_number);
exit(-1);
//cl->ReleaseResources();
}

Wyświetl plik

@ -1,4 +1,5 @@
#include "CaribouLite.hpp"
#include <string.h>
//=================================================================
void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio)
@ -68,9 +69,16 @@ void CaribouLiteRadio::CaribouLiteRxThread(CaribouLiteRadio* radio)
}
//==================================================================
int CaribouLiteRadio::ReadSamples(std::complex<float>* samples, size_t num_to_read)
int CaribouLiteRadio::ReadSamples(std::complex<float>* samples, size_t num_to_read, uint8_t* meta)
{
int ret = ReadSamples((std::complex<short>*)NULL, 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);
if (ret <= 0)
{
return ret;
@ -87,8 +95,15 @@ int CaribouLiteRadio::ReadSamples(std::complex<float>* samples, size_t num_to_re
}
//==================================================================
int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_read)
int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_read, uint8_t* meta)
{
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,
@ -105,6 +120,11 @@ 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;
}
@ -185,7 +205,9 @@ CaribouLiteRadio::~CaribouLiteRadio()
else
{
if (_read_samples) delete [] _read_samples;
_read_samples = NULL;
if (_read_metadata) delete [] _read_metadata;
_read_metadata = NULL;
}
}

Wyświetl plik

@ -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: %ld bytes\n", dev->native_batch_len);
printf(" native kernel chunk size: %d bytes\n", dev->native_batch_len);
}
//=========================================================================
@ -237,10 +237,11 @@ static int caribou_smi_find_buffer_offset(caribou_smi_st* dev, uint8_t *buffer,
size_t offs = 0;
bool found = false;
if (len <= 4)
if (len <= (CARIBOU_SMI_BYTES_PER_SAMPLE*4))
{
return 0;
}
//smi_utils_dump_hex(buffer, 16);
if (dev->debug_mode == caribou_smi_none)
{
@ -283,6 +284,7 @@ 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;
}
@ -623,7 +625,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;
return to_millisec * 2;
}
//=========================================================================
@ -662,7 +664,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 -1;
return -3;
}
// A special functionality for debug modes
@ -763,7 +765,7 @@ int caribou_smi_flush_fifo(caribou_smi_st* dev)
{
if (!dev) return -1;
if (!dev->initialized) return -1;
int ret = ioctl(dev->filedesc, SMI_STREAM_IOC_FLUSH_FIFO, 1);
int ret = read(dev->filedesc, NULL, 0);
if (ret != 0)
{
ZF_LOGE("failed flushing driver fifos");

Wyświetl plik

@ -1237,7 +1237,10 @@ 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");
if (ret == -1) {ZF_LOGE("SMI reading operation failed");}
else if (ret == -2) {}
else if (ret == -3) {ZF_LOGE("SMI data synchronization failed");}
}
else if (ret == 0)
{