summaryrefslogtreecommitdiffstats
path: root/firmware/zpu
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/zpu')
-rw-r--r--firmware/zpu/apps/txrx_uhd.c44
-rw-r--r--firmware/zpu/lib/net_common.c2
-rw-r--r--firmware/zpu/lib/udp_uart.c115
-rw-r--r--firmware/zpu/lib/udp_uart.h36
-rw-r--r--firmware/zpu/usrp2/CMakeLists.txt1
-rw-r--r--firmware/zpu/usrp2p/CMakeLists.txt1
6 files changed, 158 insertions, 41 deletions
diff --git a/firmware/zpu/apps/txrx_uhd.c b/firmware/zpu/apps/txrx_uhd.c
index 9d0a28b58..f9eedfc7d 100644
--- a/firmware/zpu/apps/txrx_uhd.c
+++ b/firmware/zpu/apps/txrx_uhd.c
@@ -72,12 +72,6 @@ static void handle_udp_data_packet(
sr_tx_ctrl->cyc_per_up = 0;
break;
- case USRP2_UDP_UART_BASE_PORT+0:
- case USRP2_UDP_UART_BASE_PORT+1:
- case USRP2_UDP_UART_BASE_PORT+2:
- turn_off_uart(src.port-USRP2_UDP_UART_BASE_PORT);
- break;
-
default: return;
}
@@ -116,7 +110,7 @@ static void handle_udp_ctrl_packet(
//ensure that the protocol versions match
if (payload_len >= sizeof(uint32_t) && ctrl_data_in->proto_ver != USRP2_FW_COMPAT_NUM){
- printf("!Error in control packet handler: Expected compatibility number %d, but got %d\n",
+ if (ctrl_data_in->proto_ver) printf("!Error in control packet handler: Expected compatibility number %d, but got %d\n",
USRP2_FW_COMPAT_NUM, ctrl_data_in->proto_ver
);
ctrl_data_in_id = USRP2_CTRL_ID_WAZZUP_BRO;
@@ -228,32 +222,6 @@ static void handle_udp_ctrl_packet(
break;
/*******************************************************************
- * UART Control
- ******************************************************************/
-/*
- case USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO:{
- //executes a readline()-style read, up to num_bytes long, up to and including newline
- int num_bytes = ctrl_data_in->data.uart_args.bytes;
- if(num_bytes > 20) num_bytes = 20;
- num_bytes = fngets_noblock(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_out.data.uart_args.data, num_bytes);
- ctrl_data_out.id = USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE;
- ctrl_data_out.data.uart_args.bytes = num_bytes;
- break;
- }
-
- case USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO:{
- int num_bytes = ctrl_data_in->data.uart_args.bytes;
- if(num_bytes > 20) num_bytes = 20;
- //before we write to the UART, we flush the receive buffer
- //this assumes that we're interested in the reply
- hal_uart_rx_flush(ctrl_data_in->data.uart_args.dev);
- fnputstr(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes);
- ctrl_data_out.id = USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE;
- ctrl_data_out.data.uart_args.bytes = num_bytes;
- break;
- }
-*/
- /*******************************************************************
* Echo test
******************************************************************/
case USRP2_CTRL_ID_HOLLER_AT_ME_BRO:
@@ -347,11 +315,10 @@ main(void)
#ifdef USRP2P
register_udp_listener(USRP2_UDP_UPDATE_PORT, handle_udp_fw_update_packet);
- int i;
- for(i=0; i<NUM_UARTS; i++)
- register_udp_listener(USRP2_UDP_UART_BASE_PORT+i, handle_uart_data_packet);
#endif
+ udp_uart_init(USRP2_UDP_UART_BASE_PORT); //setup uart messaging
+
//3) set the routing mode to slave to set defaults
pkt_ctrl_set_routing_mode(PKT_CTRL_ROUTING_MODE_SLAVE);
@@ -368,10 +335,7 @@ main(void)
pkt_ctrl_release_incoming_buffer();
}
-#ifdef USRP2P
- //look for incoming data on the four UARTs and handle it
- poll_uarts();
-#endif
+ udp_uart_poll(); //uart message handling
pic_interrupt_handler();
/*
diff --git a/firmware/zpu/lib/net_common.c b/firmware/zpu/lib/net_common.c
index 698ed97f4..42e365393 100644
--- a/firmware/zpu/lib/net_common.c
+++ b/firmware/zpu/lib/net_common.c
@@ -201,7 +201,7 @@ send_pkt(
//create a list of all buffers to copy
const void *buffs[] = {&ctrl_word, &ehdr, buf0, buf1, buf2};
- size_t lens[] = {sizeof(ctrl_word), sizeof(ehdr), len0, len1, len2};
+ size_t lens[] = {sizeof(ctrl_word), sizeof(ehdr), len0, len1, (len2 + 3) & ~3};
//copy each buffer into the out buffer
for (size_t i = 0; i < sizeof(buffs)/sizeof(buffs[0]); i++){
diff --git a/firmware/zpu/lib/udp_uart.c b/firmware/zpu/lib/udp_uart.c
new file mode 100644
index 000000000..6f6b9ee91
--- /dev/null
+++ b/firmware/zpu/lib/udp_uart.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2011 Ettus Research LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "udp_uart.h"
+#include "hal_uart.h"
+#include "net_common.h"
+#include "compiler.h"
+#include <stdbool.h>
+
+/***********************************************************************
+ * Constants
+ **********************************************************************/
+#define MAX_NUM_UARTS 4
+#ifndef UDP_UART_MASK
+ #error missing definition for UDP_UART_MASK enable mask
+#endif
+static const size_t num_idle_cyc_b4_flush = 11; //small but lucky number
+
+/***********************************************************************
+ * Globals
+ **********************************************************************/
+static uint16_t _base_port;
+
+typedef struct{
+ struct socket_address dst;
+ _AL4 uint8_t buf[256];
+ size_t len; //length of buffer
+ size_t cyc; //idle cycle count
+} udp_uart_state_t;
+
+static udp_uart_state_t _states[MAX_NUM_UARTS];
+
+/***********************************************************************
+ * UDP handler for UARTs
+ **********************************************************************/
+static void handle_uart_data_packet(
+ struct socket_address src, struct socket_address dst,
+ unsigned char *payload, int payload_len
+){
+ //handle ICMP destination unreachable
+ if (payload == NULL){
+ const size_t which = src.port-_base_port;
+ if (which >= MAX_NUM_UARTS) return;
+ _states[which].dst.port = 0;
+ }
+
+ //handle a regular blocking UART write
+ else{
+ const size_t which = dst.port-_base_port;
+ if (which >= MAX_NUM_UARTS) return;
+ _states[which].dst = src;
+ for (size_t i = 0; i < payload_len; i++){
+ hal_uart_putc((hal_uart_name_t)which, (int)payload[i]);
+ }
+ }
+}
+
+/***********************************************************************
+ * Public init function
+ **********************************************************************/
+void udp_uart_init(const uint16_t base_port){
+ _base_port = base_port;
+ for(size_t i = 0; i < MAX_NUM_UARTS; i++){
+ _states[i].dst.port = 0; //reset to null port
+ _states[i].len = 0;
+ _states[i].cyc = 0;
+ register_udp_listener(_base_port+i, handle_uart_data_packet);
+ }
+}
+
+/***********************************************************************
+ * Public poll function
+ **********************************************************************/
+void udp_uart_poll(void){
+ for (size_t i = 0; i < MAX_NUM_UARTS; i++){
+ if (((UDP_UART_MASK) & (1 << i)) == 0) continue;
+
+ bool newline = false;
+ udp_uart_state_t *state = &_states[i];
+
+ //read all characters we can without blocking
+ for (size_t j = state->len; j < sizeof(_states[0].buf); j++){
+ uint8_t ch = hal_uart_getc_noblock((hal_uart_name_t)i);
+ if (ch == 255) break;
+ if (ch == '\n' || ch == '\r') newline = true;
+ state->buf[j] = ch;
+ state->len++;
+ state->cyc = 0; //reset idle cycles
+ }
+
+ //nothing in buffer, continue to next uart
+ if (state->len == 0) continue;
+
+ //send out a message if newline or forced flush
+ if (newline || state->cyc++ > num_idle_cyc_b4_flush){
+ if (state->dst.port != 0) send_udp_pkt(_base_port+i, state->dst, state->buf, state->len);
+ state->len = 0;
+ state->cyc = 0;
+ }
+ }
+}
diff --git a/firmware/zpu/lib/udp_uart.h b/firmware/zpu/lib/udp_uart.h
new file mode 100644
index 000000000..d448e7611
--- /dev/null
+++ b/firmware/zpu/lib/udp_uart.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2011 Ettus Research LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDED_UDP_UART_H
+#define INCLUDED_UDP_UART_H
+
+#include <stdint.h>
+
+/*!
+ * Initialize the UDP/UART module.
+ * Registers handler into the network.
+ * \param base_port the source port for UART0
+ */
+void udp_uart_init(const uint16_t base_port);
+
+/*!
+ * Polls the UART state machine,
+ * and sends messages over UDP.
+ */
+void udp_uart_poll(void);
+
+#endif /* INCLUDED_UDP_UART_H */
diff --git a/firmware/zpu/usrp2/CMakeLists.txt b/firmware/zpu/usrp2/CMakeLists.txt
index 190ea9af1..3662532f1 100644
--- a/firmware/zpu/usrp2/CMakeLists.txt
+++ b/firmware/zpu/usrp2/CMakeLists.txt
@@ -20,6 +20,7 @@ INCLUDE(${CMAKE_SOURCE_DIR}/lib/CMakeLists.txt)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
ADD_DEFINITIONS(-DUSRP2)
+ADD_DEFINITIONS(-DUDP_UART_MASK=0)
ADD_LIBRARY(libusrp2fw STATIC
${COMMON_SRCS}
diff --git a/firmware/zpu/usrp2p/CMakeLists.txt b/firmware/zpu/usrp2p/CMakeLists.txt
index 976dccb9a..4cb663742 100644
--- a/firmware/zpu/usrp2p/CMakeLists.txt
+++ b/firmware/zpu/usrp2p/CMakeLists.txt
@@ -20,6 +20,7 @@ INCLUDE(${CMAKE_SOURCE_DIR}/lib/CMakeLists.txt)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
ADD_DEFINITIONS(-DUSRP2P)
+ADD_DEFINITIONS(-DUDP_UART_MASK=4) #GPS=UART2 streaming enabled
ADD_LIBRARY(libusrp2pfw STATIC
${COMMON_SRCS}