Replace TCP with UDP. (#1)

* replace tcp with udp
* remove python grc
pull/3/head v1.1
Luigi Cruz 2021-05-02 21:36:21 -06:00 zatwierdzone przez GitHub
rodzic bf54ea7286
commit 21d4f22c8b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
6 zmienionych plików z 90 dodań i 397 usunięć

Wyświetl plik

@ -1,4 +1,4 @@
/*
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Peter Lawrence
@ -39,7 +39,7 @@ and likely their manufacturer has not tested such functionality. Some code work
The smartphone may only have an ECM driver, but refuse to automatically pick ECM (unlike the OSes above);
try modifying ./examples/devices/net_lwip_webserver/usb_descriptors.c so that CONFIG_ID_ECM is default.
The smartphone may be artificially picky about which Ethernet MAC address to recognize; if this happens,
The smartphone may be artificially picky about which Ethernet MAC address to recognize; if this happens,
try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 (clearing bit 1).
*/
@ -156,7 +156,7 @@ bool dns_query_proc(const char *name, ip_addr_t *addr)
bool tud_network_recv_cb(const uint8_t *src, uint16_t size)
{
/* this shouldn't happen, but if we get another packet before
/* this shouldn't happen, but if we get another packet before
parsing the previous, we must signal our inability to accept it */
if (received_frame) return false;
@ -243,4 +243,4 @@ int main(void)
}
return 0;
}
}

Wyświetl plik

@ -9,6 +9,7 @@ target_link_libraries(piccolosdr LINK_PUBLIC
hardware_adc
hardware_dma
hardware_irq
pico_sync
)
pico_add_extra_outputs(piccolosdr)

Wyświetl plik

@ -7,40 +7,36 @@
#include "hardware/irq.h"
#include "usb_network.h"
bool streaming = false;
struct tcp_pcb* client;
uint data_ovf;
uint data_dma;
bool data_val;
bool streaming;
struct repeating_timer timer;
//#define DEBUG
#define CAPTURE_CHANNEL 0
#define CAPTURE_DEPTH 500
#define CAPTURE_DEPTH 1472
uint dma_chan_a, dma_chan_b;
uint8_t capture_buf_a[CAPTURE_DEPTH];
uint8_t capture_buf_b[CAPTURE_DEPTH];
struct pbuf *pbuf_a, *pbuf_b;
void dma_handler(uint8_t* buffer, int id) {
#ifdef DEBUG
char str[64];
int len = sprintf(str, "DMA IRQ %d [%d %d ... %d]\n", id, buffer[0], buffer[1], buffer[CAPTURE_DEPTH-1]);
tcp_write(client, str, len, 0);
tcp_output(client);
#else
tcp_write(client, buffer, CAPTURE_DEPTH, 0x01);
tcp_output(client);
#endif
static void dma_handler(uint id) {
if (data_val) {
data_ovf += 1;
}
data_dma = id;
data_val = true;
}
void dma_handler_a() {
dma_handler((uint8_t*)&capture_buf_a, 0);
static void dma_handler_a() {
dma_handler(0);
dma_channel_set_write_addr(dma_chan_a, pbuf_a->payload, false);
dma_hw->ints0 = 1u << dma_chan_a;
dma_channel_set_write_addr(dma_chan_a, &capture_buf_a, false);
}
void dma_handler_b() {
dma_handler((uint8_t*)&capture_buf_b, 1);
static void dma_handler_b() {
dma_handler(1);
dma_channel_set_write_addr(dma_chan_b, pbuf_b->payload, false);
dma_hw->ints1 = 1u << dma_chan_b;
dma_channel_set_write_addr(dma_chan_b, &capture_buf_b, false);
}
static void init_adc_dma_chain() {
@ -80,14 +76,14 @@ static void init_adc_dma_chain() {
channel_config_set_chain_to(&dma_cfg_b, dma_chan_a);
dma_channel_configure(dma_chan_a, &dma_cfg_a,
capture_buf_a, // dst
pbuf_a->payload,// dst
&adc_hw->fifo, // src
CAPTURE_DEPTH, // transfer count
true // start now
);
dma_channel_configure(dma_chan_b, &dma_cfg_b,
capture_buf_b, // dst
pbuf_b->payload, // dst
&adc_hw->fifo, // src
CAPTURE_DEPTH, // transfer count
false // start now
@ -106,70 +102,38 @@ static void init_adc_dma_chain() {
adc_run(false);
}
static void start_stream() {
dma_channel_set_write_addr(dma_chan_a, &capture_buf_a, true);
dma_channel_set_write_addr(dma_chan_b, &capture_buf_b, false);
adc_run(true);
static void start_stream(struct tcp_pcb *pcb) {
if (streaming) {
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_b, pbuf_b->payload, false);
adc_run(true);
}
static void stop_stream() {
static void stop_stream(struct tcp_pcb *pcb) {
if (!streaming) {
return;
}
adc_run(false);
adc_fifo_drain();
dma_channel_set_write_addr(dma_chan_a, &capture_buf_a, false);
dma_channel_set_write_addr(dma_chan_b, &capture_buf_b, 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);
data_ovf = 0;
data_dma = 0;
data_val = false;
streaming = false;
}
static void srv_close(struct tcp_pcb *pcb){
stop_stream();
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
tcp_close(pcb);
}
static void srv_err(void *arg, err_t err) {
// Probably an indication that the client connection went kaput! Stopping stream...
srv_close(client);
}
static err_t srv_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
if (err != ERR_OK && p != NULL) {
goto exception;
}
tcp_recved(pcb, p->tot_len);
tcp_sent(pcb, NULL);
// The connection is closed if the client sends "X".
if (((char*)p->payload)[0] == 'X') {
srv_close(pcb);
}
exception:
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, srv_err);
tcp_poll(pcb, NULL, 4);
client = pcb;
start_stream();
return err;
}
bool led_timer(struct repeating_timer *t) {
static bool led_timer(struct repeating_timer *t) {
int status = 1;
if (streaming) {
status = !gpio_get(PICO_DEFAULT_LED_PIN);
@ -183,27 +147,45 @@ int main(void) {
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
// Init ADC DMA chain.
init_adc_dma_chain();
// Init network stack.
network_init();
// Start TCP server.
struct tcp_pcb* pcb = tcp_new();
pcb->so_options |= SOF_KEEPALIVE;
pcb->keep_intvl = 75000000;
tcp_bind(pcb, IP_ADDR_ANY, 7777);
// Allocate zero-copy memory for DMA and UDP.
pbuf_a = pbuf_alloc(PBUF_RAW, CAPTURE_DEPTH, PBUF_RAM);
pbuf_b = pbuf_alloc(PBUF_RAW, CAPTURE_DEPTH, PBUF_RAM);
// Start listening for connections.
struct tcp_pcb* listen = tcp_listen(pcb);
tcp_accept(listen, srv_accept);
if (pbuf_a == NULL && pbuf_b == NULL) {
return 1;
}
// Init ADC DMA chain.
init_adc_dma_chain();
// Start data UDP port.
ip_addr_t client;
struct udp_pcb* dpcb = udp_new();
IP4_ADDR(&client, 192, 168, 7, 2);
udp_connect(dpcb, &client, 7778);
// Start LED indicator.
add_repeating_timer_ms(250, led_timer, NULL, &timer);
// Start stream right away.
start_stream(NULL);
// Listen to events.
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();
}

Wyświetl plik

@ -77,42 +77,27 @@ blocks:
coordinate: [403, 167]
rotation: 0
state: true
- name: blocks_vector_to_stream_0
id: blocks_vector_to_stream
- name: grnet_udp_source_0
id: grnet_udp_source
parameters:
affinity: ''
alias: ''
comment: ''
header: '0'
ipv6: 'False'
maxoutbuf: '0'
minoutbuf: '0'
num_items: '500'
notifyMissed: 'False'
payloadsize: '1472'
port: '7778'
srcZeros: 'False'
type: byte
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [211, 167]
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]
coordinate: [37, 173]
rotation: 0
state: true
- 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_waterfall_sink_x_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_tcp_source_0, '0', blocks_vector_to_stream_0, '0']
- [grnet_udp_source_0, '0', blocks_uchar_to_float_0, '0']
metadata:
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) */
#define NO_SYS 1
#define MEM_ALIGNMENT 4
#define LWIP_RAW 0
#define MEM_SIZE 8192 * 8
#define LWIP_RAW 1
#define LWIP_NETCONN 0
#define LWIP_SOCKET 0
#define LWIP_DHCP 0