replace tcp with udp

pull/1/head
Luigi Cruz 2021-05-03 00:29:25 -03:00
rodzic ffb17d82f0
commit 20e52bc54b
4 zmienionych plików z 57 dodań i 381 usunięć

Wyświetl plik

@ -7,32 +7,36 @@
#include "hardware/irq.h" #include "hardware/irq.h"
#include "usb_network.h" #include "usb_network.h"
bool streaming = false; uint data_ovf;
struct tcp_pcb* control = NULL; uint data_dma;
bool data_val;
bool streaming;
struct repeating_timer timer; struct repeating_timer timer;
#define CAPTURE_CHANNEL 0 #define CAPTURE_CHANNEL 0
#define CAPTURE_DEPTH 1472 #define CAPTURE_DEPTH 1472
uint dma_chan_a, dma_chan_b; uint dma_chan_a, dma_chan_b;
struct pbuf* pbuf_a; struct pbuf *pbuf_a, *pbuf_b;
struct pbuf* pbuf_b;
static void printc(char* s) { static void dma_handler(uint id) {
if (control) { if (data_val) {
tcp_write(control, s, strlen(s), TCP_WRITE_FLAG_COPY); data_ovf += 1;
tcp_output(control);
} }
data_dma = id;
data_val = true;
} }
static void dma_handler_a() { static void dma_handler_a() {
dma_hw->ints0 = 1u << dma_chan_a; dma_handler(0);
dma_channel_set_write_addr(dma_chan_a, pbuf_a->payload, false); dma_channel_set_write_addr(dma_chan_a, pbuf_a->payload, false);
dma_hw->ints0 = 1u << dma_chan_a;
} }
static void dma_handler_b() { static void dma_handler_b() {
dma_hw->ints1 = 1u << dma_chan_b; dma_handler(1);
dma_channel_set_write_addr(dma_chan_b, pbuf_b->payload, false); dma_channel_set_write_addr(dma_chan_b, pbuf_b->payload, false);
dma_hw->ints1 = 1u << dma_chan_b;
} }
static void init_adc_dma_chain() { static void init_adc_dma_chain() {
@ -100,21 +104,21 @@ static void init_adc_dma_chain() {
static void start_stream(struct tcp_pcb *pcb) { static void start_stream(struct tcp_pcb *pcb) {
if (streaming) { if (streaming) {
printc("[PICCOLO] Stream already started.\n");
return; return;
} }
data_ovf = 0;
data_dma = 0;
data_val = false;
streaming = true;
dma_channel_set_write_addr(dma_chan_a, pbuf_a->payload, true); dma_channel_set_write_addr(dma_chan_a, pbuf_a->payload, true);
dma_channel_set_write_addr(dma_chan_b, pbuf_b->payload, false); dma_channel_set_write_addr(dma_chan_b, pbuf_b->payload, false);
adc_run(true); adc_run(true);
streaming = true;
printc("[PICCOLO] Stream started.\n");
} }
static void stop_stream(struct tcp_pcb *pcb) { static void stop_stream(struct tcp_pcb *pcb) {
if (!streaming) { if (!streaming) {
printc("[PICCOLO] Stream already stopped.\n");
return; return;
} }
@ -123,54 +127,10 @@ static void stop_stream(struct tcp_pcb *pcb) {
dma_channel_set_write_addr(dma_chan_a, pbuf_a->payload, false); dma_channel_set_write_addr(dma_chan_a, pbuf_a->payload, false);
dma_channel_set_write_addr(dma_chan_b, pbuf_b->payload, false); dma_channel_set_write_addr(dma_chan_b, pbuf_b->payload, false);
data_ovf = 0;
data_dma = 0;
data_val = false;
streaming = false; streaming = false;
printc("[PICCOLO] Stream stopped.\n");
}
static void srv_err(void *arg, err_t err) {
tcp_arg(control, NULL);
tcp_sent(control, NULL);
tcp_recv(control, NULL);
tcp_close(control);
}
static err_t srv_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
if (err != ERR_OK) {
goto exception;
}
tcp_recved(pcb, p->tot_len);
tcp_sent(pcb, NULL);
if (((char*)p->payload)[0] == 'S') {
start_stream(pcb);
}
if (((char*)p->payload)[0] == 'E') {
stop_stream(pcb);
}
exception:
if (p != NULL) {
pbuf_free(p);
}
return err;
}
static err_t srv_accept(void * arg, struct tcp_pcb * pcb, err_t err) {
if (err != ERR_OK) {
return err;
}
tcp_setprio(pcb, TCP_PRIO_MIN);
tcp_recv(pcb, srv_receive);
tcp_err(pcb, NULL);
tcp_poll(pcb, NULL, 4);
control = pcb;
return err;
} }
static bool led_timer(struct repeating_timer *t) { static bool led_timer(struct repeating_timer *t) {
@ -187,26 +147,25 @@ int main(void) {
gpio_init(PICO_DEFAULT_LED_PIN); gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
// Init ADC DMA chain.
init_adc_dma_chain();
// Init network stack. // Init network stack.
network_init(); network_init();
// Start control TCP port. // Allocate zero-copy memory for DMA and UDP.
struct tcp_pcb* cpcb = tcp_new(); pbuf_a = pbuf_alloc(PBUF_RAW, CAPTURE_DEPTH, PBUF_RAM);
cpcb->so_options |= SOF_KEEPALIVE; pbuf_b = pbuf_alloc(PBUF_RAW, CAPTURE_DEPTH, PBUF_RAM);
cpcb->keep_intvl = 75000000;
tcp_bind(cpcb, IP_ADDR_ANY, 7777); if (pbuf_a == NULL && pbuf_b == NULL) {
return 1;
}
// Init ADC DMA chain.
init_adc_dma_chain();
// Start data UDP port. // Start data UDP port.
ip_addr_t client; ip_addr_t client;
IP4_ADDR(&client, 192, 168, 7, 2);
struct udp_pcb* dpcb = udp_new(); struct udp_pcb* dpcb = udp_new();
IP4_ADDR(&client, 192, 168, 7, 2);
// Start listening for control connections. udp_connect(dpcb, &client, 7778);
struct tcp_pcb* listen = tcp_listen(cpcb);
tcp_accept(listen, srv_accept);
// Start LED indicator. // Start LED indicator.
add_repeating_timer_ms(250, led_timer, NULL, &timer); add_repeating_timer_ms(250, led_timer, NULL, &timer);
@ -214,13 +173,20 @@ int main(void) {
// Start stream right away. // Start stream right away.
start_stream(NULL); start_stream(NULL);
pbuf_a = pbuf_alloc(PBUF_RAW, CAPTURE_DEPTH, PBUF_RAM);
pbuf_b = pbuf_alloc(PBUF_RAW, CAPTURE_DEPTH, PBUF_RAM);
// Listen to events. // Listen to events.
while (1) { while (1) {
if (data_val && streaming) {
if (data_dma == 0) {
udp_send(dpcb, pbuf_a);
}
if (data_dma == 1) {
udp_send(dpcb, pbuf_b);
}
data_val = false;
}
network_step(); network_step();
udp_sendto(dpcb, pbuf_a, &client, 7778);
} }
return 0; return 0;

Wyświetl plik

@ -77,42 +77,27 @@ blocks:
coordinate: [403, 167] coordinate: [403, 167]
rotation: 0 rotation: 0
state: true state: true
- name: blocks_vector_to_stream_0 - name: grnet_udp_source_0
id: blocks_vector_to_stream id: grnet_udp_source
parameters: parameters:
affinity: '' affinity: ''
alias: '' alias: ''
comment: '' comment: ''
header: '0'
ipv6: 'False'
maxoutbuf: '0' maxoutbuf: '0'
minoutbuf: '0' minoutbuf: '0'
num_items: '500' notifyMissed: 'False'
payloadsize: '1472'
port: '7778'
srcZeros: 'False'
type: byte type: byte
vlen: '1' vlen: '1'
states: states:
bus_sink: false bus_sink: false
bus_source: false bus_source: false
bus_structure: null bus_structure: null
coordinate: [211, 167] coordinate: [37, 173]
rotation: 0
state: true
- name: grnet_tcp_source_0
id: grnet_tcp_source
parameters:
addr: 192.168.7.1
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
port: '7777'
server: 'False'
type: byte
vlen: '500'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [22, 140]
rotation: 0 rotation: 0
state: true state: true
- name: qtgui_freq_sink_x_0 - name: qtgui_freq_sink_x_0
@ -359,8 +344,7 @@ connections:
- [blocks_multiply_const_vxx_0, '0', qtgui_time_sink_x_0, '0'] - [blocks_multiply_const_vxx_0, '0', qtgui_time_sink_x_0, '0']
- [blocks_multiply_const_vxx_0, '0', qtgui_waterfall_sink_x_0, '0'] - [blocks_multiply_const_vxx_0, '0', qtgui_waterfall_sink_x_0, '0']
- [blocks_uchar_to_float_0, '0', blocks_multiply_const_vxx_0, '0'] - [blocks_uchar_to_float_0, '0', blocks_multiply_const_vxx_0, '0']
- [blocks_vector_to_stream_0, '0', blocks_uchar_to_float_0, '0'] - [grnet_udp_source_0, '0', blocks_uchar_to_float_0, '0']
- [grnet_tcp_source_0, '0', blocks_vector_to_stream_0, '0']
metadata: metadata:
file_format: 1 file_format: 1

Wyświetl plik

@ -1,275 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: PiccoloSDR
# Author: Luigi Cruz
# Copyright: MIT
# GNU Radio version: 3.8.2.0
from distutils.version import StrictVersion
if __name__ == '__main__':
import ctypes
import sys
if sys.platform.startswith('linux'):
try:
x11 = ctypes.cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
except:
print("Warning: failed to XInitThreads()")
from PyQt5 import Qt
from gnuradio import qtgui
from gnuradio.filter import firdes
import sip
from gnuradio import blocks
from gnuradio import gr
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
import grnet
from gnuradio import qtgui
class piccolosdr(gr.top_block, Qt.QWidget):
def __init__(self):
gr.top_block.__init__(self, "PiccoloSDR")
Qt.QWidget.__init__(self)
self.setWindowTitle("PiccoloSDR")
qtgui.util.check_set_qss()
try:
self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
except:
pass
self.top_scroll_layout = Qt.QVBoxLayout()
self.setLayout(self.top_scroll_layout)
self.top_scroll = Qt.QScrollArea()
self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
self.top_scroll_layout.addWidget(self.top_scroll)
self.top_scroll.setWidgetResizable(True)
self.top_widget = Qt.QWidget()
self.top_scroll.setWidget(self.top_widget)
self.top_layout = Qt.QVBoxLayout(self.top_widget)
self.top_grid_layout = Qt.QGridLayout()
self.top_layout.addLayout(self.top_grid_layout)
self.settings = Qt.QSettings("GNU Radio", "piccolosdr")
try:
if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
self.restoreGeometry(self.settings.value("geometry").toByteArray())
else:
self.restoreGeometry(self.settings.value("geometry"))
except:
pass
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 500000
##################################################
# Blocks
##################################################
self.qtgui_waterfall_sink_x_0 = qtgui.waterfall_sink_f(
1024, #size
firdes.WIN_BLACKMAN_hARRIS, #wintype
0, #fc
samp_rate, #bw
"", #name
1 #number of inputs
)
self.qtgui_waterfall_sink_x_0.set_update_time(0.10)
self.qtgui_waterfall_sink_x_0.enable_grid(False)
self.qtgui_waterfall_sink_x_0.enable_axis_labels(True)
self.qtgui_waterfall_sink_x_0.set_plot_pos_half(not True)
labels = ['', '', '', '', '',
'', '', '', '', '']
colors = [0, 0, 0, 0, 0,
0, 0, 0, 0, 0]
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_waterfall_sink_x_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_waterfall_sink_x_0.set_line_label(i, labels[i])
self.qtgui_waterfall_sink_x_0.set_color_map(i, colors[i])
self.qtgui_waterfall_sink_x_0.set_line_alpha(i, alphas[i])
self.qtgui_waterfall_sink_x_0.set_intensity_range(-140, 10)
self._qtgui_waterfall_sink_x_0_win = sip.wrapinstance(self.qtgui_waterfall_sink_x_0.pyqwidget(), Qt.QWidget)
self.top_grid_layout.addWidget(self._qtgui_waterfall_sink_x_0_win)
self.qtgui_time_sink_x_0 = qtgui.time_sink_f(
1024, #size
samp_rate, #samp_rate
"", #name
1 #number of inputs
)
self.qtgui_time_sink_x_0.set_update_time(0.10)
self.qtgui_time_sink_x_0.set_y_axis(-1, 1)
self.qtgui_time_sink_x_0.set_y_label('Amplitude', "")
self.qtgui_time_sink_x_0.enable_tags(True)
self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "")
self.qtgui_time_sink_x_0.enable_autoscale(True)
self.qtgui_time_sink_x_0.enable_grid(False)
self.qtgui_time_sink_x_0.enable_axis_labels(True)
self.qtgui_time_sink_x_0.enable_control_panel(False)
self.qtgui_time_sink_x_0.enable_stem_plot(False)
labels = ['Signal 1', 'Signal 2', 'Signal 3', 'Signal 4', 'Signal 5',
'Signal 6', 'Signal 7', 'Signal 8', 'Signal 9', 'Signal 10']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ['blue', 'red', 'green', 'black', 'cyan',
'magenta', 'yellow', 'dark red', 'dark green', 'dark blue']
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
styles = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
markers = [-1, -1, -1, -1, -1,
-1, -1, -1, -1, -1]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_time_sink_x_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_time_sink_x_0.set_line_label(i, labels[i])
self.qtgui_time_sink_x_0.set_line_width(i, widths[i])
self.qtgui_time_sink_x_0.set_line_color(i, colors[i])
self.qtgui_time_sink_x_0.set_line_style(i, styles[i])
self.qtgui_time_sink_x_0.set_line_marker(i, markers[i])
self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i])
self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget)
self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_win)
self.qtgui_freq_sink_x_0 = qtgui.freq_sink_f(
1024, #size
firdes.WIN_BLACKMAN_hARRIS, #wintype
0, #fc
samp_rate, #bw
"", #name
1
)
self.qtgui_freq_sink_x_0.set_update_time(0.10)
self.qtgui_freq_sink_x_0.set_y_axis(-140, 10)
self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB')
self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
self.qtgui_freq_sink_x_0.enable_autoscale(False)
self.qtgui_freq_sink_x_0.enable_grid(False)
self.qtgui_freq_sink_x_0.set_fft_average(1.0)
self.qtgui_freq_sink_x_0.enable_axis_labels(True)
self.qtgui_freq_sink_x_0.enable_control_panel(False)
self.qtgui_freq_sink_x_0.set_plot_pos_half(not True)
labels = ['', '', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ["blue", "red", "green", "black", "cyan",
"magenta", "yellow", "dark red", "dark green", "dark blue"]
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_freq_sink_x_0.set_line_label(i, labels[i])
self.qtgui_freq_sink_x_0.set_line_width(i, widths[i])
self.qtgui_freq_sink_x_0.set_line_color(i, colors[i])
self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i])
self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget)
self.top_grid_layout.addWidget(self._qtgui_freq_sink_x_0_win)
self.grnet_tcp_source_0 = grnet.tcp_source.tcp_source(
itemsize=gr.sizeof_char*500,
addr='192.168.7.1',
port=7777,
server=False,
)
self.blocks_vector_to_stream_0 = blocks.vector_to_stream(gr.sizeof_char*1, 500)
self.blocks_uchar_to_float_0 = blocks.uchar_to_float()
self.blocks_multiply_const_vxx_0 = blocks.multiply_const_ff(3.3 / 255.0)
##################################################
# Connections
##################################################
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.qtgui_freq_sink_x_0, 0))
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.qtgui_time_sink_x_0, 0))
self.connect((self.blocks_multiply_const_vxx_0, 0), (self.qtgui_waterfall_sink_x_0, 0))
self.connect((self.blocks_uchar_to_float_0, 0), (self.blocks_multiply_const_vxx_0, 0))
self.connect((self.blocks_vector_to_stream_0, 0), (self.blocks_uchar_to_float_0, 0))
self.connect((self.grnet_tcp_source_0, 0), (self.blocks_vector_to_stream_0, 0))
def closeEvent(self, event):
self.settings = Qt.QSettings("GNU Radio", "piccolosdr")
self.settings.setValue("geometry", self.saveGeometry())
event.accept()
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.qtgui_freq_sink_x_0.set_frequency_range(0, self.samp_rate)
self.qtgui_time_sink_x_0.set_samp_rate(self.samp_rate)
self.qtgui_waterfall_sink_x_0.set_frequency_range(0, self.samp_rate)
def main(top_block_cls=piccolosdr, options=None):
if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
style = gr.prefs().get_string('qtgui', 'style', 'raster')
Qt.QApplication.setGraphicsSystem(style)
qapp = Qt.QApplication(sys.argv)
tb = top_block_cls()
tb.start()
tb.show()
def sig_handler(sig=None, frame=None):
Qt.QApplication.quit()
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
timer = Qt.QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)
def quitting():
tb.stop()
tb.wait()
qapp.aboutToQuit.connect(quitting)
qapp.exec_()
if __name__ == '__main__':
main()

Wyświetl plik

@ -35,7 +35,8 @@
/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ /* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
#define NO_SYS 1 #define NO_SYS 1
#define MEM_ALIGNMENT 4 #define MEM_ALIGNMENT 4
#define LWIP_RAW 0 #define MEM_SIZE 8192 * 8
#define LWIP_RAW 1
#define LWIP_NETCONN 0 #define LWIP_NETCONN 0
#define LWIP_SOCKET 0 #define LWIP_SOCKET 0
#define LWIP_DHCP 0 #define LWIP_DHCP 0