diff options
-rwxr-xr-x | host/lib/ic_reg_maps/common.py | 50 | ||||
-rwxr-xr-x | host/lib/ic_reg_maps/gen_zbx_cpld_regs.py | 63 | ||||
-rw-r--r-- | host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp | 2 |
3 files changed, 80 insertions, 35 deletions
diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py index a689872ff..2275c68e2 100755 --- a/host/lib/ic_reg_maps/common.py +++ b/host/lib/ic_reg_maps/common.py @@ -235,6 +235,18 @@ def to_num(arg): """ return int(eval(arg)) +def is_int(arg): + """ + check whether arg is convertable to an integer + (including non-decimal representation) + """ + try: + to_num(arg) + return True + except: + return False + + class reg: def __init__(self, reg_des): self.is_array = False @@ -247,6 +259,22 @@ class reg: 'Error parsing register description: "{}"\nWhat: {}' .format(reg_des, e)) + def _parse_options(self, optionstr): + """ + `optionstr` contains additional register information in a + comma-separated list as key=value pairs. + + For backward compability a number <x> is converted to + `default=<x>,rw` + which retains the previous behaviour. + """ + if is_int(optionstr): + # convert number into option list for backward compability + optionstr = f"default={optionstr},rw" + options = [option.partition("=") for option in optionstr.split(",")] + result = { item[0] : item[2] or None for item in options } + return result + def parse(self, reg_des): """ Parse a regmap line. @@ -268,15 +296,15 @@ class reg: initialized to 0. duper_reg is an array of length 128, of 32-bit registers. """ x = re.match( - r'^(\w*)(\[([0-9:]*)\])?\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', + r'^(\w*)(\[([0-9:]*)\])?\s*(\w*)\[(.*)\]\s*([=,\w]*)\s*(.*)$', reg_des) - name, _, addr_range, addr, bit_range, default, enums = x.groups() + name, _, addr_range, addr, bit_range, options, enums = x.groups() #store variables self._name = name self._addr = to_num(addr) if ':' in bit_range: self._addr_spec = sorted(map(int, bit_range.split(':'))) else: self._addr_spec = int(bit_range), int(bit_range) - self._default = to_num(default) + self.options = self._parse_options(options) #extract enum self._enums = list() if enums: @@ -313,9 +341,10 @@ class reg: def get_enums(self): return self._enums def get_name(self): return self._name def get_default(self): + default_val = to_num(self.options.get("default", "0")) for key, val in self.get_enums(): - if val == self._default: return ('%s_%s'%(self.get_name(), key)).upper() - return self._default + if val == default_val: return ('%s_%s'%(self.get_name(), key)).upper() + return default_val def get_type(self): if self.get_enums(): return '%s_t'%self.get_name() return 'uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8) @@ -334,6 +363,11 @@ class reg: Return the step size for register arrays """ return self._addr_step + def is_readonly(self): + """ + Check whether register is marked as readonly via option string + """ + return "ro" in self.options class mreg: def __init__(self, mreg_des, regs): @@ -353,7 +387,7 @@ class mreg: def get_type(self): return 'uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8) -def generate(name, regs_tmpl, body_tmpl='', py_body_tmpl='', file=__file__, append=False): +def generate(name, regs_tmpl, body_tmpl='', py_body_tmpl='', file=__file__, append=False, **kwargs): # determine if the destination file is a Python or C++ header file out_file = sys.argv[1] if out_file.endswith('.py'): # Write a Python file @@ -373,15 +407,17 @@ def generate(name, regs_tmpl, body_tmpl='', py_body_tmpl='', file=__file__, appe regs.append(reg(entry)) #evaluate the body template with the list of registers - body = '\n '.join(parse_tmpl(body_template, regs=regs).splitlines()) + body = '\n '.join(parse_tmpl(body_template, **dict(kwargs, regs=regs)).splitlines()) #evaluate the code template with the parsed registers and arguments code = parse_tmpl(template, + **dict(kwargs, name=name, regs=regs, mregs=mregs, body=body, file=file, + ) ) #write the generated code to file specified by argv1 diff --git a/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py b/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py index 0efc8a4d7..fce051d53 100755 --- a/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py +++ b/host/lib/ic_reg_maps/gen_zbx_cpld_regs.py @@ -18,24 +18,24 @@ REGS_TMPL = """\ ######################################################################## ## SLAVE SETUP ######################################################################## -BOARD_ID 0x0000[0:15] 0 -REVISION 0x0004[0:31] 0 -OLDEST_COMPAT_REVISION 0x0008[0:31] 0 +BOARD_ID 0x0000[0:15] ro +REVISION 0x0004[0:31] ro +OLDEST_COMPAT_REVISION 0x0008[0:31] ro SCRATCH 0x000C[0:31] 0 -GIT_HASH 0x0010[0:31] 0 -ENABLE_TX_POS_7V0 0x0040[0] 0 disable, enable -ENABLE_RX_POS_7V0 0x0040[1] 0 disable, enable -ENABLE_POS_3V3 0x0040[2] 0 disable, enable -P7V_B_STATUS 0x0044[0] 0 -P7V_A_STATUS 0x0044[1] 0 -PLL_REF_CLOCK_ENABLE 0x0048[0] 0 disable, enable +GIT_HASH 0x0010[0:31] ro +ENABLE_TX_POS_7V0 0x0040[0] scope=mpm disable, enable +ENABLE_RX_POS_7V0 0x0040[1] scope=mpm disable, enable +ENABLE_POS_3V3 0x0040[2] scope=mpm disable, enable +P7V_B_STATUS 0x0044[0] scope=mpm,ro +P7V_A_STATUS 0x0044[1] scope=mpm,ro +PLL_REF_CLOCK_ENABLE 0x0048[0] scope=mpm disable, enable ######################################################################## ## ATR ######################################################################## -CURRENT_RF0_CONFIG 0x1000[0:7] 1 -CURRENT_RF1_CONFIG 0x1000[8:15] 1 -CURRENT_RF0_DSA_CONFIG 0x1000[23:16] 1 -CURRENT_RF1_DSA_CONFIG 0x1000[31:24] 1 +CURRENT_RF0_CONFIG 0x1000[0:7] ro +CURRENT_RF1_CONFIG 0x1000[8:15] ro +CURRENT_RF0_DSA_CONFIG 0x1000[23:16] ro +CURRENT_RF1_DSA_CONFIG 0x1000[31:24] ro RF0_OPTION 0x1004[0:1] 0 sw_defined, classic_atr, fpga_state RF1_OPTION 0x1004[8:9] 0 sw_defined, classic_atr, fpga_state RF0_DSA_OPTION 0x1004[17:16] 0 sw_defined, classic_atr, fpga_state @@ -52,8 +52,8 @@ ADDRESS 0x1020[16:22] 0 READ_FLAG 0x1020[23] 1 write, read LO_SELECT 0x1020[24:26] 0 TX0_LO1, TX0_LO2, TX1_LO1, TX1_LO2, RX0_LO1, RX0_LO2, RX1_LO1, RX1_LO2 START_TRANSACTION 0x1020[28] 0 disable, enable -SPI_READY 0x1020[30] 0 -DATA_VALID 0x1020[31] 0 +SPI_READY 0x1020[30] ro +DATA_VALID 0x1020[31] ro ######################################################################## ## LO SYNC ######################################################################## @@ -301,7 +301,7 @@ uint32_t get_field(zbx_cpld_field_t field, const size_t idx) { void set_field(zbx_cpld_field_t field, uint32_t value) { switch(field) { % for addr in sorted(set([r.get_addr() for r in regs if not r.is_array])): - % for reg in filter(lambda r: r.get_addr() == addr, regs): + % for reg in filter(lambda r: r.get_addr() == addr and not r.is_readonly(), regs): case zbx_cpld_field_t::${reg.get_name()}: ${reg.get_name()} = static_cast<${reg.get_type()}>(value); break; @@ -399,17 +399,19 @@ void set_reg(uint16_t addr, uint32_t val) } } -<% - all_addrs = set() - for reg in regs: - for index in range(reg.get_array_len() if reg.is_array else 1): - all_addrs.add(reg.get_addr() + index * reg.get_addr_step_size()) -%> -std::set<size_t> get_all_addrs() +template<typename T> std::set<T> get_all_addrs(bool include_ro = false) { - std::set<size_t> addrs; - % for addr in sorted(all_addrs): - addrs.insert(${addr}); + std::set<T> addrs; + % for reg in filter(all_addr_filter, regs): + % if reg.is_readonly(): + if (include_ro) { + % else: + { + % endif + % for index in range(reg.get_array_len() if reg.is_array else 1): + addrs.insert(${reg.get_addr() + index * reg.get_addr_step_size()}); + % endfor + } % endfor return addrs; } @@ -440,11 +442,18 @@ uint16_t get_addr(const std::string& reg_name) """ if __name__ == '__main__': + import sys import common + outfile=sys.argv[1] + if outfile.endswith(".hpp"): + all_addr_filter = lambda reg: "mpm" not in reg.options.get("scope", "") + else: + all_addr_filter = lambda reg: True common.generate( name='zbx_cpld_regs', regs_tmpl=REGS_TMPL, body_tmpl=BODY_TMPL, py_body_tmpl=PY_BODY_TMPL, file=__file__, + all_addr_filter=all_addr_filter ) diff --git a/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp b/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp index 352a7def9..28a7c6347 100644 --- a/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp +++ b/host/lib/usrp/dboard/zbx/zbx_cpld_ctrl.cpp @@ -900,7 +900,7 @@ void zbx_cpld_ctrl::commit(const chan_t chan, const bool save_all) UHD_LOG_TRACE(_log_id, "Storing register cache " << (save_all ? "completely" : "selectively") << " to CPLD..."); - const auto changed_addrs = save_all ? _regs.get_all_addrs() + const auto changed_addrs = save_all ? _regs.get_all_addrs<size_t>() : _regs.get_changed_addrs<size_t>(); for (const auto addr : changed_addrs) { _poke32(addr, _regs.get_reg(addr), save_all ? NO_CHAN : chan); |