aboutsummaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/fx2/b100/usb_descriptors.a5148
-rw-r--r--firmware/fx2/b100/usrp_common.c12
-rw-r--r--firmware/fx2/b100/usrp_main.c2
-rw-r--r--firmware/zpu/apps/txrx_uhd.c44
-rw-r--r--firmware/zpu/lib/ad9510.c6
-rw-r--r--firmware/zpu/lib/clocks.c5
-rw-r--r--firmware/zpu/lib/eth_addrs.c132
-rw-r--r--firmware/zpu/lib/ethernet.h21
-rw-r--r--firmware/zpu/lib/memory_map.h37
-rw-r--r--firmware/zpu/lib/net_common.c28
-rw-r--r--firmware/zpu/lib/net_common.h5
-rw-r--r--firmware/zpu/lib/spi.c97
-rw-r--r--firmware/zpu/lib/spi.h42
-rw-r--r--firmware/zpu/lib/u2_init.c2
-rw-r--r--firmware/zpu/usrp2p/spi_flash.c4
-rw-r--r--firmware/zpu/usrp2p/spi_flash.h10
-rw-r--r--firmware/zpu/usrp2p/spif.c1
-rw-r--r--firmware/zpu/usrp2p/u2p_init.c3
-rw-r--r--firmware/zpu/usrp2p/udp_fw_update.c4
19 files changed, 235 insertions, 268 deletions
diff --git a/firmware/fx2/b100/usb_descriptors.a51 b/firmware/fx2/b100/usb_descriptors.a51
index 6efeb8367..847face16 100644
--- a/firmware/fx2/b100/usb_descriptors.a51
+++ b/firmware/fx2/b100/usb_descriptors.a51
@@ -211,8 +211,8 @@ _high_speed_config_descr::
.db DSCR_ENDPNT
.db 0x04 ; bEndpointAddress (ep 4 OUT)
.db ET_BULK ; bmAttributes
- .db <32 ; wMaxPacketSize (LSB)
- .db >32 ; wMaxPacketSize (MSB)
+ .db <512 ; wMaxPacketSize (LSB)
+ .db >512 ; wMaxPacketSize (MSB)
.db 0 ; bInterval (iso only)
;; interface descriptor 4 (FPGA command IN path, ep8 IN BULK)
@@ -233,8 +233,8 @@ _high_speed_config_descr::
.db DSCR_ENDPNT
.db 0x88 ; bEndpointAddress (ep 8 IN)
.db ET_BULK ; bmAttributes
- .db <32 ; wMaxPacketSize (LSB)
- .db >32 ; wMaxPacketSize (MSB)
+ .db <512 ; wMaxPacketSize (LSB)
+ .db >512 ; wMaxPacketSize (MSB)
.db 0 ; bInterval (iso only)
@@ -341,25 +341,24 @@ str0_end:
.even
str1: .db str1_end - str1
.db DSCR_STRING
- .db 'F, 0 ; 16-bit unicode
- .db 'r, 0
+ .db 'E, 0 ; 16-bit unicode
+ .db 't, 0
+ .db 't, 0
+ .db 'u, 0
+ .db 's, 0
+ .db ' , 0
+ .db 'R, 0
.db 'e, 0
+ .db 's, 0
.db 'e, 0
- .db ' , 0
- .db 'S, 0
- .db 'o, 0
- .db 'f, 0
- .db 't, 0
- .db 'w, 0
.db 'a, 0
.db 'r, 0
- .db 'e, 0
+ .db 'c, 0
+ .db 'h, 0
.db ' , 0
- .db 'F, 0
- .db 'o, 0
- .db 'l, 0
- .db 'k, 0
- .db 's, 0
+ .db 'L, 0
+ .db 'L, 0
+ .db 'C, 0
str1_end:
SI_PRODUCT = 2
@@ -370,13 +369,12 @@ str2: .db str2_end - str2
.db 'S, 0
.db 'R, 0
.db 'P, 0
- .db '1, 0
- .db 'P, 0
- .db ' , 0
- .db 'R, 0
- .db 'e, 0
- .db 'v, 0
- .db ' , 0
+ .db ' , 0
+ .db 'B, 0
+ .db '1, 0
+ .db '0, 0
+ .db '0, 0
+
_usb_desc_hw_rev_ascii_patch_location_0::
.db '?, 0
str2_end:
diff --git a/firmware/fx2/b100/usrp_common.c b/firmware/fx2/b100/usrp_common.c
index a21353688..968b03d48 100644
--- a/firmware/fx2/b100/usrp_common.c
+++ b/firmware/fx2/b100/usrp_common.c
@@ -85,8 +85,8 @@ init_usrp (void)
// set autoin length for EP6/EP8
EP6AUTOINLENH = (512) >> 8; SYNCDELAY; // this is the length for high speed
EP6AUTOINLENL = (512) & 0xff; SYNCDELAY;
- EP8AUTOINLENH = (32) >> 8; SYNCDELAY;
- EP8AUTOINLENL = (32) & 0xff; SYNCDELAY;
+ EP8AUTOINLENH = (512) >> 8; SYNCDELAY;
+ EP8AUTOINLENL = (512) & 0xff; SYNCDELAY;
//set FLAGA, FLAGB, FLAGC, FLAGD to be EP2EF, EP4EF, EP6PF, EP8PF
PINFLAGSAB = (bmEP2EF) | (bmEP4EF << 4);
@@ -99,13 +99,19 @@ init_usrp (void)
EP6FIFOPFL = 0xFD;
SYNCDELAY;
+ EP8FIFOPFH = 0x09;
+ SYNCDELAY;
+ EP8FIFOPFL = 0xFD;
+ SYNCDELAY;
+
// EP2FIFOPFH = 0x08;
// SYNCDELAY;
// EP2FIFOPFL = 0x00;
// SYNCDELAY;
//assert FIFOEMPTY one cycle sooner so we get it in time at the FPGA
- EP2FIFOCFG |= bmBIT5;
+ EP2FIFOCFG |= bmBIT5;
+ EP4FIFOCFG |= bmBIT5;
//set FIFOPINPOLAR to normal (active low) mode
FIFOPINPOLAR = 0x00;
diff --git a/firmware/fx2/b100/usrp_main.c b/firmware/fx2/b100/usrp_main.c
index 74427b7d2..f79d3d111 100644
--- a/firmware/fx2/b100/usrp_main.c
+++ b/firmware/fx2/b100/usrp_main.c
@@ -124,7 +124,7 @@ app_vendor_cmd (void)
case VRQ_FW_COMPAT:
EP0BCH = 0;
- EP0BCL = 3;
+ EP0BCL = 4;
break;
default:
diff --git a/firmware/zpu/apps/txrx_uhd.c b/firmware/zpu/apps/txrx_uhd.c
index 9daf441e2..30efc9518 100644
--- a/firmware/zpu/apps/txrx_uhd.c
+++ b/firmware/zpu/apps/txrx_uhd.c
@@ -89,11 +89,42 @@ static void handle_udp_data_packet(
which = 1;
break;
+ case USRP2_UDP_FIFO_CRTL_PORT:
+ which = 3;
+ break;
+
default: return;
}
- eth_mac_addr_t eth_mac_host; arp_cache_lookup_mac(&src.addr, &eth_mac_host);
- setup_framer(eth_mac_host, *ethernet_mac_addr(), src, dst, which);
+ //assume the packet destination is the packet source
+ //the arp cache lookup should never fail for this case
+ const struct socket_address src_addr = dst;
+ struct socket_address dst_addr = src;
+ eth_mac_addr_t eth_mac_dst;
+ arp_cache_lookup_mac(&dst_addr.addr, &eth_mac_dst);
+
+ //however, if this control packet has an alternative destination...
+ if (payload_len >= sizeof(usrp2_stream_ctrl_t)){
+
+ //parse the destination ip addr and udp port from the payload
+ const usrp2_stream_ctrl_t *stream_ctrl = (const usrp2_stream_ctrl_t *)payload;
+ dst_addr.addr.addr = stream_ctrl->ip_addr;
+ dst_addr.port = (uint16_t)stream_ctrl->udp_port;
+ struct ip_addr ip_dest = dst_addr.addr;
+
+ //are we in the subnet? if not use the gateway
+ const uint32_t subnet_mask = get_subnet()->addr;
+ const bool in_subnet = ((get_ip_addr()->addr & subnet_mask) == (ip_dest.addr & subnet_mask));
+ if (!in_subnet) ip_dest = *get_gateway();
+
+ //lookup the host ip address with ARP (this may fail)
+ const bool ok = arp_cache_lookup_mac(&ip_dest, &eth_mac_dst);
+ if (!ok) net_common_send_arp_request(&ip_dest);
+ const uint32_t result = (ok)? 0 : ~0;
+ send_udp_pkt(dst.port, src, &result, sizeof(result));
+ }
+
+ setup_framer(eth_mac_dst, *ethernet_mac_addr(), dst_addr, src_addr, which);
}
#define OTW_GPIO_BANK_TO_NUM(bank) \
@@ -150,8 +181,8 @@ static void handle_udp_ctrl_packet(
ctrl_data_in->data.spi_args.dev, //which device
ctrl_data_in->data.spi_args.data, //32 bit data
ctrl_data_in->data.spi_args.num_bits, //length in bits
- (ctrl_data_in->data.spi_args.mosi_edge == USRP2_CLK_EDGE_RISE)? SPIF_PUSH_FALL : SPIF_PUSH_RISE |
- (ctrl_data_in->data.spi_args.miso_edge == USRP2_CLK_EDGE_RISE)? SPIF_LATCH_RISE : SPIF_LATCH_FALL
+ ((ctrl_data_in->data.spi_args.mosi_edge == USRP2_CLK_EDGE_RISE)? SPI_PUSH_FALL : SPI_PUSH_RISE) |
+ ((ctrl_data_in->data.spi_args.miso_edge == USRP2_CLK_EDGE_RISE)? SPI_LATCH_RISE : SPI_LATCH_FALL)
);
//load output
@@ -279,6 +310,7 @@ int
main(void)
{
u2_init();
+ arp_cache_init();
#ifdef BOOTLOADER
putstr("\nUSRP N210 UDP bootloader\n");
#else
@@ -294,8 +326,7 @@ main(void)
//load the production FPGA image or firmware if appropriate
do_the_bootload_thing();
//if we get here we've fallen through to safe firmware
- set_default_mac_addr();
- set_default_ip_addr();
+ eth_addrs_set_default();
#endif
print_mac_addr(ethernet_mac_addr()); newline();
@@ -311,6 +342,7 @@ main(void)
register_udp_listener(USRP2_UDP_RX_DSP0_PORT, handle_udp_data_packet);
register_udp_listener(USRP2_UDP_RX_DSP1_PORT, handle_udp_data_packet);
register_udp_listener(USRP2_UDP_TX_DSP0_PORT, handle_udp_data_packet);
+ register_udp_listener(USRP2_UDP_FIFO_CRTL_PORT, handle_udp_data_packet);
#ifdef USRP2P
register_udp_listener(USRP2_UDP_UPDATE_PORT, handle_udp_fw_update_packet);
diff --git a/firmware/zpu/lib/ad9510.c b/firmware/zpu/lib/ad9510.c
index 4d3acb65d..4021a9bf7 100644
--- a/firmware/zpu/lib/ad9510.c
+++ b/firmware/zpu/lib/ad9510.c
@@ -1,5 +1,5 @@
-/* -*- c++ -*- */
/*
+ * Copyright 2012 Ettus Research LLC
* Copyright 2008 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -28,7 +28,7 @@ ad9510_write_reg(int regno, uint8_t value)
{
uint32_t inst = WR | (regno & 0xff);
uint32_t v = (inst << 8) | (value & 0xff);
- spi_transact(SPI_TXONLY, SPI_SS_AD9510, v, 24, SPIF_PUSH_FALL);
+ spi_transact(SPI_TXONLY, SPI_SS_AD9510, v, 24, SPI_PUSH_FALL);
}
int
@@ -37,6 +37,6 @@ ad9510_read_reg(int regno)
uint32_t inst = RD | (regno & 0xff);
uint32_t v = (inst << 8) | 0;
uint32_t r = spi_transact(SPI_TXRX, SPI_SS_AD9510, v, 24,
- SPIF_PUSH_FALL | SPIF_LATCH_FALL);
+ SPI_PUSH_FALL | SPI_LATCH_FALL);
return r & 0xff;
}
diff --git a/firmware/zpu/lib/clocks.c b/firmware/zpu/lib/clocks.c
index c1e8ce827..bc1954e13 100644
--- a/firmware/zpu/lib/clocks.c
+++ b/firmware/zpu/lib/clocks.c
@@ -43,7 +43,10 @@ clocks_init(void)
//enable the 100MHz clock output to the FPGA for 50MHz CPU clock
clocks_enable_fpga_clk(true, 1);
- spi_wait();
+ //! Cannot SPI wait since SPI is on DSP clock
+ //! because DSP clock goes away until DCM reset.
+ //! However, spi is quick, the cpu is slow, its already ready...
+ //spi_wait();
//wait for the clock to stabilize
while(!clocks_lock_detect());
diff --git a/firmware/zpu/lib/eth_addrs.c b/firmware/zpu/lib/eth_addrs.c
index c45ce7559..6d3347cf3 100644
--- a/firmware/zpu/lib/eth_addrs.c
+++ b/firmware/zpu/lib/eth_addrs.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2011 Ettus Research LLC
+ * Copyright 2010-2012 Ettus Research LLC
* Copyright 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@
#include "memory_map.h"
#include "nonstdio.h"
#include <stdbool.h>
+#include <string.h>
#include "i2c.h"
#include "usrp2/fw_common.h"
@@ -37,104 +38,69 @@ unprogrammed(const void *t, size_t len)
return all_ones | all_zeros;
}
-//////////////////// MAC Addr Stuff ///////////////////////
+typedef struct{
+ eth_mac_addr_t mac_addr;
+ struct ip_addr ip_addr;
+ struct ip_addr gateway;
+ struct ip_addr subnet;
+} eth_addrs_t;
-static bool src_mac_addr_initialized = false;
+static bool eth_addrs_initialized = false;
-static const eth_mac_addr_t default_mac_addr = {{
- 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff
- }};
+static const eth_addrs_t default_eth_addrs = {
+ .mac_addr = {{0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff}},
+ .ip_addr = {(192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)},
+ .gateway = {(192 << 24 | 168 << 16 | 10 << 8 | 1 << 0)},
+ .subnet = {(255 << 24 | 255 << 16 | 255 << 8 | 0 << 0)},
+};
-static eth_mac_addr_t src_mac_addr = {{
- 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff
- }};
-
-void set_default_mac_addr(void)
-{
- src_mac_addr_initialized = true;
- src_mac_addr = default_mac_addr;
-}
+static eth_addrs_t current_eth_addrs;
-const eth_mac_addr_t *
-ethernet_mac_addr(void)
-{
- if (!src_mac_addr_initialized){ // fetch from eeprom
- src_mac_addr_initialized = true;
+static void eth_addrs_init(void){
+ if (eth_addrs_initialized) return;
+ eth_addrs_initialized = true;
- // if we're simulating, don't read the EEPROM model, it's REALLY slow
- if (hwconfig_simulation_p())
- return &src_mac_addr;
-
- eth_mac_addr_t tmp;
- bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, &tmp, sizeof(tmp));
- if (!ok || unprogrammed(&tmp, sizeof(tmp))){
- // use the default
+ #define eth_addrs_init_x(addr, x){ \
+ const bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, addr, &current_eth_addrs.x, sizeof(current_eth_addrs.x)); \
+ if (!ok || unprogrammed(&current_eth_addrs.x, sizeof(current_eth_addrs.x))){ \
+ memcpy(&current_eth_addrs.x, &default_eth_addrs.x, sizeof(current_eth_addrs.x)); \
+ } \
}
- else
- src_mac_addr = tmp;
- }
- return &src_mac_addr;
-}
+ eth_addrs_init_x(USRP2_EE_MBOARD_MAC_ADDR, mac_addr);
+ eth_addrs_init_x(USRP2_EE_MBOARD_IP_ADDR, ip_addr);
+ eth_addrs_init_x(USRP2_EE_MBOARD_GATEWAY, gateway);
+ eth_addrs_init_x(USRP2_EE_MBOARD_SUBNET, subnet);
-bool
-ethernet_set_mac_addr(const eth_mac_addr_t *t)
-{
- bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, t, sizeof(eth_mac_addr_t));
- if (ok){
- src_mac_addr = *t;
- src_mac_addr_initialized = true;
- //eth_mac_set_addr(t); //this breaks the link
- }
-
- return ok;
}
-//////////////////// IP Addr Stuff ///////////////////////
-
-static bool src_ip_addr_initialized = false;
-
-static const struct ip_addr default_ip_addr = {
- (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)
-};
-
-static struct ip_addr src_ip_addr = {
- (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)
-};
-
-void set_default_ip_addr(void)
-{
- src_ip_addr_initialized = true;
- src_ip_addr = default_ip_addr;
+const eth_mac_addr_t *ethernet_mac_addr(void){
+ eth_addrs_init();
+ return &current_eth_addrs.mac_addr;
}
-const struct ip_addr *get_ip_addr(void)
-{
- if (!src_ip_addr_initialized){ // fetch from eeprom
- src_ip_addr_initialized = true;
-
- // if we're simulating, don't read the EEPROM model, it's REALLY slow
- if (hwconfig_simulation_p())
- return &src_ip_addr;
+const struct ip_addr *get_ip_addr(void){
+ eth_addrs_init();
+ return &current_eth_addrs.ip_addr;
+}
- struct ip_addr tmp;
- bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, &tmp, sizeof(tmp));
- if (!ok || unprogrammed(&tmp, sizeof(tmp))){
- // use the default
- }
- else
- src_ip_addr = tmp;
- }
+const struct ip_addr *get_subnet(void){
+ eth_addrs_init();
+ return &current_eth_addrs.subnet;
+}
- return &src_ip_addr;
+const struct ip_addr *get_gateway(void){
+ eth_addrs_init();
+ return &current_eth_addrs.gateway;
}
bool set_ip_addr(const struct ip_addr *t){
- bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, t, sizeof(struct ip_addr));
- if (ok){
- src_ip_addr = *t;
- src_ip_addr_initialized = true;
- }
+ const bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, t, sizeof(struct ip_addr));
+ if (ok) current_eth_addrs.ip_addr = *t;
+ return ok;
+}
- return ok;
+void eth_addrs_set_default(void){
+ eth_addrs_initialized = true;
+ memcpy(&current_eth_addrs, &default_eth_addrs, sizeof(default_eth_addrs));
}
diff --git a/firmware/zpu/lib/ethernet.h b/firmware/zpu/lib/ethernet.h
index 52b297349..b5b08cb8c 100644
--- a/firmware/zpu/lib/ethernet.h
+++ b/firmware/zpu/lib/ethernet.h
@@ -1,5 +1,5 @@
-/* -*- c -*- */
/*
+ * Copyright 2010-2012 Ettus Research LLC
* Copyright 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -44,27 +44,28 @@ void ethernet_register_link_changed_callback(ethernet_link_changed_callback_t cb
*/
const eth_mac_addr_t *ethernet_mac_addr(void);
-/*!set mac addr to default*/
-void set_default_mac_addr(void);
-
/*!
- * \brief write mac address to eeprom and begin using it
+ * \returns IP address
*/
-bool ethernet_set_mac_addr(const eth_mac_addr_t *t);
+const struct ip_addr *get_ip_addr(void);
/*!
- * \returns IP address
+ * \returns gateway address
*/
-const struct ip_addr *get_ip_addr(void);
+const struct ip_addr *get_gateway(void);
-/*!set ip addr to default*/
-void set_default_ip_addr(void);
+/*!
+ * \returns subnet address
+ */
+const struct ip_addr *get_subnet(void);
/*!
* \brief write ip address to eeprom and begin using it
*/
bool set_ip_addr(const struct ip_addr *t);
+//! Apply default settings to eth addrs
+void eth_addrs_set_default(void);
/*
* \brief read RMON regs and return error mask
diff --git a/firmware/zpu/lib/memory_map.h b/firmware/zpu/lib/memory_map.h
index 9d47522ca..4290ee20a 100644
--- a/firmware/zpu/lib/memory_map.h
+++ b/firmware/zpu/lib/memory_map.h
@@ -1,4 +1,4 @@
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
/*
* Copyright 2007,2008,2009 Free Software Foundation, Inc.
*
@@ -49,18 +49,6 @@
// SPI Core, Slave 2. See core docs for more info
/////////////////////////////////////////////////////
-typedef struct {
- volatile uint32_t txrx0;
- volatile uint32_t txrx1;
- volatile uint32_t txrx2;
- volatile uint32_t txrx3;
- volatile uint32_t ctrl;
- volatile uint32_t div;
- volatile uint32_t ss;
-} spi_regs_t;
-
-#define spi_regs ((spi_regs_t *) SPI_BASE)
-
// Masks for controlling different peripherals
#define SPI_SS_AD9510 1
#define SPI_SS_AD9777 2
@@ -124,7 +112,8 @@ typedef struct {
///////////////////////////////////////////////////
typedef struct {
- volatile uint32_t _padding[8];
+ volatile uint32_t spi;
+ volatile uint32_t _padding[7];
volatile uint32_t status;
volatile uint32_t _unused;
volatile uint32_t time64_secs_rb;
@@ -133,7 +122,10 @@ typedef struct {
volatile uint32_t irqs;
} router_status_t;
+#define SPI_READY_IRQ (1 << 12)
+
#define router_status ((router_status_t *) READBACK_BASE)
+#define readback_mux ((router_status_t *) READBACK_BASE) //alias with a better name
/*!
* \brief return non-zero if we're running under the simulator
@@ -207,7 +199,7 @@ typedef struct {
#define SR_SIMTIMER 8 // 2
#define SR_TIME64 10 // 6
#define SR_BUF_POOL 16 // 4
-
+#define SR_SPI_CORE 20 // 3
#define SR_RX_FRONT 24 // 5
#define SR_RX_CTRL0 32 // 9
#define SR_RX_DSP0 48 // 7
@@ -224,6 +216,21 @@ typedef struct {
#define SR_ADDR_BLDRDONE _SR_ADDR(5)
+// --- spi core control regs ---
+
+typedef struct {
+ volatile uint32_t divider;
+ volatile uint32_t control;
+ volatile uint32_t data;
+} spi_core_t;
+
+#define SPI_CORE_SLAVE_SELECT_SHIFT 0
+#define SPI_CORE_NUM_BITS_SHIFT 24
+#define SPI_CORE_DATA_IN_EDGE_SHIFT 30
+#define SPI_CORE_DATA_OUT_EDGE_SHIFT 31
+
+#define spi_core ((spi_core_t *) _SR_ADDR(SR_SPI_CORE))
+
// --- packet router control regs ---
typedef struct {
diff --git a/firmware/zpu/lib/net_common.c b/firmware/zpu/lib/net_common.c
index 42e365393..9b75006d3 100644
--- a/firmware/zpu/lib/net_common.c
+++ b/firmware/zpu/lib/net_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Ettus Research LLC
+ * Copyright 2009-2012 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
@@ -374,6 +374,22 @@ send_arp_reply(struct arp_eth_ipv4 *req, eth_mac_addr_t our_mac)
send_pkt(t, ETHERTYPE_ARP, &reply, sizeof(reply), 0, 0, 0, 0);
}
+void net_common_send_arp_request(const struct ip_addr *addr){
+ struct arp_eth_ipv4 req _AL4;
+ req.ar_hrd = ARPHRD_ETHER;
+ req.ar_pro = ETHERTYPE_IPV4;
+ req.ar_hln = sizeof(eth_mac_addr_t);
+ req.ar_pln = sizeof(struct ip_addr);
+ req.ar_op = ARPOP_REQUEST;
+ memcpy(req.ar_sha, ethernet_mac_addr(), sizeof(eth_mac_addr_t));
+ memcpy(req.ar_sip, get_ip_addr(), sizeof(struct ip_addr));
+ memset(req.ar_tha, 0x00, sizeof(eth_mac_addr_t));
+ memcpy(req.ar_tip, addr, sizeof(struct ip_addr));
+
+ //send the request with a broadcast ethernet mac address
+ send_pkt(BCAST_MAC_ADDR, ETHERTYPE_ARP, &req, sizeof(req), 0, 0, 0, 0);
+}
+
void send_gratuitous_arp(void){
struct arp_eth_ipv4 req _AL4;
req.ar_hrd = ARPHRD_ETHER;
@@ -415,7 +431,15 @@ handle_arp_packet(struct arp_eth_ipv4 *p, size_t size)
|| p->ar_hln != 6
|| p->ar_pln != 4)
return;
-
+
+ if (p->ar_op == ARPOP_REPLY){
+ struct ip_addr ip_addr;
+ memcpy(&ip_addr, p->ar_sip, sizeof(ip_addr));
+ eth_mac_addr_t mac_addr;
+ memcpy(&mac_addr, p->ar_sha, sizeof(mac_addr));
+ arp_cache_update(&ip_addr, &mac_addr);
+ }
+
if (p->ar_op != ARPOP_REQUEST)
return;
diff --git a/firmware/zpu/lib/net_common.h b/firmware/zpu/lib/net_common.h
index 3cbc5c514..5e6daf689 100644
--- a/firmware/zpu/lib/net_common.h
+++ b/firmware/zpu/lib/net_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Ettus Research LLC
+ * Copyright 2009-2012 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
@@ -55,4 +55,7 @@ void handle_eth_packet(uint32_t *p, size_t nlines);
void send_gratuitous_arp(void);
+//! Send an ARP request for the given IP address
+void net_common_send_arp_request(const struct ip_addr *addr);
+
#endif /* INCLUDED_NET_COMMON_H */
diff --git a/firmware/zpu/lib/spi.c b/firmware/zpu/lib/spi.c
index af0d8a68f..6f2f74899 100644
--- a/firmware/zpu/lib/spi.c
+++ b/firmware/zpu/lib/spi.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2012 Ettus Research LLC
* Copyright 2007,2008 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -17,94 +18,38 @@
#include "spi.h"
#include "memory_map.h"
-#include "pic.h"
#include "nonstdio.h"
-//void (*volatile spi_callback)(void); //SPI callback when xfer complete.
-
-//static void spi_irq_handler(unsigned irq);
-
-void
-spi_init(void)
+void spi_init(void)
{
- /*
- * f_sclk = f_wb / ((div + 1) * 2)
- */
- spi_regs->div = 1; // 0 = Div by 2 (25 MHz); 1 = Div-by-4 (12.5 MHz)
+ spi_core->divider = 10;
}
-void
-spi_wait(void)
+void spi_wait(void)
{
- while (spi_regs->ctrl & SPI_CTRL_GO_BSY)
- ;
+ while ((readback_mux->irqs & SPI_READY_IRQ) == 0){
+ //NOP
+ }
}
-uint32_t
-spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags)
+uint32_t spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags)
{
- flags &= (SPI_CTRL_TXNEG | SPI_CTRL_RXNEG);
- int ctrl = SPI_CTRL_ASS | (SPI_CTRL_CHAR_LEN_MASK & length) | flags;
-
- spi_wait();
-
- // Tell it which SPI slave device to access
- spi_regs->ss = slave & 0xffff;
-
- // Data we will send
- spi_regs->txrx0 = data;
+ uint32_t control_word = 0;
+ control_word |= (slave << SPI_CORE_SLAVE_SELECT_SHIFT);
+ control_word |= (length << SPI_CORE_NUM_BITS_SHIFT);
+ if ((flags & SPI_PUSH_RISE) != 0) control_word |= (1 << SPI_CORE_DATA_OUT_EDGE_SHIFT);
+ if ((flags & SPI_PUSH_FALL) != 0) control_word |= (0 << SPI_CORE_DATA_OUT_EDGE_SHIFT);
+ if ((flags & SPI_LATCH_RISE) != 0) control_word |= (1 << SPI_CORE_DATA_IN_EDGE_SHIFT);
+ if ((flags & SPI_LATCH_FALL) != 0) control_word |= (0 << SPI_CORE_DATA_IN_EDGE_SHIFT);
- // Run it -- write once and rewrite with GO set
- spi_regs->ctrl = ctrl;
- spi_regs->ctrl = ctrl | SPI_CTRL_GO_BSY;
+ const uint32_t data_out = data << (32 - length);
- if(readback) {
spi_wait();
- return spi_regs->txrx0;
- }
- else
- return 0;
-}
+ spi_core->control = control_word;
+ spi_core->data = data_out;
-/*
-void spi_register_callback(void (*volatile callback)(void)) {
- spi_callback = callback;
-}
-
-static void spi_irq_handler(unsigned irq) {
-// printf("SPI IRQ handler\n");
-// uint32_t wat = spi_regs->ctrl; //read a register just to clear the interrupt
- //spi_regs->ctrl &= ~SPI_CTRL_IE;
- if(spi_callback) spi_callback(); //we could just use the PIC to register the user's callback, but this provides the ability to do other things later
-}
+ if (!readback) return 0;
-uint32_t spi_get_data(void) {
- return spi_regs->txrx0;
-}
-
-bool
-spi_async_transact(int slave, uint32_t data, int length, uint32_t flags, void (*volatile callback)(void)) {
- flags &= (SPI_CTRL_TXNEG | SPI_CTRL_RXNEG);
- int ctrl = SPI_CTRL_ASS | SPI_CTRL_IE | (SPI_CTRL_CHAR_LEN_MASK & length) | flags;
-
- if(spi_regs->ctrl & SPI_CTRL_GO_BSY) {
- printf("Async SPI busy!\n");
- return false; //we don't wait on busy, we just return failure. we count on the host to not set up another transaction before the last one finishes.
- }
-
- // Tell it which SPI slave device to access
- spi_regs->ss = slave & 0xffff;
-
- // Data we will send
- spi_regs->txrx0 = data;
-
- spi_register_callback(callback);
- pic_register_handler(IRQ_SPI, spi_irq_handler);
-
- // Run it -- write once and rewrite with GO set
- spi_regs->ctrl = ctrl;
- spi_regs->ctrl = ctrl | SPI_CTRL_GO_BSY;
-
- return true;
+ spi_wait();
+ return readback_mux->spi;
}
-*/
diff --git a/firmware/zpu/lib/spi.h b/firmware/zpu/lib/spi.h
index 71245150a..125e1a502 100644
--- a/firmware/zpu/lib/spi.h
+++ b/firmware/zpu/lib/spi.h
@@ -1,5 +1,5 @@
-/* -*- c -*- */
/*
+ * Copyright 2012 Ettus Research LLC
* Copyright 2006,2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -19,8 +19,8 @@
#ifndef INCLUDED_SPI_H
#define INCLUDED_SPI_H
-#include <memory_map.h>
#include <stdbool.h>
+#include <stdint.h>
/*!
* \brief One time call to initialize SPI
@@ -39,39 +39,11 @@ void spi_wait(void);
/*
* Flags for spi_transact
*/
-#define SPIF_PUSH_RISE 0 // push tx data on rising edge of SCLK
-#define SPIF_PUSH_FALL SPI_CTRL_TXNEG // push tx data on falling edge of SCLK
-#define SPIF_LATCH_RISE 0 // latch rx data on rising edge of SCLK
-#define SPIF_LATCH_FALL SPI_CTRL_RXNEG // latch rx data on falling edge of SCLK
-
-
-uint32_t
-spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags);
-
-//uint32_t spi_get_data(void);
-//static void spi_irq_handler(unsigned irq);
-//void spi_register_callback(void (*volatile callback)(void));
-
-//bool
-//spi_async_transact(int slave, uint32_t data, int length, uint32_t flags, void (*volatile callback)(void));
-
-// ----------------------------------------------------------------
-// Routines that manipulate the FLASH SPI BUS
-// ----------------------------------------------------------------
-
-/*!
- * \brief One time call to initialize SPI
- */
-void spif_init(void);
-
-/*!
- * \brief Wait for last SPI transaction to complete.
- * Unless you need to know it completed, it's not necessary to call this.
- */
-void spif_wait(void);
-
-uint32_t
-spif_transact(bool readback_, int slave, uint32_t data, int length, uint32_t flags);
+#define SPI_PUSH_RISE (1 << 0) // push tx data on rising edge of SCLK
+#define SPI_PUSH_FALL (1 << 1) // push tx data on falling edge of SCLK
+#define SPI_LATCH_RISE (1 << 2) // latch rx data on rising edge of SCLK
+#define SPI_LATCH_FALL (1 << 3) // latch rx data on falling edge of SCLK
+uint32_t spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags);
#endif /* INCLUDED_SPI_H */
diff --git a/firmware/zpu/lib/u2_init.c b/firmware/zpu/lib/u2_init.c
index 71bd2c594..77c8c0722 100644
--- a/firmware/zpu/lib/u2_init.c
+++ b/firmware/zpu/lib/u2_init.c
@@ -51,6 +51,7 @@ u2_init(void)
hal_enable_ints();
// flash all leds to let us know board is alive
+#ifndef BOOTLOADER
hal_set_led_src(0x0, 0x1f); /* software ctrl */
hal_set_leds(0x0, 0x1f); mdelay(300);
hal_set_leds(LED_E, LED_E); mdelay(300);
@@ -61,6 +62,7 @@ u2_init(void)
hal_set_leds(0x0, 0x1f); mdelay(100);
hal_set_leds(blinks, 0x1f); mdelay(100);
}
+#endif
hal_set_led_src(0x1f & ~LED_D, 0x1f); /* hardware ctrl */
hal_set_leds(LED_D, 0x1f); // Leave one on
diff --git a/firmware/zpu/usrp2p/spi_flash.c b/firmware/zpu/usrp2p/spi_flash.c
index 9406f8042..09f908edb 100644
--- a/firmware/zpu/usrp2p/spi_flash.c
+++ b/firmware/zpu/usrp2p/spi_flash.c
@@ -1,7 +1,6 @@
-/* -*- c++ -*- */
/*
* Copyright 2009 Free Software Foundation, Inc.
- * Copyright 2009-2011 Ettus Research LLC
+ * Copyright 2009-2012 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
@@ -17,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "spi_flash.h"
#include "spi_flash_private.h"
//#include <stdlib.h>
#include <nonstdio.h>
diff --git a/firmware/zpu/usrp2p/spi_flash.h b/firmware/zpu/usrp2p/spi_flash.h
index a10533e08..8a8facdca 100644
--- a/firmware/zpu/usrp2p/spi_flash.h
+++ b/firmware/zpu/usrp2p/spi_flash.h
@@ -23,10 +23,18 @@
#include <stdint.h>
#include <stdbool.h>
-
#define SPI_FLASH_PAGE_SIZE 256
#define SPI_SS_FLASH 1
+#define SPIF_PUSH_RISE 0 // push tx data on rising edge of SCLK
+#define SPIF_PUSH_FALL SPI_CTRL_TXNEG // push tx data on falling edge of SCLK
+#define SPIF_LATCH_RISE 0 // latch rx data on rising edge of SCLK
+#define SPIF_LATCH_FALL SPI_CTRL_RXNEG // latch rx data on falling edge of SCLK
+
+void spif_init(void);
+void spif_wait(void);
+
+uint32_t spif_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags);
uint32_t spi_flash_rdid(void); /* Read ID */
uint32_t spi_flash_rdsr(void); /* Read Status Register */
diff --git a/firmware/zpu/usrp2p/spif.c b/firmware/zpu/usrp2p/spif.c
index 91da73155..60807ca4a 100644
--- a/firmware/zpu/usrp2p/spif.c
+++ b/firmware/zpu/usrp2p/spif.c
@@ -21,6 +21,7 @@
*/
#include "spi.h"
+#include "spi_flash.h"
#include "memory_map.h"
void
diff --git a/firmware/zpu/usrp2p/u2p_init.c b/firmware/zpu/usrp2p/u2p_init.c
index 381987ae6..1890dd726 100644
--- a/firmware/zpu/usrp2p/u2p_init.c
+++ b/firmware/zpu/usrp2p/u2p_init.c
@@ -24,7 +24,6 @@ void u2p_init(void){
bool safe_fw = find_safe_booted_flag();
set_safe_booted_flag(0);
if (safe_fw) {
- set_default_ip_addr();
- set_default_mac_addr();
+ eth_addrs_set_default();
}
}
diff --git a/firmware/zpu/usrp2p/udp_fw_update.c b/firmware/zpu/usrp2p/udp_fw_update.c
index 5689388a8..cd9e7d902 100644
--- a/firmware/zpu/usrp2p/udp_fw_update.c
+++ b/firmware/zpu/usrp2p/udp_fw_update.c
@@ -1,6 +1,5 @@
-/* -*- c++ -*- */
/*
- * Copyright 2010 Ettus Research LLC
+ * Copyright 2010-2012 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
@@ -19,6 +18,7 @@
//Routines to handle updating the SPI Flash firmware via UDP
#include <net_common.h>
+#include "memory_map.h"
#include "usrp2/fw_common.h"
#include "spi.h"
#include "spi_flash.h"