aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/microblaze/apps/txrx.c
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-03-25 18:36:16 -0700
committerJosh Blum <josh@joshknows.com>2010-03-25 18:36:16 -0700
commitaf586ae149fe6f7aa12d4d6766e4216f3f00d1c0 (patch)
tree4edc587df783b521c0d900d8785ab05296c6efe3 /firmware/microblaze/apps/txrx.c
parent7d195aa792037f0b5bce5085fb2db3512b479575 (diff)
downloaduhd-af586ae149fe6f7aa12d4d6766e4216f3f00d1c0.tar.gz
uhd-af586ae149fe6f7aa12d4d6766e4216f3f00d1c0.tar.bz2
uhd-af586ae149fe6f7aa12d4d6766e4216f3f00d1c0.zip
Overhaullllllled the way we do streaming. There is an odd bug where
a zero length command (now, no chain) used to stop the streaming. Now it seems to do the reverse... must investigate. Made all clock configuration into enums. The strings were painful and there cant be that many variations that enums cant cover them. The enums will make more sense to developers than mystery strings.
Diffstat (limited to 'firmware/microblaze/apps/txrx.c')
-rw-r--r--firmware/microblaze/apps/txrx.c174
1 files changed, 94 insertions, 80 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
}