diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-07-03 20:15:35 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 12:16:25 -0800 |
commit | c256b9df6502536c2e451e690f1ad5962c664d1a (patch) | |
tree | a83ad13e6f5978bbe14bb3ecf8294ba1e3d28db4 /mpm/python/usrp_mpm/periph_manager/e320_periphs.py | |
parent | 9a8435ed998fc5c65257f4c55768750b227ab19e (diff) | |
download | uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.tar.gz uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.tar.bz2 uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.zip |
x300/mpmd: Port all RFNoC devices to the new RFNoC framework
Co-Authored-By: Alex Williams <alex.williams@ni.com>
Co-Authored-By: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-Authored-By: Brent Stapleton <brent.stapleton@ettus.com>
Co-Authored-By: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Diffstat (limited to 'mpm/python/usrp_mpm/periph_manager/e320_periphs.py')
-rw-r--r-- | mpm/python/usrp_mpm/periph_manager/e320_periphs.py | 164 |
1 files changed, 139 insertions, 25 deletions
diff --git a/mpm/python/usrp_mpm/periph_manager/e320_periphs.py b/mpm/python/usrp_mpm/periph_manager/e320_periphs.py index 0cf7f59c6..cad5c39ad 100644 --- a/mpm/python/usrp_mpm/periph_manager/e320_periphs.py +++ b/mpm/python/usrp_mpm/periph_manager/e320_periphs.py @@ -48,25 +48,40 @@ class MboardRegsControl(object): Control the FPGA Motherboard registers """ # Motherboard registers - MB_COMPAT_NUM = 0x0000 - MB_DATESTAMP = 0x0004 - MB_GIT_HASH = 0x0008 - MB_SCRATCH = 0x000C - MB_NUM_CE = 0x0010 - MB_NUM_IO_CE = 0x0014 - MB_CLOCK_CTRL = 0x0018 - MB_XADC_RB = 0x001C - MB_BUS_CLK_RATE = 0x0020 - MB_BUS_COUNTER = 0x0024 - MB_SFP_PORT_INFO = 0x0028 - MB_GPIO_CTRL = 0x002C - MB_GPIO_MASTER = 0x0030 - MB_GPIO_RADIO_SRC = 0x0034 - MB_GPS_CTRL = 0x0038 - MB_GPS_STATUS = 0x003C - MB_DBOARD_CTRL = 0x0040 - MB_DBOARD_STATUS = 0x0044 - MB_XBAR_BASEPORT = 0x0048 + MB_COMPAT_NUM = 0x0000 + MB_DATESTAMP = 0x0004 + MB_GIT_HASH = 0x0008 + MB_SCRATCH = 0x000C + MB_DEVICE_ID = 0x0010 + MB_RFNOC_INFO = 0x0014 + MB_CLOCK_CTRL = 0x0018 + MB_XADC_RB = 0x001C + MB_BUS_CLK_RATE = 0x0020 + MB_BUS_COUNTER = 0x0024 + MB_SFP_PORT_INFO = 0x0028 + MB_GPIO_CTRL = 0x002C + MB_GPIO_MASTER = 0x0030 + MB_GPIO_RADIO_SRC = 0x0034 + MB_GPS_CTRL = 0x0038 + MB_GPS_STATUS = 0x003C + MB_DBOARD_CTRL = 0x0040 + MB_DBOARD_STATUS = 0x0044 + MB_NUM_TIMEKEEPERS = 0x0048 + # Timekeeper registers + MB_TIME_NOW_LO = 0x1000 + MB_TIME_NOW_HI = 0x1004 + MB_TIME_EVENT_LO = 0x1008 + MB_TIME_EVENT_HI = 0x100C + MB_TIME_CTRL = 0x1010 + MB_TIME_LAST_PPS_LO = 0x1014 + MB_TIME_LAST_PPS_HI = 0x1018 + MB_TIME_BASE_PERIOD_LO = 0x101C + MB_TIME_BASE_PERIOD_HI = 0x1020 + MB_TIMEKEEPER_OFFSET = 12 + + # Bitfield locations for the MB_RFNOC_INFO register. + MB_RFNOC_INFO_PROTO_VER = 0 + MB_RFNOC_INFO_CHDR_WIDTH = 16 # Bitfield locations for the MB_CLOCK_CTRL register. MB_CLOCK_CTRL_PPS_SEL_INT = 0 @@ -122,6 +137,44 @@ class MboardRegsControl(object): major = (compat_number>>16) & 0xff return (major, minor) + def set_device_id(self, device_id): + """ + Set device ID + """ + with self.regs: + self.log.trace("Writing MB_DEVICE_ID with 0x{:08X}".format(device_id)) + return self.poke32(self.MB_DEVICE_ID, device_id) + + def get_device_id(self): + """ + Get device ID + """ + with self.regs: + reg_val = self.peek32(self.MB_DEVICE_ID) + device_id = reg_val & 0x0000ffff + self.log.trace("Read MB_DEVICE_ID 0x{:08X}".format(device_id)) + return device_id + + def get_proto_ver(self): + """ + Return RFNoC protocol version + """ + with self.regs: + reg_val = self.peek32(self.MB_RFNOC_INFO) + proto_ver = (reg_val & 0x0000ffff) >> self.MB_RFNOC_INFO_PROTO_VER + self.log.trace("Read RFNOC_PROTO_VER 0x{:08X}".format(proto_ver)) + return proto_ver; + + def get_chdr_width(self): + """ + Return RFNoC CHDR width + """ + with self.regs: + reg_val = self.peek32(self.MB_RFNOC_INFO) + chdr_width = (reg_val & 0xffff0000) >> self.MB_RFNOC_INFO_CHDR_WIDTH + self.log.trace("Read RFNOC_CHDR_WIDTH 0x{:08X}".format(chdr_width)) + return chdr_width + def enable_fp_gpio(self, enable): """ Enable front panel GPIO buffers and power supply and set voltage 3.3 V @@ -372,7 +425,8 @@ class MboardRegsControl(object): reg_val = self.peek32(self.MB_DBOARD_CTRL) if channel_mode == "MIMO": reg_val = (0b1 << self.MB_DBOARD_CTRL_MIMO) - self.log.trace("Setting channel mode in AD9361 interface: {}".format("2R2T" if channel_mode == 2 else "1R1T")) + self.log.trace("Setting channel mode in AD9361 interface: %s", + "2R2T" if channel_mode == 2 else "1R1T") else: # Warn if user tries to set either tx0/tx1 in mimo mode # as both will be set automatically @@ -393,7 +447,7 @@ class MboardRegsControl(object): """ mask = 0b1 << self.MB_DBOARD_STATUS_TX_LOCK with self.regs: - reg_val = self.peek32(self.MB_DBOARD_STATUS) + reg_val = self.peek32(self.MB_DBOARD_STATUS) locked = (reg_val & mask) > 0 if not locked: self.log.warning("TX RF PLL reporting unlocked. ") @@ -407,7 +461,7 @@ class MboardRegsControl(object): """ mask = 0b1 << self.MB_DBOARD_STATUS_RX_LOCK with self.regs: - reg_val = self.peek32(self.MB_DBOARD_STATUS) + reg_val = self.peek32(self.MB_DBOARD_STATUS) locked = (reg_val & mask) > 0 if not locked: self.log.warning("RX RF PLL reporting unlocked. ") @@ -415,7 +469,67 @@ class MboardRegsControl(object): self.log.trace("RX RF PLL locked") return locked - def get_xbar_baseport(self): - "Get the RFNoC crossbar base port" + def get_num_timekeepers(self): + """ + Return the number of timekeepers + """ + with self.regs: + return self.peek32(self.MB_NUM_TIMEKEEPERS) + + def get_timekeeper_time(self, tk_idx, last_pps): + """ + Get the time in ticks + + Arguments: + tk_idx: Index of timekeeper + next_pps: If True, get time at last PPS. Otherwise, get time now. + """ + addr_lo = \ + (self.MB_TIME_LAST_PPS_LO if last_pps else self.MB_TIME_NOW_LO) + \ + tk_idx * self.MB_TIMEKEEPER_OFFSET + addr_hi = addr_lo + 4 + with self.regs: + time_lo = self.peek32(addr_lo) + time_hi = self.peek32(addr_hi) + return time_hi << 32 | time_lo + + + def set_timekeeper_time(self, tk_idx, ticks, next_pps): + """ + Set the time in ticks + + Arguments: + tk_idx: Index of timekeeper + ticks: Time in ticks + next_pps: If True, set time at next PPS. Otherwise, set time now. + """ + addr_lo = \ + self.MB_TIME_EVENT_LO + tk_idx * self.MB_TIMEKEEPER_OFFSET + addr_hi = addr_lo + 4 + addr_ctrl = \ + self.MB_TIME_CTRL + tk_idx * self.MB_TIMEKEEPER_OFFSET + time_lo = ticks & 0xFFFFFFFF + time_hi = (ticks > 32) & 0xFFFFFFFF + time_ctrl = 0x2 if next_pps else 0x1 + self.log.trace("Setting time on timekeeper %d to %d %s", tk_idx, ticks, + ("on next pps" if next_pps else "now")) + with self.regs: + self.poke32(addr_lo, time_lo) + self.poke32(addr_hi, time_hi) + self.poke32(addr_ctrl, time_ctrl) + + def set_tick_period(self, tk_idx, period_ns): + """ + Set the time per tick in nanoseconds (tick period) + + Arguments: + tk_idx: Index of timekeeper + period_ns: Period in nanoseconds + """ + addr_lo = self.MB_TIME_BASE_PERIOD_LO + tk_idx * self.MB_TIMEKEEPER_OFFSET + addr_hi = addr_lo + 4 + period_lo = period_ns & 0xFFFFFFFF + period_hi = (period_ns > 32) & 0xFFFFFFFF with self.regs: - return self.peek32(self.MB_XBAR_BASEPORT) + self.poke32(addr_lo, period_lo) + self.poke32(addr_hi, period_hi) |