kopia lustrzana https://github.com/cariboulabs/cariboulite
bug fixes, python
rodzic
f704da6c93
commit
d465c5b425
|
@ -1,49 +1,57 @@
|
|||
from PySimpleGUI.PySimpleGUI import Canvas, Column
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
|
||||
import SoapySDR
|
||||
from SoapySDR import SOAPY_SDR_RX, SOAPY_SDR_CS16
|
||||
from SoapySDR import SOAPY_SDR_RX, SOAPY_SDR_TX, SOAPY_SDR_CS16
|
||||
from PySimpleGUI import Window, WIN_CLOSED, Slider, Button, theme, Text, Radio, Image
|
||||
from numpy.lib.arraypad import pad
|
||||
|
||||
# Enumerate the Soapy devices
|
||||
res = SoapySDR.Device.enumerate()
|
||||
for result in res:
|
||||
print(result)
|
||||
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()
|
||||
|
||||
# Data and Source Configuration
|
||||
rx_chan = 1 # RX1 = 0, RX2 = 1
|
||||
N = 16384 # Number of complex samples per transfer
|
||||
fs = 4e6 # Radio sample Rate
|
||||
freq = 868e6 # LO tuning frequency in Hz
|
||||
use_agc = True # Use or don't use the AGC
|
||||
timeout_us = int(5e6)
|
||||
toolbar = Toolbar(figure_canvas_agg, canvas_toolbar)
|
||||
toolbar.update()
|
||||
figure_canvas_agg.get_tk_widget().pack(side='right', fill='both', expand=1)
|
||||
|
||||
# Initialize CaribouLite
|
||||
sdr = SoapySDR.Device(dict(driver="Cariboulite")) # Create Cariboulite
|
||||
sdr.setSampleRate(SOAPY_SDR_RX, rx_chan, fs) # Set sample rate
|
||||
sdr.setGainMode(SOAPY_SDR_RX, rx_chan, use_agc) # Set the gain mode
|
||||
sdr.setFrequency(SOAPY_SDR_RX, rx_chan, freq) # Tune the LO
|
||||
sdr.setBandwidth(SOAPY_SDR_RX, rx_chan, 2.5e6)
|
||||
|
||||
# Create data buffer and start streaming samples to it
|
||||
rx_buff = np.empty(2 * N, np.int16) # Create memory buffer for data stream
|
||||
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [
|
||||
rx_chan]) # Setup data stream
|
||||
sdr.activateStream(rx_stream) # this turns the radio on
|
||||
class Toolbar(NavigationToolbar2Tk):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Toolbar, self).__init__(*args,**kwargs)
|
||||
|
||||
# Save the file names for plotting later. Remove if not plotting.
|
||||
file_names = []
|
||||
file_ctr = 0
|
||||
|
||||
nfiles = 1
|
||||
def create_window():
|
||||
#theme("Default")
|
||||
layout = [
|
||||
[Column(
|
||||
layout=[
|
||||
[Text('Receiver LO')],
|
||||
[Text('Transmitter Fc')]
|
||||
]
|
||||
)]
|
||||
[Canvas(key='controls_cv')],
|
||||
[Column(
|
||||
layout=[
|
||||
[Canvas(key='fig_cv', size=(400*2, 400))]
|
||||
],
|
||||
background_color='#DAE0E6',
|
||||
pad=(0,0)
|
||||
)],
|
||||
[Button("Correct", size=(10,1)), Button("Exit", size=(10,1))],
|
||||
]
|
||||
window = Window("CaribouLite PlayGround", layout, location=(800,400))
|
||||
return window
|
||||
|
||||
while file_ctr < nfiles:
|
||||
print(file_ctr, '. READING ', N, ' samples from CaribouLite')
|
||||
# Read the samples from the data buffer
|
||||
sr = sdr.readStream(rx_stream, [rx_buff], N, timeoutUs=timeout_us)
|
||||
|
||||
# Make sure that the proper number of samples was read
|
||||
rc = sr.ret
|
||||
assert rc == N, 'Error Reading Samples from Device (error code = %d)!' % rc
|
||||
|
||||
def estimate_correct(rx_buff):
|
||||
s_real = rx_buff[::2].astype(np.float32)
|
||||
s_imag = rx_buff[1::2].astype(np.float32)
|
||||
|
||||
|
@ -59,22 +67,98 @@ while file_ctr < nfiles:
|
|||
sin_phi_est = (2/alpha_est)*np.mean(I*Q)
|
||||
cos_phi_est = np.sqrt(1-sin_phi_est**2)
|
||||
|
||||
print('phase error: ', np.arccos(cos_phi_est)*360/3.1415, ' degrees')
|
||||
print('amplitude error: ', 20*np.log10(alpha_est), ' dB' )
|
||||
|
||||
I_new_p = (1/alpha_est) * I
|
||||
Q_new_p = (-sin_phi_est/alpha_est) * I + Q
|
||||
y = (I_new_p + 1j*Q_new_p) / cos_phi_est
|
||||
|
||||
print('phase error: ', np.arccos(cos_phi_est)*360/3.1415, ' degrees')
|
||||
print('amplitude error: ', 20*np.log10(alpha_est), ' dB' )
|
||||
return (s_real, s_imag, alpha_est, sin_phi_est, cos_phi_est, I_new_p, Q_new_p)
|
||||
|
||||
# plt.plot(s_real, s_imag, 'k', label='I')
|
||||
plt.scatter(I_new_p, Q_new_p)
|
||||
plt.ylabel('I / Q Balance')
|
||||
plt.show()
|
||||
def main():
|
||||
# Data and Source Configuration
|
||||
tx_chan = 0 # S1G = 0, 6G = 1
|
||||
rx_chan = 1 # S1G = 0, 6G = 1
|
||||
N = 16384 # Nu5mber of complex samples per transfer
|
||||
fs = 4e6 # Radio sample Rate
|
||||
freq = 868e6 # LO tuning frequency in Hz
|
||||
use_agc = True # Use or don't use the AGC
|
||||
gain = 60
|
||||
n_reads = 0
|
||||
|
||||
file_ctr += 1
|
||||
if file_ctr > nfiles:
|
||||
break
|
||||
rx_buff = np.empty(2 * N, np.int16) # Create memory buffer for data stream
|
||||
timeout_us = int(5e6)
|
||||
|
||||
# Stop streaming and close the connection to the radio
|
||||
sdr.deactivateStream(rx_stream)
|
||||
sdr.closeStream(rx_stream)
|
||||
# Initialize CaribouLite
|
||||
sdr = SoapySDR.Device(dict(driver="Cariboulite")) # Create Cariboulite
|
||||
|
||||
# The wide channel parameters
|
||||
sdr.setSampleRate(SOAPY_SDR_RX, rx_chan, fs) # Set sample rate
|
||||
sdr.setGainMode(SOAPY_SDR_RX, rx_chan, use_agc) # Set the gain mode
|
||||
sdr.setGain(SOAPY_SDR_RX, rx_chan, gain) # Set the gain
|
||||
sdr.setFrequency(SOAPY_SDR_RX, rx_chan, freq) # Tune the LO
|
||||
sdr.setBandwidth(SOAPY_SDR_RX, rx_chan, 2.5e6)
|
||||
|
||||
# The S1G channel parameter
|
||||
sdr.setFrequency(SOAPY_SDR_TX, tx_chan, 868.5e6)
|
||||
sdr.setGain(SOAPY_SDR_TX, tx_chan, 50)
|
||||
cw_tx_stream = sdr.setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, [tx_chan], dict(CW="1"))
|
||||
sdr.activateStream(cw_tx_stream)
|
||||
|
||||
# Create data buffer and start streaming samples to it
|
||||
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16,
|
||||
[rx_chan]) # Setup data stream
|
||||
sdr.activateStream(rx_stream) # this turns the radio on
|
||||
|
||||
# create the window
|
||||
window = create_window()
|
||||
|
||||
while True:
|
||||
event, values = window.read(timeout = 20)
|
||||
|
||||
if (event == "Exit" or event == WIN_CLOSED):
|
||||
break;
|
||||
|
||||
if (event == "Correct"):
|
||||
n_reads += 1
|
||||
sr = sdr.readStream(rx_stream, [rx_buff], N, timeoutUs=timeout_us)
|
||||
|
||||
# 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)
|
||||
break;
|
||||
|
||||
I,Q, alpha_est, sin_phi_est, cos_phi_est, I_new, Q_new = estimate_correct(rx_buff)
|
||||
|
||||
plt.figure(1).clf()
|
||||
fig = plt.gcf()
|
||||
DPI = fig.get_dpi()
|
||||
fig.set_size_inches(404*2/float(DPI), 404/float(DPI))
|
||||
plt.subplot(121)
|
||||
plt.scatter(I, Q)
|
||||
plt.title('I/Q original')
|
||||
plt.subplot(122)
|
||||
plt.scatter(I_new, Q_new)
|
||||
plt.title('I/Q corrected')
|
||||
plt.grid()
|
||||
draw_figure_with_toolbar(window['fig_cv'].TKCanvas, fig, window['controls_cv'].TKCanvas)
|
||||
|
||||
|
||||
# Stop streaming and close the connection to the radio
|
||||
window.close()
|
||||
sdr.deactivateStream(rx_stream)
|
||||
sdr.deactivateStream(cw_tx_stream)
|
||||
sdr.closeStream(rx_stream)
|
||||
|
||||
|
||||
|
||||
###########################################################
|
||||
## Global Area
|
||||
|
||||
# Enumerate the Soapy devices
|
||||
#res = SoapySDR.Device.enumerate()
|
||||
#for result in res:
|
||||
# print(result)
|
||||
main()
|
||||
|
|
|
@ -80,6 +80,7 @@ extern "C" {
|
|||
{ \
|
||||
.cs_pin = CARIBOULITE_MIXER_SS, \
|
||||
.reset_pin = CARIBOULITE_MIXER_RESET, \
|
||||
.ref_freq_hz = 32e6, \
|
||||
.initialized = 0, \
|
||||
}, \
|
||||
.reset_fpga_on_startup = 1, \
|
||||
|
|
|
@ -114,7 +114,7 @@ int cariboulite_dispose_radios(cariboulite_radios_st* radios)
|
|||
caribou_smi_destroy_stream(&radios->radio_6g.cariboulite_sys->smi, radios->radio_sub1g.tx_stream_id);
|
||||
radios->radio_6g.tx_stream_id = -1;
|
||||
}
|
||||
sleep(1);
|
||||
usleep(100000);
|
||||
|
||||
cariboulite_radio_state_st* rad_s1g = GET_RADIO_PTR(radios,cariboulite_channel_s1g);
|
||||
cariboulite_radio_state_st* rad_6g = GET_RADIO_PTR(radios,cariboulite_channel_6g);
|
||||
|
@ -774,7 +774,7 @@ int cariboulite_activate_channel(cariboulite_radios_st* radios,
|
|||
{
|
||||
cariboulite_radio_state_st* rad = GET_RADIO_PTR(radios,channel);
|
||||
|
||||
ZF_LOGD("Activating channel %d", channel);
|
||||
ZF_LOGD("Activating channel %d, dir = %s, active = %d", channel, rad->channel_direction==cariboulite_channel_dir_rx?"RX":"TX", active);
|
||||
// if the channel state is active, turn it off before reactivating
|
||||
if (rad->state != at86rf215_radio_state_cmd_tx_prep)
|
||||
{
|
||||
|
@ -855,6 +855,15 @@ int cariboulite_set_cw_outputs(cariboulite_radios_st* radios,
|
|||
}
|
||||
rad->cw_output = cw_out;
|
||||
|
||||
if (cw_out)
|
||||
{
|
||||
rad->channel_direction = cariboulite_channel_dir_tx;
|
||||
}
|
||||
else
|
||||
{
|
||||
rad->channel_direction = cariboulite_channel_dir_rx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -160,8 +160,8 @@ int cariboulite_init_submodules (cariboulite_st* sys)
|
|||
// Configure modem
|
||||
//------------------------------------------------------
|
||||
ZF_LOGD("Configuring modem initial state");
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_8ma, at86rf215_clock_out_freq_32mhz);
|
||||
at86rf215_setup_rf_irq(&sys->modem, 0, 1, at86rf215_drive_current_4ma);
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_2ma, at86rf215_clock_out_freq_32mhz);
|
||||
at86rf215_setup_rf_irq(&sys->modem, 0, 1, at86rf215_drive_current_2ma);
|
||||
at86rf215_radio_set_state(&sys->modem, at86rf215_rf_channel_900mhz, at86rf215_radio_state_cmd_trx_off);
|
||||
at86rf215_radio_set_state(&sys->modem, at86rf215_rf_channel_2400mhz, at86rf215_radio_state_cmd_trx_off);
|
||||
|
||||
|
@ -211,6 +211,7 @@ int cariboulite_init_submodules (cariboulite_st* sys)
|
|||
|
||||
// Configure mixer
|
||||
//------------------------------------------------------
|
||||
rffc507x_setup_reference_freq(&sys->mixer, 32e6);
|
||||
rffc507x_calibrate(&sys->mixer);
|
||||
|
||||
ZF_LOGI("Cariboulite submodules successfully initialized");
|
||||
|
@ -295,7 +296,7 @@ int cariboulite_release_submodules(cariboulite_st* sys)
|
|||
//------------------------------------------------------
|
||||
ZF_LOGD("CLOSE SMI");
|
||||
caribou_smi_close(&sys->smi);
|
||||
sleep(1);
|
||||
usleep(10000);
|
||||
|
||||
// AT86RF215
|
||||
//------------------------------------------------------
|
||||
|
|
|
@ -24,6 +24,7 @@ static char *io_utils_gpio_mode_strs[] = {"IN","OUT","ALT5","ALT4","ALT0","ALT1"
|
|||
int io_utils_setup(pigpioSigHandler sigHandler)
|
||||
{
|
||||
ZF_LOGI("initializing pigpio");
|
||||
gpioCfgInterfaces(PI_DISABLE_FIFO_IF|PI_DISABLE_SOCK_IF|PI_LOCALHOST_SOCK_IF);
|
||||
int status = gpioInitialise();
|
||||
if (status < 0)
|
||||
{
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
|
||||
#define LO_MAX 5400
|
||||
#define LO_MAX_HZ (LO_MAX*1e6)
|
||||
#define REF_FREQ 32
|
||||
#define REF_FREQ_HZ (REF_FREQ*1e6)
|
||||
#define FREQ_ONE_MHZ (1000*1000)
|
||||
|
||||
//===========================================================================
|
||||
|
@ -151,8 +149,8 @@ int rffc507x_init( rffc507x_st* dev,
|
|||
set_RFFC507X_P2CTV(dev, 12);
|
||||
set_RFFC507X_P1CTV(dev, 12);
|
||||
set_RFFC507X_RGBYP(dev, 1);
|
||||
set_RFFC507X_P2MIXIDD(dev, 6);
|
||||
set_RFFC507X_P1MIXIDD(dev, 6);
|
||||
set_RFFC507X_P2MIXIDD(dev, 5);
|
||||
set_RFFC507X_P1MIXIDD(dev, 5);
|
||||
|
||||
// Others
|
||||
set_RFFC507X_LDEN(dev, 1);
|
||||
|
@ -253,9 +251,10 @@ void rffc507x_enable(rffc507x_st* dev)
|
|||
}
|
||||
|
||||
//===========================================================================
|
||||
void rffc507x_calculate_freq_params(uint8_t lodiv, double fvco, uint8_t fbkdiv, uint16_t *n, uint16_t *p1nmsb, uint8_t *p1nlsb, double* act_freq_hz)
|
||||
void rffc507x_calculate_freq_params(double ref_freq_hz, uint8_t lodiv, double fvco, uint8_t fbkdiv,
|
||||
uint16_t *n, uint16_t *p1nmsb, uint8_t *p1nlsb, double* act_freq_hz)
|
||||
{
|
||||
double n_div = fvco / fbkdiv / REF_FREQ_HZ;
|
||||
double n_div = fvco / fbkdiv / ref_freq_hz;
|
||||
*n = (uint16_t)(n_div);
|
||||
|
||||
double temp_p1nmsb = ( (double)(1<<16) ) * ( n_div - (double)(*n) );
|
||||
|
@ -266,7 +265,18 @@ void rffc507x_calculate_freq_params(uint8_t lodiv, double fvco, uint8_t fbkdiv,
|
|||
uint32_t n_div24_bit = (uint32_t)(round(n_div * (1<<24))) & 0xFFFFFFFF;
|
||||
//uint32_t n_div24_bit = (uint32_t)((n_div * (1<<24))) & 0xFFFFFFFF;
|
||||
|
||||
if (act_freq_hz) *act_freq_hz = (REF_FREQ_HZ * n_div24_bit * fbkdiv) / ((double)(lodiv) * (double)(1<<24));
|
||||
if (act_freq_hz) *act_freq_hz = (ref_freq_hz * n_div24_bit * fbkdiv) / ((double)(lodiv) * (double)(1<<24));
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int rffc507x_setup_reference_freq(rffc507x_st* dev, double ref_freq_hz)
|
||||
{
|
||||
if (ref_freq_hz < 10e6 || ref_freq_hz > 104e6)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
dev->ref_freq_hz = ref_freq_hz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -298,7 +308,7 @@ double rffc507x_set_frequency(rffc507x_st* dev, double lo_hz)
|
|||
set_RFFC507X_PLLCPL(dev, 2);
|
||||
}
|
||||
|
||||
rffc507x_calculate_freq_params(lodiv, fvco, fbkdiv, &n, &p1nmsb, &p1nlsb, &tune_freq_hz);
|
||||
rffc507x_calculate_freq_params(dev->ref_freq_hz, lodiv, fvco, fbkdiv, &n, &p1nmsb, &p1nlsb, &tune_freq_hz);
|
||||
|
||||
//ZF_LOGD("----------------------------------------------------------");
|
||||
//ZF_LOGD("LO_HZ=%.2f n_lo=%d lodiv=%d", lo_hz, n_lo, lodiv);
|
||||
|
@ -323,7 +333,7 @@ double rffc507x_set_frequency(rffc507x_st* dev, double lo_hz)
|
|||
// After the device is enabled, the divider values can be reprogrammed with the prescaler divider ratio of 2
|
||||
// and the new n, nummsb, and numlsb values. Taking the previous example of an LO of 314.159265MHz:
|
||||
fbkdiv = 2;
|
||||
rffc507x_calculate_freq_params(lodiv, fvco, fbkdiv, &n, &p1nmsb, &p1nlsb, &tune_freq_hz);
|
||||
rffc507x_calculate_freq_params(dev->ref_freq_hz, lodiv, fvco, fbkdiv, &n, &p1nmsb, &p1nlsb, &tune_freq_hz);
|
||||
|
||||
//ZF_LOGD("LO_HZ=%.2f n_lo=%d lodiv=%d", lo_hz, n_lo, lodiv);
|
||||
//ZF_LOGD("fvco=%.2f fbkdiv=%d n=%d", fvco, fbkdiv, n);
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct
|
|||
{
|
||||
int cs_pin;
|
||||
int reset_pin;
|
||||
double ref_freq_hz;
|
||||
|
||||
io_utils_spi_st* io_spi;
|
||||
int io_spi_handle;
|
||||
|
@ -104,6 +105,7 @@ void rffc507x_print_stat(rffc507x_device_status_st* stat);
|
|||
void rffc507x_calibrate(rffc507x_st* dev);
|
||||
void rffc507x_relock(rffc507x_st* dev);
|
||||
void rffc507x_output_lo(rffc507x_st* dev, int state);
|
||||
int rffc507x_setup_reference_freq(rffc507x_st* dev, double ref_freq_hz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ rffc507x_st dev =
|
|||
{
|
||||
.cs_pin = CARIBOULITE_MXR_SS,
|
||||
.reset_pin = CARIBOULITE_MXR_RESET,
|
||||
.ref_freq_hz = 32e6,
|
||||
};
|
||||
|
||||
int main ()
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
int stream_id;
|
||||
int stream_dir;
|
||||
int stream_channel;
|
||||
int is_cw;
|
||||
Cariboulite_Format chosen_format;
|
||||
private:
|
||||
tsqueue_st queue;
|
||||
|
|
|
@ -40,7 +40,7 @@ SampleQueue::SampleQueue(int mtu_bytes, int num_buffers)
|
|||
// a buffer for conversion betwen native and emulated formats
|
||||
// the maximal size is the 2*(mtu_size in bytes)
|
||||
interm_native_buffer = new sample_complex_int16[2*mtu_size_bytes];
|
||||
|
||||
is_cw = 0;
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
|
|
@ -184,12 +184,11 @@ SoapySDR::Stream *Cariboulite::setupStream(const int direction,
|
|||
const std::vector<size_t> &channels,
|
||||
const SoapySDR::Kwargs &args)
|
||||
{
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "setupStream: dir: %d, format: %s, channels: ", direction, format.c_str());
|
||||
for (int i = 0; i < (int)channels.size(); i++)
|
||||
{
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "setupStream: %d. %ld", i, channels[i]);
|
||||
}
|
||||
|
||||
int cw = (args.count("CW") != 0) ? std::atoi(args.at("CW").c_str()) : 0;
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "setupStream: dir= %s, format= %s, is_cw= %d, ch= %d",
|
||||
direction == SOAPY_SDR_TX?"TX":"RX", format.c_str(), cw,
|
||||
channels.size()?channels[0]:0);
|
||||
|
||||
std::vector<size_t> channels_internal = channels;
|
||||
// default channel - sub1GHz
|
||||
if ( channels_internal.size() == 0 )
|
||||
|
@ -204,6 +203,7 @@ SoapySDR::Stream *Cariboulite::setupStream(const int direction,
|
|||
caribou_smi_stream_type_en type = (direction == SOAPY_SDR_RX) ? caribou_smi_stream_type_read : caribou_smi_stream_type_write;
|
||||
caribou_smi_channel_en channel = (ch == cariboulite_channel_s1g) ? caribou_smi_channel_900 : caribou_smi_channel_2400;
|
||||
int stream_id = CARIBOU_SMI_GET_STREAM_ID(type, channel);
|
||||
sample_queues[stream_id]->is_cw = cw;
|
||||
|
||||
// Setup the SampleQueue's format
|
||||
if (format == SOAPY_SDR_CS16)
|
||||
|
@ -228,18 +228,26 @@ SoapySDR::Stream *Cariboulite::setupStream(const int direction,
|
|||
throw std::runtime_error( "setupStream invalid format " + format );
|
||||
}
|
||||
|
||||
// create the stream
|
||||
stream_id = caribou_smi_setup_stream(&sess.cariboulite_sys.smi,
|
||||
type, channel,
|
||||
GET_MTU_MS_BYTES(BUFFER_SIZE_MS), 1,
|
||||
caribou_stream_data_event,
|
||||
this);
|
||||
if (stream_id < 0)
|
||||
// create the stream (only for non CW streams)
|
||||
if (sample_queues[stream_id]->is_cw)
|
||||
{
|
||||
throw std::runtime_error( "setupStream caribou_smi_setup_stream failed" );
|
||||
cariboulite_set_cw_outputs(&radios, (cariboulite_channel_en)ch, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
cariboulite_set_cw_outputs(&radios, (cariboulite_channel_en)ch, false, false);
|
||||
stream_id = caribou_smi_setup_stream(&sess.cariboulite_sys.smi,
|
||||
type, channel,
|
||||
GET_MTU_MS_BYTES(BUFFER_SIZE_MS), 1,
|
||||
caribou_stream_data_event,
|
||||
this);
|
||||
if (stream_id < 0)
|
||||
{
|
||||
throw std::runtime_error( "setupStream caribou_smi_setup_stream failed" );
|
||||
}
|
||||
}
|
||||
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "finished setup stream, stream_id = %d", stream_id);
|
||||
SoapySDR_logf(SOAPY_SDR_INFO, "finished setup stream, stream_id = %d, CW=%d", stream_id, cw);
|
||||
return (SoapySDR::Stream *)((void*)stream_id);
|
||||
}
|
||||
|
||||
|
@ -305,7 +313,10 @@ int Cariboulite::activateStream(SoapySDR::Stream *stream,
|
|||
(cariboulite_channel_en)sample_queues[stream_id]->stream_channel,
|
||||
true);
|
||||
|
||||
caribou_smi_run_pause_stream (&sess.cariboulite_sys.smi, (intptr_t)stream, 1);
|
||||
if ((cariboulite_channel_en)sample_queues[stream_id]->is_cw == 0)
|
||||
{
|
||||
caribou_smi_run_pause_stream (&sess.cariboulite_sys.smi, (intptr_t)stream, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -329,8 +340,11 @@ int Cariboulite::deactivateStream(SoapySDR::Stream *stream, const int flags, con
|
|||
SoapySDR_logf(SOAPY_SDR_INFO, "deactivateStream");
|
||||
int stream_id = (intptr_t)stream;
|
||||
|
||||
caribou_smi_run_pause_stream (&sess.cariboulite_sys.smi, (intptr_t)stream, 0);
|
||||
sleep(1);
|
||||
if ((cariboulite_channel_en)sample_queues[stream_id]->is_cw == 0)
|
||||
{
|
||||
caribou_smi_run_pause_stream (&sess.cariboulite_sys.smi, (intptr_t)stream, 0);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
cariboulite_activate_channel(&radios,
|
||||
(cariboulite_channel_en)sample_queues[stream_id]->stream_channel,
|
||||
|
|
Ładowanie…
Reference in New Issue