summaryrefslogtreecommitdiff
path: root/usrp2
diff options
context:
space:
mode:
Diffstat (limited to 'usrp2')
-rw-r--r--usrp2/firmware/apps/app_common_v2.c17
-rw-r--r--usrp2/firmware/include/usrp2_eth_packet.h2
-rw-r--r--usrp2/firmware/lib/memory_map.h19
-rw-r--r--usrp2/fpga/timing/time_sync.v5
-rw-r--r--usrp2/host/include/usrp2/usrp2.h7
-rw-r--r--usrp2/host/lib/usrp2.cc6
-rw-r--r--usrp2/host/lib/usrp2_impl.cc24
-rw-r--r--usrp2/host/lib/usrp2_impl.h1
8 files changed, 79 insertions, 2 deletions
diff --git a/usrp2/firmware/apps/app_common_v2.c b/usrp2/firmware/apps/app_common_v2.c
index c277d12f0..df943a4ee 100644
--- a/usrp2/firmware/apps/app_common_v2.c
+++ b/usrp2/firmware/apps/app_common_v2.c
@@ -55,6 +55,18 @@ sync_to_pps(const op_generic_t *p)
}
static bool
+sync_every_pps(const op_generic_t *p)
+{
+ // FIXME use bit fields or defined masks
+ if (p->ok)
+ timesync_regs->tick_control |= 16;
+ else
+ timesync_regs->tick_control &= ~16;
+
+ return true;
+}
+
+static bool
config_mimo_cmd(const op_config_mimo_t *p)
{
clocks_mimo_config(p->flags);
@@ -505,6 +517,11 @@ handle_control_chan_frame(u2_eth_packet_t *pkt, size_t len)
subpktlen = generic_reply(gp, reply_payload, reply_payload_space, true);
break;
+ case OP_SYNC_EVERY_PPS:
+ subpktlen = generic_reply(gp, reply_payload, reply_payload_space,
+ sync_every_pps((op_generic_t *) payload));
+ break;
+
default:
printf("app_common_v2: unhandled opcode = %d\n", gp->opcode);
break;
diff --git a/usrp2/firmware/include/usrp2_eth_packet.h b/usrp2/firmware/include/usrp2_eth_packet.h
index 77de02dbb..98e2123ed 100644
--- a/usrp2/firmware/include/usrp2_eth_packet.h
+++ b/usrp2/firmware/include/usrp2_eth_packet.h
@@ -195,6 +195,8 @@ typedef struct {
#define OP_SET_RX_LO_OFFSET_REPLY (OP_SET_RX_LO_OFFSET | OP_REPLY_BIT)
#define OP_RESET_DB 15
#define OP_RESET_DB_REPLY (OP_RESET_DB | OP_REPLY_BIT)
+#define OP_SYNC_EVERY_PPS 16
+#define OP_SYNC_EVERY_PPS_REPLY (OP_SYNC_EVERY_PPS | OP_REPLY_BIT)
/*
* All subpackets are a multiple of 4 bytes long.
diff --git a/usrp2/firmware/lib/memory_map.h b/usrp2/firmware/lib/memory_map.h
index 0519282bb..f4bf42010 100644
--- a/usrp2/firmware/lib/memory_map.h
+++ b/usrp2/firmware/lib/memory_map.h
@@ -629,6 +629,25 @@ typedef struct {
#define TIMESYNC_BASE 0xE800
typedef struct {
+ /*!
+ * \brief Time sync configuration.
+ *
+ * <pre>
+ *
+ * 3 2 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------------------------------------------------+-+-+-+-+-+
+ * | |T|G|X|I|S|
+ * +-----------------------------------------------------+-+-+-+-+-+
+ *
+ * S - Tick source (0 = free run, 1 = pps, default=0)
+ * I - Tick interrupt enable (not implemented)
+ * X - Use external sync source (default=1)
+ * G - PPS edge selection (0=negedge, 1=posedge, default=0)
+ * T - Trigger sync every pps edge (default=0)
+ *
+ * </pre>
+ */
volatile uint32_t tick_control;
volatile uint32_t tick_interval;
volatile uint32_t delta_time;
diff --git a/usrp2/fpga/timing/time_sync.v b/usrp2/fpga/timing/time_sync.v
index 6b9848064..a4c021f58 100644
--- a/usrp2/fpga/timing/time_sync.v
+++ b/usrp2/fpga/timing/time_sync.v
@@ -22,6 +22,7 @@ module time_sync
reg tick_int_enable, tick_source, external_sync;
reg [31:0] tick_interval;
reg sync_on_next_pps;
+ reg sync_every_pps;
reg pps_edge;
// Generate master time
@@ -30,7 +31,7 @@ module time_sync
master_time <= 0;
else if(external_sync & sync_rcvd)
master_time <= master_time_rcvd + delta_time;
- else if(pps_ext & sync_on_next_pps)
+ else if(pps_ext & (sync_on_next_pps|sync_every_pps))
master_time <= 0;
else
master_time <= master_time + 1;
@@ -62,6 +63,7 @@ module time_sync
tick_interval <= 100000-1; // default to 1K times per second
delta_time <= 0;
pps_edge <= 0;
+ sync_every_pps <= 0;
end
else if(wb_write)
case(adr_i[2:0])
@@ -71,6 +73,7 @@ module time_sync
tick_int_enable <= dat_i[1];
external_sync <= dat_i[2];
pps_edge <= dat_i[3];
+ sync_every_pps <= dat_i[4];
end
3'd1 :
tick_interval <= dat_i;
diff --git a/usrp2/host/include/usrp2/usrp2.h b/usrp2/host/include/usrp2/usrp2.h
index 2186ce90b..14f04fafd 100644
--- a/usrp2/host/include/usrp2/usrp2.h
+++ b/usrp2/host/include/usrp2/usrp2.h
@@ -372,11 +372,16 @@ namespace usrp2 {
bool burn_mac_addr(const std::string &new_addr);
/*!
- * Reset master time to 0 at next PPS rising edge
+ * Reset master time to 0 at next PPS edge
*/
bool sync_to_pps();
/*!
+ * Reset master time to 0 at every PPS edge
+ */
+ bool sync_every_pps(bool enable);
+
+ /*!
* Read memory from Wishbone bus as 32-bit words. Handles endian swapping if needed.
*
* \param addr 32-bit aligned address. Only the lower 16-bits are significant.
diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc
index 6a54c6da6..77c1e3374 100644
--- a/usrp2/host/lib/usrp2.cc
+++ b/usrp2/host/lib/usrp2.cc
@@ -413,6 +413,12 @@ namespace usrp2 {
return d_impl->sync_to_pps();
}
+ bool
+ usrp2::sync_every_pps(bool enable)
+ {
+ return d_impl->sync_every_pps(enable);
+ }
+
std::vector<uint32_t>
usrp2::peek32(uint32_t addr, uint32_t words)
{
diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc
index 4b4de024f..ea50a709c 100644
--- a/usrp2/host/lib/usrp2_impl.cc
+++ b/usrp2/host/lib/usrp2_impl.cc
@@ -77,6 +77,8 @@ namespace usrp2 {
case OP_SET_TX_LO_OFFSET_REPLY: return "OP_SET_TX_LO_OFFSET_REPLY";
case OP_SET_RX_LO_OFFSET: return "OP_SET_RX_LO_OFFSET";
case OP_SET_RX_LO_OFFSET_REPLY: return "OP_SET_RX_LO_OFFSET_REPLY";
+ case OP_SYNC_EVERY_PPS: return "OP_SYNC_EVERY_PPS";
+ case OP_SYNC_EVERY_PPS_REPLY: return "OP_SYNC_EVERY_PPS_REPLY";
default:
char buf[64];
@@ -1128,6 +1130,28 @@ namespace usrp2 {
return ntohx(reply.ok) == 1;
}
+ bool
+ usrp2::impl::sync_every_pps(bool enable)
+ {
+ op_generic_cmd cmd;
+ op_generic_t reply;
+
+ memset(&cmd, 0, sizeof(cmd));
+ init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
+ cmd.op.opcode = OP_SYNC_EVERY_PPS;
+ cmd.op.len = sizeof(cmd.op);
+ cmd.op.rid = d_next_rid++;
+ cmd.op.ok = enable ? 1 : 0;
+ cmd.eop.opcode = OP_EOP;
+ cmd.eop.len = sizeof(cmd.eop);
+
+ pending_reply p(cmd.op.rid, &reply, sizeof(reply));
+ if (!transmit_cmd(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
+ return false;
+
+ return ntohx(reply.ok) == 1;
+ }
+
std::vector<uint32_t>
usrp2::impl::peek32(uint32_t addr, uint32_t words)
{
diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h
index dfd054c03..6822f8f97 100644
--- a/usrp2/host/lib/usrp2_impl.h
+++ b/usrp2/host/lib/usrp2_impl.h
@@ -180,6 +180,7 @@ namespace usrp2 {
bool burn_mac_addr(const std::string &new_addr);
bool sync_to_pps();
+ bool sync_every_pps(bool enable);
std::vector<uint32_t> peek32(uint32_t addr, uint32_t words);
bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
};