aboutsummaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/microblaze/apps/txrx.c174
-rw-r--r--firmware/microblaze/lib/memory_map.h3
2 files changed, 96 insertions, 81 deletions
diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c
index 5eec99c4f..a2e3f0430 100644
--- a/firmware/microblaze/apps/txrx.c
+++ b/firmware/microblaze/apps/txrx.c
@@ -54,11 +54,6 @@
#define FW_SETS_SEQNO 1 // define to 0 or 1 (FIXME must be 1 for now)
-#if (FW_SETS_SEQNO)
-static int fw_seqno; // used when f/w is filling in sequence numbers
-#endif
-
-
/*
* Full duplex Tx and Rx between ethernet and DSP pipelines
*
@@ -127,18 +122,14 @@ dbsm_t dsp_rx_sm; // the state machine
// The mac address of the host we're sending to.
eth_mac_addr_t host_mac_addr;
-#define TIME_NOW ((uint32_t)(~0))
-
-// variables for streaming mode
-
-static bool streaming_p = false;
-static unsigned int streaming_items_per_frame = 0;
-static uint32_t time_secs = TIME_NOW;
-static uint32_t time_ticks = TIME_NOW;
-static int streaming_frame_count = 0;
+//controls continuous streaming...
+static bool auto_reload_command = false;
+static size_t streaming_items_per_frame = 0;
+static int streaming_frame_count = 0;
#define FRAMES_PER_CMD 2
-bool is_streaming(void){ return streaming_p; }
+static void setup_network(void);
+static void setup_vrt(void);
// ----------------------------------------------------------------
// the fast-path setup global variables
@@ -159,6 +150,9 @@ void handle_udp_data_packet(
struct socket_address src, struct socket_address dst,
unsigned char *payload, int payload_len
){
+ //store the 2nd word as the following:
+ streaming_items_per_frame = ((uint32_t *)payload)[1];
+
//its a tiny payload, load the fast-path variables
fp_mac_addr_src = *ethernet_mac_addr();
arp_cache_lookup_mac(&src.addr, &fp_mac_addr_dst);
@@ -176,6 +170,24 @@ void handle_udp_data_packet(
print_ip_addr(&fp_socket_dst.addr); newline();
printf(" destination udp port: %d\n", fp_socket_dst.port);
newline();
+
+ //setup network and vrt
+ setup_network();
+ setup_vrt();
+
+ // kick off the state machine
+ dbsm_start(&dsp_rx_sm);
+
+}
+
+static void inline issue_stream_command(size_t nsamps, bool now, bool chain, uint32_t secs, uint32_t ticks, bool start){
+ //printf("Stream cmd: nsamps %d, now %d, chain %d, secs %u, ticks %u\n", (int)nsamps, now, chain, secs, ticks);
+ sr_rx_ctrl->cmd = MK_RX_CMD(nsamps, now, chain);
+
+ if (start) dbsm_start(&dsp_rx_sm);
+
+ sr_rx_ctrl->time_secs = secs;
+ sr_rx_ctrl->time_ticks = ticks; // enqueue command
}
#define OTW_GPIO_BANK_TO_NUM(bank) \
@@ -443,20 +455,68 @@ void handle_udp_ctrl_packet(
ctrl_data_out.id = USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE;
break;
- case USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO:
- time_secs = ctrl_data_in->data.streaming.secs;
- time_ticks = ctrl_data_in->data.streaming.ticks;
- streaming_items_per_frame = ctrl_data_in->data.streaming.samples;
+ /*******************************************************************
+ * Streaming
+ ******************************************************************/
+ case USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO:{
+
+ //issue two commands and set the auto-reload flag
+ if (ctrl_data_in->data.stream_cmd.continuous){
+ printf("Setting up continuous streaming...\n");
+ auto_reload_command = true;
+ streaming_frame_count = FRAMES_PER_CMD;
+
+ issue_stream_command(
+ streaming_items_per_frame * FRAMES_PER_CMD,
+ (ctrl_data_in->data.stream_cmd.now == 0)? false : true, //now
+ true, //chain
+ ctrl_data_in->data.stream_cmd.secs,
+ ctrl_data_in->data.stream_cmd.ticks,
+ true //start
+ );
+
+ issue_stream_command(
+ streaming_items_per_frame * FRAMES_PER_CMD,
+ true, //now
+ true, //chain
+ 0, 0, //time does not matter
+ false
+ );
- if (ctrl_data_in->data.streaming.enabled == 0){
- stop_rx_cmd();
}
+
+ //issue regular stream commands (split commands if too large)
else{
- start_rx_streaming_cmd();
- }
+ auto_reload_command = false;
+ size_t num_samps = ctrl_data_in->data.stream_cmd.num_samps;
+ if (num_samps == 0) num_samps = 1; //FIXME hack, zero is used when stopping continuous streaming but it somehow makes it inifinite
+
+ bool chain = num_samps > MAX_SAMPLES_PER_CMD;
+ issue_stream_command(
+ (chain)? streaming_items_per_frame : num_samps, //nsamps
+ (ctrl_data_in->data.stream_cmd.now == 0)? false : true, //now
+ chain, //chain
+ ctrl_data_in->data.stream_cmd.secs,
+ ctrl_data_in->data.stream_cmd.ticks,
+ false
+ );
- ctrl_data_out.id = USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE;
+ //handle rest of the samples that did not fit into one cmd
+ while(chain){
+ num_samps -= MAX_SAMPLES_PER_CMD;
+ chain = num_samps > MAX_SAMPLES_PER_CMD;
+ issue_stream_command(
+ (chain)? streaming_items_per_frame : num_samps, //nsamps
+ true, //now
+ chain, //chain
+ 0, 0, //time does not matter
+ false
+ );
+ }
+ }
+ ctrl_data_out.id = USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE;
break;
+ }
/*******************************************************************
* DUC
@@ -531,7 +591,7 @@ eth_pkt_inspector(dbsm_t *sm, int bufno)
// In the future, a hardware state machine will do this...
if ( //warning! magic numbers approaching....
(((buff + ((2 + 14 + 20)/sizeof(uint32_t)))[0] & 0xffff) == USRP2_UDP_DATA_PORT) &&
- ((buff + ((2 + 14 + 20 + 8)/sizeof(uint32_t)))[0] != 0)
+ ((buff + ((2 + 14 + 20 + 8)/sizeof(uint32_t)))[0] != USRP2_INVALID_VRT_HEADER)
) return false;
//test if its an ip recovery packet
@@ -557,7 +617,7 @@ eth_pkt_inspector(dbsm_t *sm, int bufno)
//------------------------------------------------------------------
-static uint16_t get_vrt_packet_words(void){
+static size_t get_vrt_packet_words(void){
return streaming_items_per_frame + \
USRP2_HOST_RX_VRT_HEADER_WORDS32 + \
USRP2_HOST_RX_VRT_TRAILER_WORDS32;
@@ -567,9 +627,7 @@ static bool vrt_has_trailer(void){
return USRP2_HOST_RX_VRT_TRAILER_WORDS32 > 0;
}
-void
-restart_streaming(void)
-{
+static void setup_vrt(void){
// setup RX DSP regs
sr_rx_ctrl->nsamples_per_pkt = streaming_items_per_frame;
sr_rx_ctrl->nchannels = 1;
@@ -582,26 +640,6 @@ restart_streaming(void)
);
sr_rx_ctrl->vrt_stream_id = 0;
sr_rx_ctrl->vrt_trailer = 0;
-
- streaming_p = true;
- streaming_frame_count = FRAMES_PER_CMD;
-
- sr_rx_ctrl->cmd =
- MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame,
- (time_ticks==TIME_NOW)?1:0, 1); // conditionally set "now" bit, set "chain" bit
-
- // kick off the state machine
- dbsm_start(&dsp_rx_sm);
-
- sr_rx_ctrl->time_secs = time_secs;
- sr_rx_ctrl->time_ticks = time_ticks; // enqueue first of two commands
-
- // make sure this one and the rest have the "now" and "chain" bits set.
- sr_rx_ctrl->cmd =
- MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame, 1, 1);
-
- sr_rx_ctrl->time_secs = 0;
- sr_rx_ctrl->time_ticks = 0; // enqueue second command
}
/*
@@ -630,19 +668,15 @@ link_changed_callback(int speed)
printf("\neth link changed: speed = %d\n", speed);
}
-void
-start_rx_streaming_cmd(void)
-{
- /*
- * Construct ethernet header and preload into two buffers
- */
+static void setup_network(void){
+ //setup header and load into two buffers
struct {
uint32_t ctrl_word;
} mem _AL4;
memset(&mem, 0, sizeof(mem));
- printf("samples per frame: %d\n", streaming_items_per_frame);
- printf("words in a vrt packet %d\n", get_vrt_packet_words());
+ printf("items per frame: %d\n", (int)streaming_items_per_frame);
+ printf("words in a vrt packet %d\n", (int)get_vrt_packet_words());
mem.ctrl_word = get_vrt_packet_words()*sizeof(uint32_t) | 1 << 16;
memcpy_wa(buffer_ram(DSP_RX_BUF_0), &mem, sizeof(mem));
@@ -678,26 +712,6 @@ start_rx_streaming_cmd(void)
sr_udp_sm->udp_hdr.dst_port = fp_socket_dst.port;
sr_udp_sm->udp_hdr.length = UDP_SM_INS_UDP_LEN;
sr_udp_sm->udp_hdr.checksum = UDP_SM_LAST_WORD; // zero UDP checksum
-
- if (FW_SETS_SEQNO)
- fw_seqno = 0;
-
- restart_streaming();
-}
-
-void
-stop_rx_cmd(void)
-{
- if (is_streaming()){
- streaming_p = false;
-
- // no samples, "now", not chained
- sr_rx_ctrl->cmd = MK_RX_CMD(0, 1, 0);
-
- sr_rx_ctrl->time_secs = 0;
- sr_rx_ctrl->time_ticks = 0; // enqueue command
- }
-
}
#if (FW_SETS_SEQNO)
@@ -713,10 +727,10 @@ bool
fw_sets_seqno_inspector(dbsm_t *sm, int buf_this) // returns false
{
// queue up another rx command when required
- if (streaming_p && --streaming_frame_count == 0){
+ if (auto_reload_command && --streaming_frame_count == 0){
streaming_frame_count = FRAMES_PER_CMD;
sr_rx_ctrl->time_secs = 0;
- sr_rx_ctrl->time_ticks = 0;
+ sr_rx_ctrl->time_ticks = 0; //enqueue last command
}
return false; // we didn't handle the packet
@@ -820,7 +834,7 @@ main(void)
// FIXME Figure out how to handle this robustly.
// Any buffers that are emptying should be allowed to drain...
- if (streaming_p){
+ if (auto_reload_command){
// restart_streaming();
// FIXME report error
}
diff --git a/firmware/microblaze/lib/memory_map.h b/firmware/microblaze/lib/memory_map.h
index bb6a1036d..fed1e5259 100644
--- a/firmware/microblaze/lib/memory_map.h
+++ b/firmware/microblaze/lib/memory_map.h
@@ -525,8 +525,9 @@ typedef struct {
volatile uint32_t pad[7]; // Make each structure 16 elements long
} sr_rx_ctrl_t;
+#define MAX_SAMPLES_PER_CMD 0x3fffffff
#define MK_RX_CMD(nsamples, now, chain) \
- ((((now) & 0x1) << 31) | ((chain & 0x1) << 30) | ((nsamples) & 0x3fffffff))
+ ((((now) & 0x1) << 31) | (((chain) & 0x1) << 30) | ((nsamples) & 0x3fffffff))
#define sr_rx_ctrl ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL))