aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/microblaze/apps/txrx.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/microblaze/apps/txrx.c')
-rw-r--r--firmware/microblaze/apps/txrx.c206
1 files changed, 135 insertions, 71 deletions
diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c
index 77c8e498c..b82c7702b 100644
--- a/firmware/microblaze/apps/txrx.c
+++ b/firmware/microblaze/apps/txrx.c
@@ -47,6 +47,8 @@
#include <i2c.h>
#include <lsdac.h>
#include <lsadc.h>
+#include <ethertype.h>
+#include <arp_cache.h>
#define FW_SETS_SEQNO 1 // define to 0 or 1 (FIXME must be 1 for now)
@@ -136,30 +138,42 @@ static int streaming_frame_count = 0;
bool is_streaming(void){ return streaming_p; }
-
// ----------------------------------------------------------------
+// the fast-path setup global variables
+// ----------------------------------------------------------------
+static eth_mac_addr_t fp_mac_addr_src, fp_mac_addr_dst;
+static struct socket_address fp_socket_src, fp_socket_dst;
-void start_rx_streaming_cmd(void *p);
+// ----------------------------------------------------------------
+void start_rx_streaming_cmd(void);
void stop_rx_cmd(void);
-static eth_mac_addr_t get_my_eth_mac_addr(void){
- return *ethernet_mac_addr();
+static void print_ip_addr(const void *t){
+ uint8_t *p = (uint8_t *)t;
+ printf("%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
}
-static struct ip_addr get_my_ip_addr(void){
- struct ip_addr addr;
- addr.addr = 192 << 24 | 168 << 16 | 10 << 8 | 2 << 0;
- return addr;
-}
-
-static bool _is_data;
-
void handle_udp_data_packet(
struct socket_address src, struct socket_address dst,
unsigned char *payload, int payload_len
){
- //TODO store the reply port
- _is_data = true;
+ //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);
+ fp_socket_src = dst;
+ fp_socket_dst = src;
+ printf("Storing for fast path:\n");
+ printf(" source mac addr: ");
+ print_mac_addr(fp_mac_addr_src.addr); newline();
+ printf(" source ip addr: ");
+ print_ip_addr(&fp_socket_src.addr); newline();
+ printf(" source udp port: %d\n", fp_socket_src.port);
+ printf(" destination mac addr: ");
+ print_mac_addr(fp_mac_addr_dst.addr); newline();
+ printf(" destination ip addr: ");
+ print_ip_addr(&fp_socket_dst.addr); newline();
+ printf(" destination udp port: %d\n", fp_socket_dst.port);
+ newline();
}
#define OTW_GPIO_BANK_TO_NUM(bank) \
@@ -190,14 +204,24 @@ void handle_udp_ctrl_packet(
******************************************************************/
case USRP2_CTRL_ID_GIVE_ME_YOUR_IP_ADDR_BRO:
ctrl_data_out.id = USRP2_CTRL_ID_THIS_IS_MY_IP_ADDR_DUDE;
- struct ip_addr ip_addr = get_my_ip_addr();
- memcpy(&ctrl_data_out.data.ip_addr, &ip_addr, sizeof(ip_addr));
+ memcpy(&ctrl_data_out.data.ip_addr, get_ip_addr(), sizeof(struct ip_addr));
+ break;
+
+ case USRP2_CTRL_ID_HERE_IS_A_NEW_IP_ADDR_BRO:
+ ctrl_data_out.id = USRP2_CTRL_ID_THIS_IS_MY_IP_ADDR_DUDE;
+ set_ip_addr((struct ip_addr *)&ctrl_data_in->data.ip_addr);
+ memcpy(&ctrl_data_out.data.ip_addr, get_ip_addr(), sizeof(struct ip_addr));
break;
case USRP2_CTRL_ID_GIVE_ME_YOUR_MAC_ADDR_BRO:
ctrl_data_out.id = USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE;
- eth_mac_addr_t mac_addr = get_my_eth_mac_addr();
- memcpy(&ctrl_data_out.data.mac_addr, &mac_addr, sizeof(mac_addr));
+ memcpy(&ctrl_data_out.data.mac_addr, ethernet_mac_addr(), sizeof(eth_mac_addr_t));
+ break;
+
+ case USRP2_CTRL_ID_HERE_IS_A_NEW_MAC_ADDR_BRO:
+ ctrl_data_out.id = USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE;
+ ethernet_set_mac_addr((eth_mac_addr_t *)&ctrl_data_in->data.mac_addr);
+ memcpy(&ctrl_data_out.data.mac_addr, ethernet_mac_addr(), sizeof(eth_mac_addr_t));
break;
case USRP2_CTRL_ID_GIVE_ME_YOUR_DBOARD_IDS_BRO:
@@ -394,6 +418,7 @@ void handle_udp_ctrl_packet(
******************************************************************/
case USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO:
dsp_rx_regs->freq = ctrl_data_in->data.ddc_args.freq_word;
+ dsp_rx_regs->scale_iq = ctrl_data_in->data.ddc_args.scale_iq;
//setup the interp and half band filters
{
@@ -419,11 +444,13 @@ void handle_udp_ctrl_packet(
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;
+
if (ctrl_data_in->data.streaming.enabled == 0){
stop_rx_cmd();
}
else{
- start_rx_streaming_cmd(NULL);
+ start_rx_streaming_cmd();
}
ctrl_data_out.id = USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE;
@@ -457,6 +484,25 @@ void handle_udp_ctrl_packet(
ctrl_data_out.id = USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE;
break;
+ /*******************************************************************
+ * Time Config
+ ******************************************************************/
+ case USRP2_CTRL_ID_GOT_A_NEW_TIME_FOR_YOU_BRO:
+ sr_time64->imm = (ctrl_data_in->data.time_args.now == 0)? 0 : 1;
+ sr_time64->ticks = ctrl_data_in->data.time_args.ticks;
+ sr_time64->secs = ctrl_data_in->data.time_args.secs; //set this last to latch the regs
+ ctrl_data_out.id = USRP2_CTRL_ID_SWEET_I_GOT_THAT_TIME_DUDE;
+ break;
+
+ /*******************************************************************
+ * MUX Config
+ ******************************************************************/
+ case USRP2_CTRL_ID_UPDATE_THOSE_MUX_SETTINGS_BRO:
+ dsp_rx_regs->rx_mux = ctrl_data_in->data.mux_args.rx_mux;
+ dsp_tx_regs->tx_mux = ctrl_data_in->data.mux_args.tx_mux;
+ ctrl_data_out.id = USRP2_CTRL_ID_UPDATED_THE_MUX_SETTINGS_DUDE;
+ break;
+
default:
ctrl_data_out.id = USRP2_CTRL_ID_HUH_WHAT;
@@ -472,15 +518,52 @@ void handle_udp_ctrl_packet(
static bool
eth_pkt_inspector(dbsm_t *sm, int bufno)
{
- _is_data = false;
- handle_eth_packet(buffer_ram(bufno), buffer_pool_status->last_line[bufno] - 3);
- return !_is_data;
+ //point me to the ethernet frame
+ uint32_t *buff = (uint32_t *)buffer_ram(bufno);
+
+ //treat this as fast-path data?
+ // We have to do this operation as fast as possible.
+ // Therefore, we do not check all the headers,
+ // just check that the udp port matches
+ // and that the vrt header is non zero.
+ // 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)
+ ) return false;
+
+ //test if its an ip recovery packet
+ typedef struct{
+ padded_eth_hdr_t eth_hdr;
+ char code[4];
+ union {
+ struct ip_addr ip_addr;
+ } data;
+ }recovery_packet_t;
+ recovery_packet_t *recovery_packet = (recovery_packet_t *)buff;
+ if (recovery_packet->eth_hdr.ethertype == 0xbeee && strncmp(recovery_packet->code, "addr", 4) == 0){
+ printf("Got ip recovery packet: "); print_ip_addr(&recovery_packet->data.ip_addr); newline();
+ set_ip_addr(&recovery_packet->data.ip_addr);
+ return true;
+ }
+
+ //pass it to the slow-path handler
+ size_t len = buffer_pool_status->last_line[bufno] - 3;
+ handle_eth_packet(buff, len);
+ return true;
}
//------------------------------------------------------------------
-#define VRT_HEADER_WORDS 5
-#define VRT_TRAILER_WORDS 1
+static uint16_t get_vrt_packet_words(void){
+ return streaming_items_per_frame + \
+ USRP2_HOST_RX_VRT_HEADER_WORDS32 + \
+ USRP2_HOST_RX_VRT_TRAILER_WORDS32;
+}
+
+static bool vrt_has_trailer(void){
+ return USRP2_HOST_RX_VRT_TRAILER_WORDS32 > 0;
+}
void
restart_streaming(void)
@@ -491,10 +574,10 @@ restart_streaming(void)
sr_rx_ctrl->clear_overrun = 1; // reset
sr_rx_ctrl->vrt_header = (0
| VRTH_PT_IF_DATA_WITH_SID
- | VRTH_HAS_TRAILER
+ | (vrt_has_trailer()? VRTH_HAS_TRAILER : 0)
| VRTH_TSI_OTHER
| VRTH_TSF_SAMPLE_CNT
- | (VRT_HEADER_WORDS+streaming_items_per_frame+VRT_TRAILER_WORDS));
+ );
sr_rx_ctrl->vrt_stream_id = 0;
sr_rx_ctrl->vrt_trailer = 0;
@@ -524,14 +607,14 @@ restart_streaming(void)
*
* init chksum to zero to start.
*/
-/*static unsigned int
+static unsigned int
CHKSUM(unsigned int x, unsigned int *chksum)
{
*chksum += x;
*chksum = (*chksum & 0xffff) + (*chksum>>16);
*chksum = (*chksum & 0xffff) + (*chksum>>16);
return x;
-}*/
+}
/*
* Called when eth phy state changes (w/ interrupts disabled)
@@ -546,7 +629,7 @@ link_changed_callback(int speed)
}
void
-start_rx_streaming_cmd(void *p)
+start_rx_streaming_cmd(void)
{
/*
* Construct ethernet header and preload into two buffers
@@ -556,31 +639,32 @@ start_rx_streaming_cmd(void *p)
} mem _AL4;
memset(&mem, 0, sizeof(mem));
- //p->items_per_frame = (1500)/sizeof(uint32_t) - (DSP_TX_FIRST_LINE + VRT_HEADER_WORDS + VRT_TRAILER_WORDS); //FIXME
- //mem.ctrl_word = (VRT_HEADER_WORDS+p->items_per_frame+VRT_TRAILER_WORDS)*sizeof(uint32_t) | 1 << 16;
+ printf("samples per frame: %d\n", streaming_items_per_frame);
+ printf("words in a vrt packet %d\n", 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));
memcpy_wa(buffer_ram(DSP_RX_BUF_1), &mem, sizeof(mem));
//setup ethernet header machine
- /*sr_udp_sm->eth_hdr.mac_dst_0_1 = (host_dst_mac_addr.addr[0] << 8) | host_dst_mac_addr.addr[1];
- sr_udp_sm->eth_hdr.mac_dst_2_3 = (host_dst_mac_addr.addr[2] << 8) | host_dst_mac_addr.addr[3];
- sr_udp_sm->eth_hdr.mac_dst_4_5 = (host_dst_mac_addr.addr[4] << 8) | host_dst_mac_addr.addr[5];
- sr_udp_sm->eth_hdr.mac_src_0_1 = (host_src_mac_addr.addr[0] << 8) | host_src_mac_addr.addr[1];
- sr_udp_sm->eth_hdr.mac_src_2_3 = (host_src_mac_addr.addr[2] << 8) | host_src_mac_addr.addr[3];
- sr_udp_sm->eth_hdr.mac_src_4_5 = (host_src_mac_addr.addr[4] << 8) | host_src_mac_addr.addr[5];
- sr_udp_sm->eth_hdr.ether_type = ETHERTYPE_IPV4;*/
+ sr_udp_sm->eth_hdr.mac_dst_0_1 = (fp_mac_addr_dst.addr[0] << 8) | fp_mac_addr_dst.addr[1];
+ sr_udp_sm->eth_hdr.mac_dst_2_3 = (fp_mac_addr_dst.addr[2] << 8) | fp_mac_addr_dst.addr[3];
+ sr_udp_sm->eth_hdr.mac_dst_4_5 = (fp_mac_addr_dst.addr[4] << 8) | fp_mac_addr_dst.addr[5];
+ sr_udp_sm->eth_hdr.mac_src_0_1 = (fp_mac_addr_src.addr[0] << 8) | fp_mac_addr_src.addr[1];
+ sr_udp_sm->eth_hdr.mac_src_2_3 = (fp_mac_addr_src.addr[2] << 8) | fp_mac_addr_src.addr[3];
+ sr_udp_sm->eth_hdr.mac_src_4_5 = (fp_mac_addr_src.addr[4] << 8) | fp_mac_addr_src.addr[5];
+ sr_udp_sm->eth_hdr.ether_type = ETHERTYPE_IPV4;
//setup ip header machine
- /*unsigned int chksum = 0;
+ unsigned int chksum = 0;
sr_udp_sm->ip_hdr.ver_ihl_tos = CHKSUM(0x4500, &chksum); // IPV4, 5 words of header (20 bytes), TOS=0
sr_udp_sm->ip_hdr.total_length = UDP_SM_INS_IP_LEN; // Don't checksum this line in SW
sr_udp_sm->ip_hdr.identification = CHKSUM(0x0000, &chksum); // ID
sr_udp_sm->ip_hdr.flags_frag_off = CHKSUM(0x4000, &chksum); // don't fragment
sr_udp_sm->ip_hdr.ttl_proto = CHKSUM(0x2011, &chksum); // TTL=32, protocol = UDP (17 decimal)
//sr_udp_sm->ip_hdr.checksum .... filled in below
- uint32_t src_ip_addr = host_src_ip_addr.s_addr;
- uint32_t dst_ip_addr = host_dst_ip_addr.s_addr;
+ uint32_t src_ip_addr = fp_socket_src.addr.addr;
+ uint32_t dst_ip_addr = fp_socket_dst.addr.addr;
sr_udp_sm->ip_hdr.src_addr_high = CHKSUM(src_ip_addr >> 16, &chksum); // IP src high
sr_udp_sm->ip_hdr.src_addr_low = CHKSUM(src_ip_addr & 0xffff, &chksum); // IP src low
sr_udp_sm->ip_hdr.dst_addr_high = CHKSUM(dst_ip_addr >> 16, &chksum); // IP dst high
@@ -588,17 +672,14 @@ start_rx_streaming_cmd(void *p)
sr_udp_sm->ip_hdr.checksum = UDP_SM_INS_IP_HDR_CHKSUM | (chksum & 0xffff);
//setup the udp header machine
- sr_udp_sm->udp_hdr.src_port = host_src_udp_port;
- sr_udp_sm->udp_hdr.dst_port = host_dst_udp_port;
+ sr_udp_sm->udp_hdr.src_port = fp_socket_src.port;
+ 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*/
+ sr_udp_sm->udp_hdr.checksum = UDP_SM_LAST_WORD; // zero UDP checksum
if (FW_SETS_SEQNO)
fw_seqno = 0;
- //streaming_items_per_frame = p->items_per_frame;
- //time_secs = p->time_secs;
- //time_ticks = p->time_ticks;
restart_streaming();
}
@@ -617,25 +698,6 @@ stop_rx_cmd(void)
}
-
-/*static void
-setup_tx()
-{
- sr_tx_ctrl->clear_state = 1;
- bp_clear_buf(DSP_TX_BUF_0);
- bp_clear_buf(DSP_TX_BUF_1);
-
- int tx_scale = 256;
- int interp = 32;
-
- // setup some defaults
-
- dsp_tx_regs->freq = 0;
- dsp_tx_regs->scale_iq = (tx_scale << 16) | tx_scale;
- dsp_tx_regs->interp_rate = interp;
-}*/
-
-
#if (FW_SETS_SEQNO)
/*
* Debugging ONLY. This will be handled by the tx_protocol_engine.
@@ -677,12 +739,14 @@ main(void)
putstr("\nTxRx-NEWETH\n");
print_mac_addr(ethernet_mac_addr()->addr);
newline();
+ print_ip_addr(get_ip_addr()); newline();
ethernet_register_link_changed_callback(link_changed_callback);
ethernet_init();
- register_get_eth_mac_addr(get_my_eth_mac_addr);
- register_get_ip_addr(get_my_ip_addr);
+ register_mac_addr(ethernet_mac_addr());
+ register_ip_addr(get_ip_addr());
+
register_udp_listener(USRP2_UDP_CTRL_PORT, handle_udp_ctrl_packet);
register_udp_listener(USRP2_UDP_DATA_PORT, handle_udp_data_packet);
@@ -724,9 +788,9 @@ main(void)
// tell app_common that this dbsm could be sending to the ethernet
ac_could_be_sending_to_eth = &dsp_rx_sm;
-
- // program tx registers
- //setup_tx();
+ sr_tx_ctrl->clear_state = 1;
+ bp_clear_buf(DSP_TX_BUF_0);
+ bp_clear_buf(DSP_TX_BUF_1);
// kick off the state machine
dbsm_start(&dsp_tx_sm);