kopia lustrzana https://github.com/cariboulabs/cariboulite
firmware bugfix for high speed smi stansactions (>350MBit/sec)
smi driver bug fix - SMI DEACTIVATION timeoutbug_fixes_integration_tx
rodzic
568bcbc0b5
commit
44b709b142
|
@ -9,6 +9,7 @@
|
|||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <csignal>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
@ -76,7 +77,7 @@ void runSoapyProcess( SoapySDR::Device *device,
|
|||
std::cout << "Starting stream loop, press Ctrl+C to exit..." << std::endl;
|
||||
device->activateStream(stream);
|
||||
signal(SIGINT, sigIntHandler);
|
||||
|
||||
|
||||
// Main Processing Loop
|
||||
while (not loopDone)
|
||||
{
|
||||
|
@ -85,8 +86,9 @@ void runSoapyProcess( SoapySDR::Device *device,
|
|||
int ret = device->readStream(stream, (void* const*)&buff, numElems, flags, timeUS);
|
||||
if (ret < 0)
|
||||
{
|
||||
std::cerr << "Unexpected stream error " << ret << std::endl;
|
||||
break;
|
||||
//std::cerr << "Unexpected stream error " << ret << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
#-----------------------
|
||||
# IMPORTS
|
||||
#-----------------------
|
||||
from PySimpleGUI.PySimpleGUI import Canvas, Column
|
||||
from PySimpleGUI import Window, WIN_CLOSED, Slider, Button, theme, Text, Radio, Image, InputText, Canvas
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
|
||||
import numpy as np
|
||||
from numpy.lib.arraypad import pad
|
||||
import time
|
||||
import SoapySDR
|
||||
from SoapySDR import SOAPY_SDR_RX, SOAPY_SDR_TX, SOAPY_SDR_CS16
|
||||
|
||||
#-------------------------
|
||||
# GUI
|
||||
#-------------------------
|
||||
def create_window(sensors):
|
||||
sensors_ctrls = []
|
||||
for i in range(len(sensors)):
|
||||
sensors_ctrls.append(Text(sensors[i] + ": "))
|
||||
sensors_ctrls.append(InputText('0.0', key=sensors[i]))
|
||||
|
||||
layout = [
|
||||
[Column(
|
||||
layout=[
|
||||
[Text('Receiver Freq. [Hz]:'), InputText('868000000', key='RxFreq'), Text('RX Bandwidth: 2.5 MHz')],
|
||||
]
|
||||
)],
|
||||
[Canvas(key='controls_cv')],
|
||||
[Column(
|
||||
layout=[
|
||||
[Canvas(key='fig_cv', size=(1000, 600))]
|
||||
],
|
||||
background_color='#DAE0E6',
|
||||
pad=(0,0)
|
||||
)],
|
||||
sensors_ctrls,
|
||||
[Button("Exit", size=(10,1)), Button("Run", size=(10,1))],
|
||||
]
|
||||
window = Window("CaribouLite Capture", layout, location=(1000,700))
|
||||
return window
|
||||
|
||||
|
||||
def update_iq_graphs(window, I, Q, f, psd):
|
||||
plt.figure(1).clf()
|
||||
fig = plt.gcf()
|
||||
DPI = fig.get_dpi()
|
||||
|
||||
fig.set_size_inches(304*4/float(DPI), 304/float(DPI))
|
||||
axs = fig.add_subplot(121)
|
||||
plt.plot(I, label="I")
|
||||
plt.plot(Q, label="Q")
|
||||
plt.legend(loc='upper center')
|
||||
plt.title('I/Q')
|
||||
|
||||
plt.subplot(122)
|
||||
plt.plot(f, psd)
|
||||
plt.title('PSD')
|
||||
|
||||
plt.grid()
|
||||
draw_figure_with_toolbar(window['fig_cv'].TKCanvas, fig, window['controls_cv'].TKCanvas)
|
||||
|
||||
def draw_figure_with_toolbar(canvas, fig, canvas_toolbar):
|
||||
if canvas.children:
|
||||
for child in canvas.winfo_children():
|
||||
child.destroy()
|
||||
if canvas_toolbar.children:
|
||||
for child in canvas_toolbar.winfo_children():
|
||||
child.destroy()
|
||||
|
||||
figure_canvas_agg = FigureCanvasTkAgg(fig, master=canvas)
|
||||
figure_canvas_agg.draw()
|
||||
|
||||
toolbar = Toolbar(figure_canvas_agg, canvas_toolbar)
|
||||
toolbar.update()
|
||||
figure_canvas_agg.get_tk_widget().pack(side='right', fill='both', expand=1)
|
||||
|
||||
#-------------------------
|
||||
# SOAPY
|
||||
#-------------------------
|
||||
def setup_receiver(sdr, freq_hz):
|
||||
use_agc = False
|
||||
sdr.setGainMode(SOAPY_SDR_RX, 0, use_agc)
|
||||
sdr.setGain(SOAPY_SDR_RX, 0, 0)
|
||||
sdr.setBandwidth(SOAPY_SDR_RX, 0, 2500e5)
|
||||
sdr.setFrequency(SOAPY_SDR_RX, 0, freq_hz)
|
||||
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0])
|
||||
return rx_stream
|
||||
|
||||
|
||||
def update_receiver_freq(sdr, stream, freq_hz):
|
||||
sdr.setFrequency(SOAPY_SDR_RX, 0, freq_hz)
|
||||
|
||||
class Toolbar(NavigationToolbar2Tk):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Toolbar, self).__init__(*args,**kwargs)
|
||||
|
||||
def calculate_psd(I, Q, fs):
|
||||
x = I + 1j*Q
|
||||
N = (int)(len(I) / 16)
|
||||
x = x[0:N]
|
||||
x = x * np.hamming(len(x)) # apply a Hamming window
|
||||
PSD = (np.abs(np.fft.fft(x))/N)**2
|
||||
PSD_log = 10.0*np.log10(PSD)
|
||||
PSD_shifted = np.fft.fftshift(PSD_log)
|
||||
f = np.arange(fs/-2.0, fs/2.0, fs/N) # start, stop, step. centered around 0 Hz
|
||||
return f,PSD_shifted
|
||||
|
||||
|
||||
|
||||
#-----------------------
|
||||
# MAIN
|
||||
#-----------------------
|
||||
def main():
|
||||
# Buffer Parameters
|
||||
N = 131072
|
||||
Fs = 4e6
|
||||
rx_buff = np.empty(2 * N, np.int16) # Create memory buffer for data stream
|
||||
|
||||
# Initialize CaribouLite Soapy
|
||||
#sdr = SoapySDR.Device({"driver": "Cariboulite", "channel": "S1G"})
|
||||
sdr = SoapySDR.Device({"driver": "Cariboulite", "channel": "HiF"})
|
||||
rx_stream = setup_receiver(sdr, 900e6)
|
||||
sensors_list = sdr.listSensors(SOAPY_SDR_RX, 0)
|
||||
|
||||
# Create the window
|
||||
window = create_window(sensors_list)
|
||||
while True:
|
||||
event, values = window.read(timeout = 20)
|
||||
|
||||
#---------------------------------------------
|
||||
if (event == "Exit" or event == WIN_CLOSED):
|
||||
break;
|
||||
|
||||
#---------------------------------------------
|
||||
elif event == "Run":
|
||||
print("clicked run")
|
||||
rx_freq = float(values['RxFreq'])
|
||||
update_receiver_freq(sdr, rx_stream, rx_freq)
|
||||
|
||||
sdr.activateStream(rx_stream)
|
||||
|
||||
for ii in range(10):
|
||||
sr = sdr.readStream(rx_stream, [rx_buff], N, timeoutUs=int(5e6))
|
||||
|
||||
sr = sdr.readStream(rx_stream, [rx_buff], N, timeoutUs=int(5e6))
|
||||
if (sr.ret != N):
|
||||
print("Error Reading Samples from Device (error code = %d)!" % sr.ret)
|
||||
continue;
|
||||
|
||||
sdr.deactivateStream(rx_stream)
|
||||
|
||||
s_real = rx_buff[::2].astype(np.float32)
|
||||
s_imag = rx_buff[1::2].astype(np.float32)
|
||||
|
||||
f, psd = calculate_psd(s_real, s_imag, Fs)
|
||||
|
||||
update_iq_graphs(window, s_real, s_imag, f, psd)
|
||||
|
||||
else:
|
||||
for i in range(len(sensors_list)):
|
||||
values[sensors_list[i]] = str(sdr.readSensor(SOAPY_SDR_RX, 0, sensors_list[i]))
|
||||
|
||||
|
||||
# Stop streaming and close the connection to the radio
|
||||
window.close()
|
||||
sdr.closeStream(rx_stream)
|
||||
|
||||
|
||||
|
||||
# run the program
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,84 +0,0 @@
|
|||
# PySimpleGUI
|
||||
from PySimpleGUI.PySimpleGUI import Canvas, Column
|
||||
from PySimpleGUI import Window, WIN_CLOSED, Slider, Button, theme, Text, Radio, Image, InputText, Canvas
|
||||
|
||||
# Numpy
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
|
||||
import numpy as np
|
||||
from numpy.lib.arraypad import pad
|
||||
|
||||
# System
|
||||
import time
|
||||
|
||||
# Soapy
|
||||
import SoapySDR
|
||||
from SoapySDR import SOAPY_SDR_RX, SOAPY_SDR_TX, SOAPY_SDR_CS16
|
||||
|
||||
|
||||
def setup_receiver(sdr, freq_hz):
|
||||
use_agc = False
|
||||
sdr.setGainMode(SOAPY_SDR_RX, 0, use_agc)
|
||||
sdr.setGain(SOAPY_SDR_RX, 0, 50)
|
||||
sdr.setBandwidth(SOAPY_SDR_RX, 0, 2500e5)
|
||||
sdr.setFrequency(SOAPY_SDR_RX, 0, freq_hz)
|
||||
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [0])
|
||||
return rx_stream
|
||||
|
||||
|
||||
def update_receiver_freq(sdr, stream, channel, freq_hz):
|
||||
sdr.setFrequency(SOAPY_SDR_RX, channel, freq_hz)
|
||||
|
||||
|
||||
##
|
||||
## GLOBAL AREA
|
||||
##
|
||||
|
||||
# Data and Source Configuration
|
||||
Fs = 4e6
|
||||
N = int(Fs/4) # Number of complex samples per transfer
|
||||
rx_buff = np.empty(2 * N, np.int16) # Create memory buffer for data stream
|
||||
freq = 1090e6
|
||||
|
||||
# Initialize CaribouLite Soapy
|
||||
sdr = SoapySDR.Device({"driver": "Cariboulite", "device_id": "1"})
|
||||
rx_stream = setup_receiver(sdr, freq)
|
||||
sdr.activateStream(rx_stream)
|
||||
|
||||
sr = sdr.readStream(rx_stream, [rx_buff], N, timeoutUs=int(5e6))
|
||||
# Make sure that the proper number of samples was read
|
||||
rc = sr.ret
|
||||
if (rc != N):
|
||||
print("Error Reading Samples from Device (error code = %d)!" % rc)
|
||||
exit
|
||||
|
||||
s_real = rx_buff[::2].astype(np.float32) / 4096.0
|
||||
s_imag = rx_buff[1::2].astype(np.float32) / 4096.0
|
||||
x = s_real + 1j*s_imag
|
||||
|
||||
## PSD
|
||||
|
||||
#N = 2048
|
||||
#x = x[0:N] # we will only take the FFT of the first 1024 samples, see text below
|
||||
#x = x * np.hamming(len(x)) # apply a Hamming window
|
||||
|
||||
#PSD = (np.abs(np.fft.fft(x))/N)**2
|
||||
#PSD_log = 10.0*np.log10(PSD)
|
||||
#PSD_shifted = np.fft.fftshift(PSD_log)
|
||||
|
||||
#center_freq = freq
|
||||
#f = np.arange(Fs/-2.0, Fs/2.0, Fs/N) # start, stop, step. centered around 0 Hz
|
||||
#f += center_freq # now add center frequency
|
||||
|
||||
window_size = 2048
|
||||
overlap = window_size - 64
|
||||
|
||||
fig = plt.figure()
|
||||
#plt.plot(f, PSD_shifted)
|
||||
plt.specgram(x, NFFT=window_size, Fs=Fs, noverlap=overlap, mode='psd')
|
||||
plt.show()
|
||||
|
||||
#fig = plt.figure()
|
||||
#plt.plot(s_real)
|
||||
#plt.plot(s_imag)
|
||||
#plt.show()
|
Plik diff jest za duży
Load Diff
|
@ -89,6 +89,7 @@ module smi_ctrl ( input i_rst_b,
|
|||
reg r_channel;
|
||||
assign o_channel = r_channel;
|
||||
reg [7:0] r_smi_test_count;
|
||||
reg [31:0] r_fifo_pulled_data;
|
||||
|
||||
wire soe_and_reset;
|
||||
assign soe_and_reset = i_rst_b & i_smi_soe_se;
|
||||
|
@ -98,8 +99,10 @@ module smi_ctrl ( input i_rst_b,
|
|||
if (i_rst_b == 1'b0) begin
|
||||
int_cnt <= 5'd31;
|
||||
r_smi_test_count <= 8'h56;
|
||||
r_fifo_pulled_data <= 32'h00000000;
|
||||
end else begin
|
||||
w_fifo_pull_trigger <= (int_cnt == 5'd7) && !i_smi_test;
|
||||
// trigger the fifo pulling on the second byte
|
||||
w_fifo_pull_trigger <= (int_cnt == 5'd23) && !i_smi_test;
|
||||
|
||||
if ( i_smi_test ) begin
|
||||
if (r_smi_test_count == 0) begin
|
||||
|
@ -110,7 +113,12 @@ module smi_ctrl ( input i_rst_b,
|
|||
end
|
||||
end else begin
|
||||
int_cnt <= int_cnt - 8;
|
||||
o_smi_data_out <= i_fifo_pulled_data[int_cnt:int_cnt-7];
|
||||
o_smi_data_out <= r_fifo_pulled_data[int_cnt:int_cnt-7];
|
||||
|
||||
// update the internal register as soon as we reach the fourth byte
|
||||
if (int_cnt == 5'd7) begin
|
||||
r_fifo_pulled_data <= i_fifo_pulled_data;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
17274
firmware/top.asc
17274
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.
2502
firmware/top.blif
2502
firmware/top.blif
Plik diff jest za duży
Load Diff
13351
firmware/top.json
13351
firmware/top.json
Plik diff jest za duży
Load Diff
|
@ -8,6 +8,8 @@ CYAN='\033[0;36m'
|
|||
NC='\033[0m' # No Color
|
||||
ERROR="0"
|
||||
|
||||
[ $(id -u) = 0 ] && echo "Please do not run this script as root" && exit 100
|
||||
|
||||
# update the git repo on develop_R1 branch to include sub-modules
|
||||
printf "\n[ 1 ] ${GREEN}CaribouLite Git Repo${NC}\n"
|
||||
#git checkout develop_R1
|
||||
|
|
|
@ -420,7 +420,7 @@ static void modem_rx_iq(sys_st *sys)
|
|||
bool pull_debug = false;
|
||||
bool lfsr_debug = false;
|
||||
double current_freq_lo = 900e6;
|
||||
double current_freq_hi = 2400e6;
|
||||
double current_freq_hi = 900e6;
|
||||
|
||||
iq_test_reader_st ctrl = {0};
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ static int caribou_smi_find_buffer_offset(caribou_smi_st* dev, uint8_t *buffer,
|
|||
|
||||
if (dev->debug_mode == caribou_smi_none)
|
||||
{
|
||||
for (offs = 0; offs<(len-4); offs++)
|
||||
for (offs = 0; offs<(len-CARIBOU_SMI_BYTES_PER_SAMPLE); offs++)
|
||||
{
|
||||
uint32_t s = __builtin_bswap32(*((uint32_t*)(&buffer[offs])));
|
||||
|
||||
|
@ -206,7 +206,7 @@ static int caribou_smi_find_buffer_offset(caribou_smi_st* dev, uint8_t *buffer,
|
|||
}
|
||||
else if (dev->debug_mode == caribou_smi_push || dev->debug_mode == caribou_smi_pull)
|
||||
{
|
||||
for (offs = 0; offs<(len-4); offs++)
|
||||
for (offs = 0; offs<(len-CARIBOU_SMI_BYTES_PER_SAMPLE); offs++)
|
||||
{
|
||||
uint32_t s = /*__builtin_bswap32*/(*((uint32_t*)(&buffer[offs])));
|
||||
//printf("%d => %08X, %08X\n", offs, s, caribou_smi_count_bit(s^CARIBOU_SMI_DEBUG_WORD));
|
||||
|
@ -238,8 +238,8 @@ static int caribou_smi_rx_data_analyze(caribou_smi_st* dev,
|
|||
caribou_smi_sample_meta* meta_offset)
|
||||
{
|
||||
int offs = 0;
|
||||
size_t actual_length = data_length;
|
||||
int size_shortening_samples = 0;
|
||||
size_t actual_length = data_length; // in bytes
|
||||
int size_shortening_samples = 0; // in samples
|
||||
uint32_t *actual_samples = (uint32_t*)(data);
|
||||
|
||||
caribou_smi_sample_complex_int16* cmplx_vec = samples_out;
|
||||
|
@ -255,8 +255,8 @@ static int caribou_smi_rx_data_analyze(caribou_smi_st* dev,
|
|||
// this may be accompanied by a few samples losses (sphoradic OS
|
||||
// scheduling) thus trying to stitch buffers one to another may
|
||||
// be not effective. The single sample is interpolated
|
||||
size_shortening_samples = (offs > 0) ? (offs / 4 + 1) : 0;
|
||||
actual_length -= size_shortening_samples * 4;
|
||||
size_shortening_samples = (offs > 0) ? (offs / CARIBOU_SMI_BYTES_PER_SAMPLE + 1) : 0;
|
||||
actual_length -= size_shortening_samples * CARIBOU_SMI_BYTES_PER_SAMPLE;
|
||||
actual_samples = (uint32_t*)(data + offs);
|
||||
|
||||
// analyze the data
|
||||
|
@ -274,7 +274,7 @@ static int caribou_smi_rx_data_analyze(caribou_smi_st* dev,
|
|||
// [31:30] [ 29:17 ] [ 16 ] [ 15:14 ] [ 13:1 ] [ 0 ]
|
||||
// [ '10'] [ I sample ] [ '0' ] [ '01' ] [ Q sample ] [ 'S' ]
|
||||
|
||||
for (i = 0; i < actual_length / 4; i++)
|
||||
for (i = 0; i < actual_length / CARIBOU_SMI_BYTES_PER_SAMPLE; i++)
|
||||
{
|
||||
uint32_t s = __builtin_bswap32(actual_samples[i]);
|
||||
|
||||
|
@ -292,11 +292,14 @@ static int caribou_smi_rx_data_analyze(caribou_smi_st* dev,
|
|||
}
|
||||
}
|
||||
|
||||
// last sample insterpolation (linear for I and Q)
|
||||
// last sample insterpolation (linear for I and Q or preserve)
|
||||
if (size_shortening_samples > 0)
|
||||
{
|
||||
cmplx_vec[i].i = 2*cmplx_vec[i-1].i - cmplx_vec[i-2].i;
|
||||
cmplx_vec[i].q = 2*cmplx_vec[i-1].q - cmplx_vec[i-2].q;
|
||||
//cmplx_vec[i].i = 2*cmplx_vec[i-1].i - cmplx_vec[i-2].i;
|
||||
//cmplx_vec[i].q = 2*cmplx_vec[i-1].q - cmplx_vec[i-2].q;
|
||||
|
||||
cmplx_vec[i].i = 110*cmplx_vec[i-1].i/100 - cmplx_vec[i-2].i/10;
|
||||
cmplx_vec[i].q = 110*cmplx_vec[i-1].q/100 - cmplx_vec[i-2].q/10;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,7 +413,13 @@ static int caribou_smi_timeout_read(caribou_smi_st* dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return read(dev->filedesc, buffer, len);
|
||||
int ret = read(dev->filedesc, buffer, len);
|
||||
|
||||
/*if (ret > 16)
|
||||
{
|
||||
smi_utils_dump_hex(buffer, 16);
|
||||
}*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
@ -539,7 +548,6 @@ int caribou_smi_read(caribou_smi_st* dev, caribou_smi_channel_en channel,
|
|||
else
|
||||
{
|
||||
int data_affset = caribou_smi_rx_data_analyze(dev, dev->read_temp_buffer, ret, sample_offset, meta_offset);
|
||||
|
||||
if (data_affset < 0)
|
||||
{
|
||||
return -1;
|
||||
|
|
|
@ -259,7 +259,7 @@ static int smi_init_programmed_read(struct bcm2835_smi_instance *smi_inst, int n
|
|||
smics_temp = read_smi_reg(smi_inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE);
|
||||
write_smi_reg(smi_inst, smics_temp, SMICS);
|
||||
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_enabled(smi_inst), 5000, success);
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_enabled(smi_inst), 10000U, success);
|
||||
if (!success)
|
||||
{
|
||||
return -1;
|
||||
|
@ -275,10 +275,10 @@ static int smi_init_programmed_read(struct bcm2835_smi_instance *smi_inst, int n
|
|||
|
||||
/* Just to be certain: */
|
||||
mb();
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_is_active(smi_inst), 5000, success);
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_is_active(smi_inst), 20000U, success);
|
||||
if (!success)
|
||||
{
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
//set_address_direction(smi_stream_dir_device_to_smi);
|
||||
write_smi_reg(smi_inst, smics_temp, SMICS);
|
||||
|
@ -297,7 +297,7 @@ static int smi_init_programmed_write(struct bcm2835_smi_instance *smi_inst, int
|
|||
smics_temp = read_smi_reg(smi_inst, SMICS) & ~SMICS_ENABLE;
|
||||
write_smi_reg(smi_inst, smics_temp, SMICS);
|
||||
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_enabled(smi_inst), 5000, success);
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_enabled(smi_inst), 20000U, success);
|
||||
if (!success)
|
||||
{
|
||||
return -1;
|
||||
|
@ -465,17 +465,13 @@ ssize_t stream_smi_user_dma( struct bcm2835_smi_instance *inst,
|
|||
return 0;
|
||||
}*/
|
||||
|
||||
//printk(KERN_ERR DRIVER_NAME": SEMA-INIT\n");
|
||||
sema_init(&inst->bounce.callback_sem, 0);
|
||||
|
||||
//printk(KERN_ERR DRIVER_NAME": BOUNCE\n");
|
||||
|
||||
if (bounce)
|
||||
{
|
||||
*bounce = &(inst->bounce);
|
||||
}
|
||||
|
||||
//printk(KERN_ERR DRIVER_NAME": SGL\n");
|
||||
sgl = &(inst->bounce.sgl[buff_num]);
|
||||
if (sgl == NULL)
|
||||
{
|
||||
|
@ -483,8 +479,7 @@ ssize_t stream_smi_user_dma( struct bcm2835_smi_instance *inst,
|
|||
spin_unlock(&inst->transaction_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//printk(KERN_ERR DRIVER_NAME": SUBMIT SGL\n");
|
||||
|
||||
if (!stream_smi_dma_submit_sgl(inst, sgl, 1, dma_dir, stream_smi_dma_callback_user_copy))
|
||||
{
|
||||
dev_err(inst->dev, "sgl submit failed");
|
||||
|
@ -497,17 +492,21 @@ ssize_t stream_smi_user_dma( struct bcm2835_smi_instance *inst,
|
|||
// we have only 8 bit width
|
||||
if (dma_dir == DMA_DEV_TO_MEM)
|
||||
{
|
||||
if (smi_init_programmed_read(inst, DMA_BOUNCE_BUFFER_SIZE) != 0)
|
||||
int ret = smi_init_programmed_read(inst, DMA_BOUNCE_BUFFER_SIZE);
|
||||
if (ret != 0)
|
||||
{
|
||||
spin_unlock(&inst->transaction_lock);
|
||||
//dev_err(inst->dev, "smi_init_programmed_read returned %d", ret);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (smi_init_programmed_write(inst, DMA_BOUNCE_BUFFER_SIZE) != 0)
|
||||
int ret = smi_init_programmed_write(inst, DMA_BOUNCE_BUFFER_SIZE);
|
||||
if (ret != 0)
|
||||
{
|
||||
spin_unlock(&inst->transaction_lock);
|
||||
//dev_err(inst->dev, "smi_init_programmed_write returned %d", ret);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -548,7 +547,8 @@ int reader_thread_stream_function(void *pv)
|
|||
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, "reader_thread return illegal count = %d", count);
|
||||
dev_err(inst->dev, "reader_thread return illegal count = %d", count);
|
||||
//current_dma_buffer = 1-current_dma_buffer;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -590,6 +590,9 @@ int reader_thread_stream_function(void *pv)
|
|||
}
|
||||
else
|
||||
{
|
||||
//--------------------------------------------------------
|
||||
// Switch the buffers
|
||||
current_dma_buffer = 1-current_dma_buffer;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -605,10 +608,6 @@ int reader_thread_stream_function(void *pv)
|
|||
}
|
||||
t3 = ktime_to_ns(ktime_sub(ktime_get(), start));
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Switch the buffers
|
||||
current_dma_buffer = 1-current_dma_buffer;
|
||||
|
||||
//dev_info(inst->dev, "TIMING (1,2,3): %lld %lld %lld %d", (long long)t1, (long long)t2, (long long)t3, current_dma_buffer);
|
||||
}
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -5,18 +5,18 @@
|
|||
|
||||
|
||||
#define NUM_BYTES_PER_CPLX_ELEM ( sizeof(caribou_smi_sample_complex_int16) )
|
||||
#define NUM_NATIVE_MTUS_PER_QUEUE ( 5 )
|
||||
#define NUM_NATIVE_MTUS_PER_QUEUE ( 10 )
|
||||
|
||||
//=================================================================
|
||||
void ReaderThread(SoapySDR::Stream* stream)
|
||||
{
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "Enterring Reader Thread");
|
||||
/*SoapySDR_logf(SOAPY_SDR_INFO, "Enterring Reader Thread");
|
||||
|
||||
while (stream->readerThreadRunning())
|
||||
{
|
||||
if (!stream->stream_active)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,10 @@ void ReaderThread(SoapySDR::Stream* stream)
|
|||
ret = 0;
|
||||
}
|
||||
|
||||
stream->rx_queue->put(stream->interm_native_buffer1, ret);
|
||||
if (ret && !stream->rx_queue->full()) stream->rx_queue->put(stream->interm_native_buffer1, ret);
|
||||
}
|
||||
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "Leaving Reader Thread");
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "Leaving Reader Thread");*/
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
@ -50,8 +50,8 @@ SoapySDR::Stream::Stream(cariboulite_radio_state_st *radio)
|
|||
SoapySDR_logf(SOAPY_SDR_INFO, "Creating SampleQueue MTU: %d I/Q samples (%d bytes)",
|
||||
mtu_size, mtu_size * sizeof(caribou_smi_sample_complex_int16));
|
||||
|
||||
rx_queue = new circular_buffer<caribou_smi_sample_complex_int16>(
|
||||
mtu_size * NUM_NATIVE_MTUS_PER_QUEUE);
|
||||
/*rx_queue = new circular_buffer<caribou_smi_sample_complex_int16>(
|
||||
mtu_size * NUM_NATIVE_MTUS_PER_QUEUE);*/
|
||||
|
||||
// create the actual native queue
|
||||
format = CARIBOULITE_FORMAT_INT16;
|
||||
|
@ -59,8 +59,8 @@ SoapySDR::Stream::Stream(cariboulite_radio_state_st *radio)
|
|||
// Init the internal IIR filters
|
||||
// a buffer for conversion between native and emulated formats
|
||||
// the maximal size is the twice the MTU
|
||||
interm_native_buffer1 = new caribou_smi_sample_complex_int16[mtu_size];
|
||||
interm_native_buffer2 = new caribou_smi_sample_complex_int16[mtu_size];
|
||||
//interm_native_buffer1 = new caribou_smi_sample_complex_int16[2*mtu_size];
|
||||
interm_native_buffer2 = new caribou_smi_sample_complex_int16[2*mtu_size];
|
||||
interm_native_meta = new caribou_smi_sample_meta[2 * mtu_size];
|
||||
|
||||
filterType = DigitalFilter_None;
|
||||
|
@ -76,9 +76,9 @@ SoapySDR::Stream::Stream(cariboulite_radio_state_st *radio)
|
|||
filt100_q.setup(4e6, 100e3/2);
|
||||
filt2p5M_q.setup(4e6, 2.5e6/2);
|
||||
|
||||
reader_thread_running = 1;
|
||||
/*reader_thread_running = 1;
|
||||
stream_active = 0;
|
||||
reader_thread = new std::thread(ReaderThread, this);
|
||||
reader_thread = new std::thread(ReaderThread, this);*/
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
@ -88,12 +88,12 @@ SoapySDR::Stream::~Stream()
|
|||
filter_i = NULL;
|
||||
filter_q = NULL;
|
||||
|
||||
stream_active = 0;
|
||||
/*stream_active = 0;
|
||||
reader_thread_running = 0;
|
||||
reader_thread->join();
|
||||
delete reader_thread;
|
||||
delete reader_thread;*/
|
||||
|
||||
delete[] interm_native_buffer1;
|
||||
//delete[] interm_native_buffer1;
|
||||
delete[] interm_native_buffer2;
|
||||
delete[] interm_native_meta;
|
||||
delete rx_queue;
|
||||
|
@ -164,8 +164,21 @@ int SoapySDR::Stream::Write(caribou_smi_sample_complex_int16 *buffer, size_t num
|
|||
//=================================================================
|
||||
int SoapySDR::Stream::Read(caribou_smi_sample_complex_int16 *buffer, size_t num_samples, uint8_t *meta, long timeout_us)
|
||||
{
|
||||
if (rx_queue->size() < num_samples) return -1;
|
||||
return rx_queue->get(buffer, num_samples);
|
||||
//printf("%d\n", rx_queue->size());
|
||||
//if (rx_queue->size() < num_samples) return -1;
|
||||
//return rx_queue->get(buffer, num_samples);
|
||||
int ret = cariboulite_radio_read_samples(radio, buffer, (caribou_smi_sample_meta*)meta, num_samples);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret == -1)
|
||||
{
|
||||
printf("reader thread failed to read SMI!\n");
|
||||
}
|
||||
// a special case for debug streams which are not
|
||||
// taken care of in the soapy front-end (ret = -2)
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
@ -174,7 +187,7 @@ int SoapySDR::Stream::ReadSamples(caribou_smi_sample_complex_int16* buffer, size
|
|||
int res = Read(buffer, num_elements, NULL, timeout_us);
|
||||
if (res < 0)
|
||||
{
|
||||
SoapySDR_logf(SOAPY_SDR_ERROR, "Reading %d elements failed from queue", num_elements);
|
||||
//SoapySDR_logf(SOAPY_SDR_ERROR, "Reading %d elements failed from queue", num_elements);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,9 @@ int Cariboulite::activateStream(SoapySDR::Stream *stream,
|
|||
const size_t numElems)
|
||||
{
|
||||
stream->activateStream(1);
|
||||
return cariboulite_radio_activate_channel(&radio, stream->getInnerStreamType(), true);
|
||||
int ret = cariboulite_radio_activate_channel(&radio, stream->getInnerStreamType(), true);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
return ret;
|
||||
}
|
||||
|
||||
//========================================================
|
||||
|
|
Ładowanie…
Reference in New Issue