diff options
Diffstat (limited to 'usrp2')
-rw-r--r-- | usrp2/firmware/apps/app_common_v2.c | 17 | ||||
-rw-r--r-- | usrp2/firmware/include/usrp2_eth_packet.h | 2 | ||||
-rw-r--r-- | usrp2/firmware/lib/memory_map.h | 19 | ||||
-rw-r--r-- | usrp2/fpga/timing/time_sync.v | 5 | ||||
-rw-r--r-- | usrp2/host/include/usrp2/usrp2.h | 7 | ||||
-rw-r--r-- | usrp2/host/lib/usrp2.cc | 6 | ||||
-rw-r--r-- | usrp2/host/lib/usrp2_impl.cc | 24 | ||||
-rw-r--r-- | usrp2/host/lib/usrp2_impl.h | 1 |
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); }; |