aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-05-10 14:18:00 -0700
committerJosh Blum <josh@joshknows.com>2010-05-10 14:18:00 -0700
commit650e0d9b35eeca9cec3989159310f4d5e3d38836 (patch)
treed311fffb7abb84e61c76251df5cdcd0383cf3918
parent9c7c178f70f8a78dc638d5f4301407893351b4fd (diff)
parent30bd666e306cb8f8c947c6ba99a76f7c49484597 (diff)
downloaduhd-650e0d9b35eeca9cec3989159310f4d5e3d38836.tar.gz
uhd-650e0d9b35eeca9cec3989159310f4d5e3d38836.tar.bz2
uhd-650e0d9b35eeca9cec3989159310f4d5e3d38836.zip
Merge branch 'shrinkfw' into usrp2
-rw-r--r--firmware/microblaze/apps/txrx_uhd.c145
-rw-r--r--firmware/microblaze/lib/Makefile.am1
-rw-r--r--firmware/microblaze/lib/banal.c18
-rw-r--r--firmware/microblaze/lib/banal.h3
-rw-r--r--firmware/microblaze/lib/hal_io.c128
-rw-r--r--firmware/microblaze/lib/hal_io.h58
-rw-r--r--firmware/microblaze/lib/memory_map.h4
-rw-r--r--firmware/microblaze/lib/print_fxpt.c83
-rw-r--r--firmware/microblaze/lib/print_mac_addr.c10
-rw-r--r--firmware/microblaze/lib/u2_init.c21
-rw-r--r--fpga/usrp2/vrt/vita_rx_control.v24
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp3
-rw-r--r--host/lib/usrp/usrp2/fw_common.h14
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp22
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp72
-rw-r--r--host/lib/usrp/usrp2/usrp2_regs.hpp39
16 files changed, 112 insertions, 533 deletions
diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c
index 8ff3b8c58..db830fa51 100644
--- a/firmware/microblaze/apps/txrx_uhd.c
+++ b/firmware/microblaze/apps/txrx_uhd.c
@@ -22,8 +22,6 @@
#include "config.h"
#endif
-#define DEBUG_MODE 0 //0 for normal operation
-
#include <lwip/ip.h>
#include <lwip/udp.h>
#include "u2_init.h"
@@ -49,8 +47,6 @@
#include <ethertype.h>
#include <arp_cache.h>
-#define LEDS_SW LED_A
-
/*
* Full duplex Tx and Rx between ethernet and DSP pipelines
*
@@ -126,14 +122,7 @@ 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;
-//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
-
static void setup_network(void);
-static void setup_vrt(void);
// ----------------------------------------------------------------
// the fast-path setup global variables
@@ -154,9 +143,6 @@ 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);
@@ -177,23 +163,12 @@ void handle_udp_data_packet(
//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) \
(((bank) == USRP2_DIR_RX)? (GPIO_RX_BANK) : (GPIO_TX_BANK))
@@ -304,72 +279,6 @@ void handle_udp_ctrl_packet(
break;
/*******************************************************************
- * 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");
- printf("items per frame: %d\n", (int)streaming_items_per_frame);
- hal_set_leds(LED_A, LEDS_SW);
- 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
- );
-
- }
-
- //issue regular stream commands (split commands if too large)
- else{
- hal_set_leds(0, LEDS_SW);
- 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
- (ctrl_data_in->data.stream_cmd.chain == 0)? chain : true, //chain
- ctrl_data_in->data.stream_cmd.secs,
- ctrl_data_in->data.stream_cmd.ticks,
- false
- );
-
- //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
- (ctrl_data_in->data.stream_cmd.chain == 0)? chain : true, //chain
- 0, 0, //time does not matter
- false
- );
- }
- }
- ctrl_data_out.id = USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE;
- break;
- }
-
- /*******************************************************************
* Peek and Poke Register
******************************************************************/
case USRP2_CTRL_ID_POKE_THIS_REGISTER_FOR_ME_BRO:
@@ -463,25 +372,6 @@ eth_pkt_inspector(dbsm_t *sm, int bufno)
//------------------------------------------------------------------
-static bool vrt_has_trailer(void){
- return USRP2_HOST_RX_VRT_TRAILER_WORDS32 > 0;
-}
-
-static void setup_vrt(void){
- // setup RX DSP regs
- sr_rx_ctrl->nsamples_per_pkt = streaming_items_per_frame;
- sr_rx_ctrl->nchannels = 1;
- sr_rx_ctrl->clear_overrun = 1; // reset
- sr_rx_ctrl->vrt_header = (0
- | VRTH_PT_IF_DATA_WITH_SID
- | (vrt_has_trailer()? VRTH_HAS_TRAILER : 0)
- | VRTH_TSI_OTHER
- | VRTH_TSF_SAMPLE_CNT
- );
- sr_rx_ctrl->vrt_stream_id = 0;
- sr_rx_ctrl->vrt_trailer = 0;
-}
-
/*
* 1's complement sum for IP and UDP headers
*
@@ -554,13 +444,6 @@ fw_sets_seqno_inspector(dbsm_t *sm, int buf_this) // returns false
buff->control_word = MK_RX_CTRL_WORD(vrt_len);
buff->vrt_header[0] = (buff->vrt_header[0] & ~VRTH_PKT_SIZE_MASK) | (vrt_len & VRTH_PKT_SIZE_MASK);
- // queue up another rx command when required
- 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; //enqueue last command
- }
-
return false; // we didn't handle the packet
}
@@ -594,27 +477,6 @@ main(void)
register_udp_listener(USRP2_UDP_CTRL_PORT, handle_udp_ctrl_packet);
register_udp_listener(USRP2_UDP_DATA_PORT, handle_udp_data_packet);
- hal_set_led_src(0, LEDS_SW);
-
-#if 0
- // make bit 15 of Tx gpio's be a s/w output
- hal_gpio_set_sel(GPIO_TX_BANK, 15, 's');
- hal_gpio_set_ddr(GPIO_TX_BANK, 0x8000, 0x8000);
-#endif
-
-//set them all to the atr settings by default
-hal_gpio_set_sels(GPIO_TX_BANK, "aaaaaaaaaaaaaaaa");
-hal_gpio_set_sels(GPIO_RX_BANK, "aaaaaaaaaaaaaaaa");
-
- output_regs->debug_mux_ctrl = 1;
-#if DEBUG_MODE
- hal_gpio_set_sels(GPIO_TX_BANK, "0000000000000000");
- hal_gpio_set_sels(GPIO_RX_BANK, "0000000000000000");
- hal_gpio_set_ddr(GPIO_TX_BANK, 0xffff, 0xffff);
- hal_gpio_set_ddr(GPIO_RX_BANK, 0xffff, 0xffff);
-#endif
-
-
// initialize double buffering state machine for ethernet -> DSP Tx
dbsm_init(&dsp_tx_sm, DSP_TX_BUF_0,
@@ -662,13 +524,6 @@ hal_gpio_set_sels(GPIO_RX_BANK, "aaaaaaaaaaaaaaaa");
// FIXME Figure out how to handle this robustly.
// Any buffers that are emptying should be allowed to drain...
- if (auto_reload_command){
- // restart_streaming();
- // FIXME report error
- }
- else {
- // FIXME report error
- }
putchar('O');
}
}
diff --git a/firmware/microblaze/lib/Makefile.am b/firmware/microblaze/lib/Makefile.am
index 783895850..b51d74463 100644
--- a/firmware/microblaze/lib/Makefile.am
+++ b/firmware/microblaze/lib/Makefile.am
@@ -44,7 +44,6 @@ libu2fw_a_SOURCES = \
pic.c \
print_mac_addr.c \
print_rmon_regs.c \
- print_fxpt.c \
print_buffer.c \
printf.c \
sd.c \
diff --git a/firmware/microblaze/lib/banal.c b/firmware/microblaze/lib/banal.c
index 23f5f3b8a..42937957f 100644
--- a/firmware/microblaze/lib/banal.c
+++ b/firmware/microblaze/lib/banal.c
@@ -29,21 +29,3 @@ get_uint64(const unsigned char *s)
{
return (((uint64_t)get_uint32(s)) << 32) | get_uint32(s+4);
}
-
-uint32_t
-divide_uint64(uint64_t dividend, uint32_t divisor)
-{
- uint32_t result = 0;
- uint64_t dividend_ = 0;
- for(int i = 31; i >= 0; i--){
- //approximate the divisor with the ith result bit set
- uint64_t tmp = dividend_;
- tmp += (uint64_t)divisor << i;
- //set the ith result bit if the approximation is less
- if (tmp <= dividend){
- dividend_ = tmp;
- result |= 1 << i;
- }
- }
- return result;
-}
diff --git a/firmware/microblaze/lib/banal.h b/firmware/microblaze/lib/banal.h
index 6d9420602..7b3c71a20 100644
--- a/firmware/microblaze/lib/banal.h
+++ b/firmware/microblaze/lib/banal.h
@@ -87,7 +87,4 @@ get_int64(const unsigned char *s)
void
print_ip(struct ip_addr ip);
-uint32_t
-divide_uint64(uint64_t dividend, uint32_t divisor);
-
#endif /* INCLUDED_BANAL_H */
diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c
index fdfa15000..0afd6a2cc 100644
--- a/firmware/microblaze/lib/hal_io.c
+++ b/firmware/microblaze/lib/hal_io.c
@@ -24,134 +24,6 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
-//#include <assert.h>
-
-/*
- * ========================================================================
- * GPIOS
- * ========================================================================
- */
-void
-hal_gpio_set_ddr(int bank, int value, int mask)
-{
- bank &= 0x1;
-
- if (bank == GPIO_TX_BANK){ // tx in top half
- value <<= 16;
- mask <<= 16;
- }
- else {
- value &= 0xffff;
- mask &= 0xffff;
- }
-
- int ei = hal_disable_ints();
- gpio_base->ddr = (gpio_base->ddr & ~mask) | (value & mask);
- hal_restore_ints(ei);
-}
-
-static bool
-code_to_int(char code, int *val)
-{
- switch(code){
- case 's': *val = GPIO_SEL_SW; return true;
- case 'a': *val = GPIO_SEL_ATR; return true;
- case '0': *val = GPIO_SEL_DEBUG_0; return true;
- case '1': *val = GPIO_SEL_DEBUG_1; return true;
- case '.':
- default:
- return false;
- }
-}
-
-void
-hal_gpio_set_sel(int bank, int bitno, char code)
-{
- bank &= 0x1;
- int t;
-
- if (!code_to_int(code, &t))
- return;
-
- int val = t << (2 * bitno);
- int mask = 0x3 << (2 * bitno);
-
- volatile uint32_t *sel = bank == GPIO_TX_BANK ? &gpio_base->tx_sel : &gpio_base->rx_sel;
- int ei = hal_disable_ints();
- int v = (*sel & ~mask) | (val & mask);
- *sel = v;
- hal_restore_ints(ei);
-
- if (0)
- printf("hal_gpio_set_sel(bank=%d, bitno=%d, code=%c) *sel = 0x%x\n",
- bank, bitno, code, v);
-}
-
-void
-hal_gpio_set_sels(int bank, char *codes)
-{
- //assert(strlen(codes) == 16);
-
- int val = 0;
- int mask = 0;
- int i;
-
- for (i = 15; i >= 0; i--){
- val <<= 2;
- mask <<= 2;
- int t;
- if (code_to_int(codes[i], &t)){
- val |= t;
- mask |= 0x3;
- }
- }
-
- volatile uint32_t *sel = bank == GPIO_TX_BANK ? &gpio_base->tx_sel : &gpio_base->rx_sel;
- int ei = hal_disable_ints();
- *sel = (*sel & ~mask) | (val & mask);
- hal_restore_ints(ei);
-}
-
-
-/*!
- * \brief write \p value to gpio pins specified by \p mask.
- */
-void
-hal_gpio_write(int bank, int value, int mask)
-{
- static uint32_t _gpio_io_shadow;
-
- bank &= 0x1;
-
- if (bank == GPIO_TX_BANK){ // tx in top half
- value <<= 16;
- mask <<= 16;
- }
- else {
- value &= 0xffff;
- mask &= 0xffff;
- }
-
- //int ei = hal_disable_ints();
- _gpio_io_shadow = (_gpio_io_shadow & ~mask) | (value & mask);
- gpio_base->io = _gpio_io_shadow;
- //hal_restore_ints(ei);
-}
-
-
-/*!
- * \brief read GPIO bits
- */
-int
-hal_gpio_read(int bank)
-{
- bank &= 0x1;
- int r = gpio_base->io;
- if (bank == GPIO_TX_BANK)
- r >>= 16;
-
- return r & 0xffff;
-}
/*
* ========================================================================
diff --git a/firmware/microblaze/lib/hal_io.h b/firmware/microblaze/lib/hal_io.h
index f8ec617f8..d8967f063 100644
--- a/firmware/microblaze/lib/hal_io.h
+++ b/firmware/microblaze/lib/hal_io.h
@@ -24,64 +24,6 @@
void hal_io_init(void);
void hal_finish();
-
-/*
- * ------------------------------------------------------------------------
- * The GPIO pins are organized into two banks of 16-bits.
- * Bank 0 goes to the Tx daughterboard, Bank 1 goes to the Rx daughterboard.
- *
- * Each pin may be configured as an input or an output from the FPGA.
- * For output pins, there are four signals which may be routed to the
- * pin. The four signals are the value written by s/w, the output of
- * the ATR controller, or two different sources of debug info from the
- * FPGA fabric.
- * ------------------------------------------------------------------------
- */
-
-#define GPIO_TX_BANK 0 // pins that connect to the Tx daughterboard
-#define GPIO_RX_BANK 1 // pins that connect to the Rx daughterboard
-
-
-/*!
- * \brief Set the data direction for GPIO pins
- *
- * If the bit is set, it's an output from the FPGA.
- * \param value is a 16-bit bitmask of values
- * \param mask is a 16-bit bitmask of which bits to effect.
- */
-void hal_gpio_set_ddr(int bank, int value, int mask);
-
-/*!
- * \brief Select the source of the signal for an output pin.
- *
- * \param code is is one of 's', 'a', '0', '1'
- * where 's' selects software output, 'a' selects ATR output, '0' selects
- * debug 0, '1' selects debug 1.
- */
-void hal_gpio_set_sel(int bank, int bitno, char code);
-
-/*!
- * \brief Select the source of the signal for the output pins.
- *
- * \param codes is is a string of 16 characters composed of '.', 's',
- * 'a', '0', or '1' where '.' means "don't change", 's' selects
- * software output, 'a' selects ATR output, '0' selects debug 0, '1'
- * selects debug 1.
- */
-void hal_gpio_set_sels(int bank, char *codes);
-
-
-/*!
- * \brief write \p value to gpio pins specified by \p mask.
- */
-void hal_gpio_write(int bank, int value, int mask);
-
-/*!
- * \brief read GPIO bits
- */
-int hal_gpio_read(int bank);
-
-
/*
* ------------------------------------------------------------------------
* control the leds
diff --git a/firmware/microblaze/lib/memory_map.h b/firmware/microblaze/lib/memory_map.h
index fed1e5259..cdf3dd338 100644
--- a/firmware/microblaze/lib/memory_map.h
+++ b/firmware/microblaze/lib/memory_map.h
@@ -525,10 +525,6 @@ 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))
-
#define sr_rx_ctrl ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL))
// --- dsp rx regs ---
diff --git a/firmware/microblaze/lib/print_fxpt.c b/firmware/microblaze/lib/print_fxpt.c
deleted file mode 100644
index 185bbc51b..000000000
--- a/firmware/microblaze/lib/print_fxpt.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * 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 <nonstdio.h>
-
-/*
- * print uint64_t
- */
-void
-print_uint64(uint64_t u)
-{
- const char *_hex = "0123456789ABCDEF";
- if (u >= 10)
- print_uint64(u/10);
- putchar(_hex[u%10]);
-}
-
-static void
-print_thousandths(int thousandths)
-{
- putchar('.');
- if (thousandths < 100)
- putchar('0');
- if (thousandths < 10)
- putchar('0');
- printf("%d", thousandths);
-}
-
-
-void
-print_fxpt_freq(u2_fxpt_freq_t v)
-{
- if (v < 0){
- v = -v;
- putchar('-');
- }
-
- int64_t int_part = v >> 20;
- int32_t frac_part = v & ((1 << 20) - 1);
-
-#if 0
- // would work, if we had it
- printf("%lld.%03d", int_part, (frac_part * 1000) >> 20);
-#else
- print_uint64(int_part);
- print_thousandths((frac_part * 1000) >> 20);
-#endif
-}
-
-void
-print_fxpt_gain(u2_fxpt_gain_t v)
-{
- if (v < 0){
- v = -v;
- putchar('-');
- }
-
- int32_t int_part = v >> 7;
- int32_t frac_part = v & ((1 << 7) - 1);
-
-#if 0
- // would work, if we had it
- printf("%d.%03d", int_part, (frac_part * 1000) >> 7);
-#else
- printf("%d", int_part);
- print_thousandths((frac_part * 1000) >> 7);
-#endif
-}
-
diff --git a/firmware/microblaze/lib/print_mac_addr.c b/firmware/microblaze/lib/print_mac_addr.c
index 838fd614a..475082325 100644
--- a/firmware/microblaze/lib/print_mac_addr.c
+++ b/firmware/microblaze/lib/print_mac_addr.c
@@ -20,11 +20,9 @@
void
print_mac_addr(const unsigned char addr[6])
{
- puthex8(addr[0]); putchar(':');
- puthex8(addr[1]); putchar(':');
- puthex8(addr[2]); putchar(':');
- puthex8(addr[3]); putchar(':');
- puthex8(addr[4]); putchar(':');
- puthex8(addr[5]);
+ for(size_t i = 0; i < 6; i++){
+ if(i) putchar(':');
+ puthex8(addr[i]);
+ }
}
diff --git a/firmware/microblaze/lib/u2_init.c b/firmware/microblaze/lib/u2_init.c
index 399d834cb..6809101c0 100644
--- a/firmware/microblaze/lib/u2_init.c
+++ b/firmware/microblaze/lib/u2_init.c
@@ -46,15 +46,6 @@ get_hw_rev(void)
bool
u2_init(void)
{
- // Set GPIOs to inputs, disable GPIO streaming
- hal_gpio_set_ddr(GPIO_TX_BANK, 0x0000, 0xffff);
- hal_gpio_set_ddr(GPIO_RX_BANK, 0x0000, 0xffff);
-
- hal_gpio_write(GPIO_TX_BANK, 0x0000, 0xffff); // init s/w output value to zero
- hal_gpio_write(GPIO_RX_BANK, 0x0000, 0xffff);
-
- dsp_rx_regs->gpio_stream_enable = 0; // I, Q LSBs come from DSP
-
hal_io_init();
// init spi, so that we can switch over to the high-speed clock
@@ -67,18 +58,6 @@ u2_init(void)
// set up the default clocks
clocks_init();
- // clocks_enable_test_clk(true,1);
-
- // Enable ADCs
- output_regs->adc_ctrl = ADC_CTRL_ON;
-
- // Initial values for tx and rx mux registers
- dsp_tx_regs->tx_mux = 0x10;
- dsp_rx_regs->rx_mux = 0x44444444;
-
- // Set up serdes
- output_regs->serdes_ctrl = (SERDES_ENABLE | SERDES_RXEN);
-
pic_init(); // progammable interrupt controller
bp_init(); // buffer pool
diff --git a/fpga/usrp2/vrt/vita_rx_control.v b/fpga/usrp2/vrt/vita_rx_control.v
index 669b8299d..742dd47e0 100644
--- a/fpga/usrp2/vrt/vita_rx_control.v
+++ b/fpga/usrp2/vrt/vita_rx_control.v
@@ -31,13 +31,13 @@ module vita_rx_control
wire [63:0] rcvtime_pre;
reg [63:0] rcvtime;
- wire [29:0] numlines_pre;
- wire send_imm_pre, chain_pre;
- reg send_imm, chain;
+ wire [28:0] numlines_pre;
+ wire send_imm_pre, chain_pre, reload_pre;
+ reg send_imm, chain, reload;
wire full_ctrl, read_ctrl, empty_ctrl, write_ctrl;
reg sc_pre2;
wire [33:0] fifo_line;
- reg [29:0] lines_left;
+ reg [28:0] lines_left, lines_total;
reg [2:0] ibs_state;
wire now, early, late;
wire sample_fifo_in_rdy;
@@ -67,7 +67,7 @@ module vita_rx_control
shortfifo #(.WIDTH(96)) commandfifo
(.clk(clk),.rst(reset),.clear(clear_int),
.datain({new_command,new_time}), .write(write_ctrl&~full_ctrl), .full(full_ctrl),
- .dataout({send_imm_pre,chain_pre,numlines_pre,rcvtime_pre}),
+ .dataout({send_imm_pre,chain_pre,reload_pre,numlines_pre,rcvtime_pre}),
.read(read_ctrl), .empty(empty_ctrl),
.occupied(command_queue_len), .space() );
@@ -98,7 +98,7 @@ module vita_rx_control
.src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i),
.space(), .occupied() );
- // Inband Signalling State Machine
+ // Inband Signallling State Machine
time_compare
time_compare (.time_now(vita_time), .trigger_time(rcvtime), .now(now), .early(early), .late(late));
@@ -111,9 +111,11 @@ module vita_rx_control
begin
ibs_state <= IBS_IDLE;
lines_left <= 0;
+ lines_total <= 0;
rcvtime <= 0;
send_imm <= 0;
chain <= 0;
+ reload <= 0;
end
else
case(ibs_state)
@@ -121,10 +123,12 @@ module vita_rx_control
if(~empty_ctrl)
begin
lines_left <= numlines_pre;
+ lines_total <= numlines_pre;
rcvtime <= rcvtime_pre;
ibs_state <= IBS_WAITING;
send_imm <= send_imm_pre;
chain <= chain_pre;
+ reload <= reload_pre;
end
IBS_WAITING :
if(go_now)
@@ -141,14 +145,21 @@ module vita_rx_control
if(lines_left == 1)
if(~chain)
ibs_state <= IBS_IDLE;
+ else if(empty_ctrl & reload)
+ begin
+ ibs_state <= IBS_RUNNING;
+ lines_left <= lines_total;
+ end
else if(empty_ctrl)
ibs_state <= IBS_BROKENCHAIN;
else
begin
lines_left <= numlines_pre;
+ lines_total <= numlines_pre;
rcvtime <= rcvtime_pre;
send_imm <= send_imm_pre;
chain <= chain_pre;
+ reload <= reload_pre;
if(numlines_pre == 0) // If we are told to stop here
ibs_state <= IBS_IDLE;
else
@@ -178,3 +189,4 @@ module vita_rx_control
{ 2'b0, overrun, chain_pre, sample_fifo_in_rdy, attempt_sample_write, sample_fifo_src_rdy_o,sample_fifo_dst_rdy_i} };
endmodule // rx_control
+
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index fc4c5479e..195a9bc53 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -94,9 +94,6 @@ void usrp2_impl::init_ddc_config(void){
_ddc_decim = default_decim;
_ddc_freq = 0;
update_ddc_config();
-
- //initial command that kills streaming (in case if was left on)
- issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
}
void usrp2_impl::update_ddc_config(void){
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index e80001ff2..f28013cf6 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -34,7 +34,7 @@ extern "C" {
//defines the protocol version in this shared header
//increment this value when the protocol is changed
-#define USRP2_PROTO_VERSION 2
+#define USRP2_PROTO_VERSION 3
//used to differentiate control packets over data port
#define USRP2_INVALID_VRT_HEADER 0
@@ -70,9 +70,6 @@ typedef enum{
USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO = 'h',
USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE = 'H',
- USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO = '{',
- USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE = '}',
-
USRP2_CTRL_ID_POKE_THIS_REGISTER_FOR_ME_BRO = 'p',
USRP2_CTRL_ID_OMG_POKED_REGISTER_SO_BAD_DUDE = 'P',
@@ -114,15 +111,6 @@ typedef struct{
_SINS_ uint8_t data[sizeof(_SINS_ uint32_t)];
} i2c_args;
struct {
- _SINS_ uint8_t now; //stream now?
- _SINS_ uint8_t continuous; //auto-reload commmands?
- _SINS_ uint8_t chain;
- _SINS_ uint8_t _pad[1];
- _SINS_ uint32_t secs;
- _SINS_ uint32_t ticks;
- _SINS_ uint32_t num_samps;
- } stream_cmd;
- struct {
_SINS_ uint32_t addr;
_SINS_ uint32_t data;
_SINS_ uint8_t num_bytes; //1, 2, 4
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 2634e84aa..7c9d003ce 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -16,6 +16,7 @@
//
#include "usrp2_impl.hpp"
+#include "usrp2_regs.hpp"
#include <uhd/transport/convert_types.hpp>
#include <boost/format.hpp>
#include <boost/asio.hpp> //htonl and ntohl
@@ -42,14 +43,23 @@ void usrp2_impl::io_init(void){
_rx_stream_id_to_packet_seq[0] = 0;
//send a small data packet so the usrp2 knows the udp source port
- //and the maximum number of lines (32 bit words) per packet
managed_send_buffer::sptr send_buff = _data_transport->get_send_buff();
- boost::uint32_t data[2] = {
- htonl(USRP2_INVALID_VRT_HEADER),
- htonl(_max_rx_samples_per_packet)
- };
- memcpy(send_buff->cast<void*>(), data, sizeof(data));
+ boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER);
+ memcpy(send_buff->cast<void*>(), &data, sizeof(data));
send_buff->done(sizeof(data));
+
+ //setup RX DSP regs
+ _iface->poke32(FR_RX_CTRL_NSAMPS_PER_PKT, _max_rx_samples_per_packet);
+ _iface->poke32(FR_RX_CTRL_NCHANNELS, 1);
+ _iface->poke32(FR_RX_CTRL_CLEAR_OVERRUN, 1); //reset
+ _iface->poke32(FR_RX_CTRL_VRT_HEADER, 0
+ | (0x1 << 28) //if data with stream id
+ | (0x1 << 26) //has trailer
+ | (0x3 << 22) //integer time other
+ | (0x1 << 20) //fractional time sample count
+ );
+ _iface->poke32(FR_RX_CTRL_VRT_STREAM_ID, 0);
+ _iface->poke32(FR_RX_CTRL_VRT_TRAILER, 0);
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 36bef4f25..2c8fd2df4 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -63,6 +63,13 @@ void usrp2_impl::mboard_init(void){
boost::uint16_t data = ad9777_regs.get_write_reg(addr);
_iface->transact_spi(SPI_SS_AD9777, spi_config_t::EDGE_RISE, data, 16, false /*no rb*/);
}
+
+ //enable ADCs
+ _iface->poke32(FR_MISC_CTRL_ADC, FRF_MISC_CTRL_ADC_ON);
+
+ //set up serdes
+ _iface->poke32(FR_MISC_CTRL_SERDES, FRF_MISC_CTRL_SERDES_ENABLE | FRF_MISC_CTRL_SERDES_RXEN);
+
}
void usrp2_impl::init_clock_config(void){
@@ -97,9 +104,9 @@ void usrp2_impl::update_clock_config(void){
//clock source ref 10mhz
switch(_clock_config.ref_source){
- case clock_config_t::REF_INT : _iface->poke32(FR_CLOCK_CONTROL, 0x10); break;
- case clock_config_t::REF_SMA : _iface->poke32(FR_CLOCK_CONTROL, 0x1C); break;
- case clock_config_t::REF_MIMO: _iface->poke32(FR_CLOCK_CONTROL, 0x15); break;
+ case clock_config_t::REF_INT : _iface->poke32(FR_MISC_CTRL_CLOCK, 0x10); break;
+ case clock_config_t::REF_SMA : _iface->poke32(FR_MISC_CTRL_CLOCK, 0x1C); break;
+ case clock_config_t::REF_MIMO: _iface->poke32(FR_MISC_CTRL_CLOCK, 0x15); break;
default: throw std::runtime_error("usrp2: unhandled clock configuration reference source");
}
@@ -119,40 +126,31 @@ void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){
}
void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
- //setup the out data
- usrp2_ctrl_data_t out_data;
- out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO);
- out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0;
- out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs);
- out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.get_ticks(get_master_clock_freq()));
-
- //set these to defaults, then change in the switch statement
- out_data.data.stream_cmd.continuous = 0;
- out_data.data.stream_cmd.chain = 0;
- out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps);
-
- //setup chain, num samps, and continuous below
- switch(stream_cmd.stream_mode){
- case stream_cmd_t::STREAM_MODE_START_CONTINUOUS:
- out_data.data.stream_cmd.continuous = 1;
- break;
-
- case stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS:
- out_data.data.stream_cmd.num_samps = htonl(0);
- break;
-
- case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE:
- //all set by defaults above
- break;
-
- case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE:
- out_data.data.stream_cmd.chain = 1;
- break;
- }
-
- //send and recv
- usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data);
- UHD_ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE);
+ UHD_ASSERT_THROW(stream_cmd.num_samps <= FR_RX_CTRL_MAX_SAMPS_PER_CMD);
+
+ //setup the mode to instruction flags
+ typedef boost::tuple<bool, bool, bool> inst_t;
+ static const uhd::dict<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst = boost::assign::map_list_of
+ //reload, chain, samps
+ (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, inst_t(true, true, false))
+ (stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, inst_t(false, false, false))
+ (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true))
+ (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true, true))
+ ;
+
+ //setup the instruction flag values
+ bool inst_reload, inst_chain, inst_samps;
+ boost::tie(inst_reload, inst_chain, inst_samps) = mode_to_inst[stream_cmd.stream_mode];
+
+ //issue the stream command
+ _iface->poke32(FR_RX_CTRL_STREAM_CMD, FR_RX_CTRL_MAKE_CMD(
+ (inst_samps)? stream_cmd.num_samps : ((inst_chain)? _max_rx_samples_per_packet : 1),
+ (stream_cmd.stream_now)? 1 : 0,
+ (inst_chain)? 1 : 0,
+ (inst_reload)? 1 : 0
+ ));
+ _iface->poke32(FR_RX_CTRL_TIME_SECS, stream_cmd.time_spec.secs);
+ _iface->poke32(FR_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_ticks(get_master_clock_freq()));
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp
index 0e2a18756..feeccaa34 100644
--- a/host/lib/usrp/usrp2/usrp2_regs.hpp
+++ b/host/lib/usrp/usrp2/usrp2_regs.hpp
@@ -64,7 +64,23 @@
/////////////////////////////////////////////////
// Misc Control
////////////////////////////////////////////////
-#define FR_CLOCK_CONTROL _SR_ADDR(0)
+#define FR_MISC_CTRL_CLOCK _SR_ADDR(0)
+#define FR_MISC_CTRL_SERDES _SR_ADDR(1)
+#define FR_MISC_CTRL_ADC _SR_ADDR(2)
+#define FR_MISC_CTRL_LEDS _SR_ADDR(3)
+#define FR_MISC_CTRL_PHY _SR_ADDR(4) // LSB is reset line to eth phy
+#define FR_MISC_CTRL_DBG_MUX _SR_ADDR(5)
+#define FR_MISC_CTRL_RAM_PAGE _SR_ADDR(6) // FIXME should go somewhere else...
+#define FR_MISC_CTRL_FLUSH_ICACHE _SR_ADDR(7) // Flush the icache
+#define FR_MISC_CTRL_LED_SRC _SR_ADDR(8) // HW or SW control for LEDs
+
+#define FRF_MISC_CTRL_SERDES_ENABLE 8
+#define FRF_MISC_CTRL_SERDES_PRBSEN 4
+#define FRF_MISC_CTRL_SERDES_LOOPEN 2
+#define FRF_MISC_CTRL_SERDES_RXEN 1
+
+#define FRF_MISC_CTRL_ADC_ON 0x0F
+#define FRF_MISC_CTRL_ADC_OFF 0x00
/////////////////////////////////////////////////
// VITA49 64 bit time (write only)
@@ -207,4 +223,25 @@
#define FR_ATR_FULL_TXSIDE FR_ATR_BASE + 12
#define FR_ATR_FULL_RXSIDE FR_ATR_BASE + 14
+///////////////////////////////////////////////////
+// VITA RX CTRL regs
+///////////////////////////////////////////////////
+// The following 3 are logically a single command register.
+// They are clocked into the underlying fifo when time_ticks is written.
+#define FR_RX_CTRL_STREAM_CMD _SR_ADDR(SR_RX_CTRL + 0) // {now, chain, num_samples(30)
+#define FR_RX_CTRL_TIME_SECS _SR_ADDR(SR_RX_CTRL + 1)
+#define FR_RX_CTRL_TIME_TICKS _SR_ADDR(SR_RX_CTRL + 2)
+
+#define FR_RX_CTRL_CLEAR_OVERRUN _SR_ADDR(SR_RX_CTRL + 3) // write anything to clear overrun
+#define FR_RX_CTRL_VRT_HEADER _SR_ADDR(SR_RX_CTRL + 4) // word 0 of packet. FPGA fills in packet counter
+#define FR_RX_CTRL_VRT_STREAM_ID _SR_ADDR(SR_RX_CTRL + 5) // word 1 of packet.
+#define FR_RX_CTRL_VRT_TRAILER _SR_ADDR(SR_RX_CTRL + 6)
+#define FR_RX_CTRL_NSAMPS_PER_PKT _SR_ADDR(SR_RX_CTRL + 7)
+#define FR_RX_CTRL_NCHANNELS _SR_ADDR(SR_RX_CTRL + 8) // 1 in basic case, up to 4 for vector sources
+
+//helpful macros for dealing with stream cmd
+#define FR_RX_CTRL_MAX_SAMPS_PER_CMD 0x1fffffff
+#define FR_RX_CTRL_MAKE_CMD(nsamples, now, chain, reload) \
+ ((((now) & 0x1) << 31) | (((chain) & 0x1) << 30) | (((reload) & 0x1) << 29) | ((nsamples) & 0x1fffffff))
+
#endif /* INCLUDED_USRP2_REGS_HPP */