tmc2130: Add support for two's complement signed fields to FieldHelper
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
2cff3291c0
commit
6903ab87ca
|
@ -69,14 +69,14 @@ Fields["PWMCONF"] = {
|
||||||
Fields["PWM_SCALE"] = { "PWM_SCALE": 0xff }
|
Fields["PWM_SCALE"] = { "PWM_SCALE": 0xff }
|
||||||
Fields["LOST_STEPS"] = { "LOST_STEPS": 0xfffff }
|
Fields["LOST_STEPS"] = { "LOST_STEPS": 0xfffff }
|
||||||
|
|
||||||
|
SignedFields = ["CUR_A", "CUR_B", "sgt"]
|
||||||
|
|
||||||
FieldFormatters = {
|
FieldFormatters = {
|
||||||
"I_scale_analog": (lambda v: "1(ExtVREF)" if v else ""),
|
"I_scale_analog": (lambda v: "1(ExtVREF)" if v else ""),
|
||||||
"shaft": (lambda v: "1(Reverse)" if v else ""),
|
"shaft": (lambda v: "1(Reverse)" if v else ""),
|
||||||
"drv_err": (lambda v: "1(ErrorShutdown!)" if v else ""),
|
"drv_err": (lambda v: "1(ErrorShutdown!)" if v else ""),
|
||||||
"uv_cp": (lambda v: "1(Undervoltage!)" if v else ""),
|
"uv_cp": (lambda v: "1(Undervoltage!)" if v else ""),
|
||||||
"VERSION": (lambda v: "%#x" % v),
|
"VERSION": (lambda v: "%#x" % v),
|
||||||
"CUR_A": (lambda v: decode_signed_int(v, 9)),
|
|
||||||
"CUR_B": (lambda v: decode_signed_int(v, 9)),
|
|
||||||
"MRES": (lambda v: "%d(%dusteps)" % (v, 0x100 >> v)),
|
"MRES": (lambda v: "%d(%dusteps)" % (v, 0x100 >> v)),
|
||||||
"otpw": (lambda v: "1(OvertempWarning!)" if v else ""),
|
"otpw": (lambda v: "1(OvertempWarning!)" if v else ""),
|
||||||
"ot": (lambda v: "1(OvertempError!)" if v else ""),
|
"ot": (lambda v: "1(OvertempError!)" if v else ""),
|
||||||
|
@ -84,7 +84,6 @@ FieldFormatters = {
|
||||||
"s2gb": (lambda v: "1(ShortToGND_B!)" if v else ""),
|
"s2gb": (lambda v: "1(ShortToGND_B!)" if v else ""),
|
||||||
"ola": (lambda v: "1(OpenLoad_A!)" if v else ""),
|
"ola": (lambda v: "1(OpenLoad_A!)" if v else ""),
|
||||||
"olb": (lambda v: "1(OpenLoad_B!)" if v else ""),
|
"olb": (lambda v: "1(OpenLoad_B!)" if v else ""),
|
||||||
"sgt": (lambda v: decode_signed_int(v, 7)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,15 +95,11 @@ FieldFormatters = {
|
||||||
def ffs(mask):
|
def ffs(mask):
|
||||||
return (mask & -mask).bit_length() - 1
|
return (mask & -mask).bit_length() - 1
|
||||||
|
|
||||||
# Decode two's complement signed integer
|
|
||||||
def decode_signed_int(val, bits):
|
|
||||||
if ((val >> (bits - 1)) & 1):
|
|
||||||
return val - (1 << bits)
|
|
||||||
return val
|
|
||||||
|
|
||||||
class FieldHelper:
|
class FieldHelper:
|
||||||
def __init__(self, all_fields, field_formatters={}, registers=None):
|
def __init__(self, all_fields, signed_fields=[], field_formatters={},
|
||||||
|
registers=None):
|
||||||
self.all_fields = all_fields
|
self.all_fields = all_fields
|
||||||
|
self.signed_fields = {sf: 1 for sf in signed_fields}
|
||||||
self.field_formatters = field_formatters
|
self.field_formatters = field_formatters
|
||||||
self.registers = registers
|
self.registers = registers
|
||||||
if self.registers is None:
|
if self.registers is None:
|
||||||
|
@ -118,7 +113,10 @@ class FieldHelper:
|
||||||
if reg_value is None:
|
if reg_value is None:
|
||||||
reg_value = self.registers[reg_name]
|
reg_value = self.registers[reg_name]
|
||||||
mask = self.all_fields[reg_name][field_name]
|
mask = self.all_fields[reg_name][field_name]
|
||||||
return (reg_value & mask) >> ffs(mask)
|
field_value = (reg_value & mask) >> ffs(mask)
|
||||||
|
if field_name in self.signed_fields and ((reg_value & mask)<<1) > mask:
|
||||||
|
field_value -= (1 << field_value.bit_length())
|
||||||
|
return field_value
|
||||||
def set_field(self, field_name, field_value, reg_value=None, reg_name=None):
|
def set_field(self, field_name, field_value, reg_value=None, reg_name=None):
|
||||||
# Returns register value with field bits filled with supplied value
|
# Returns register value with field bits filled with supplied value
|
||||||
if reg_name is None:
|
if reg_name is None:
|
||||||
|
@ -138,20 +136,23 @@ class FieldHelper:
|
||||||
maxval = mask >> ffs(mask)
|
maxval = mask >> ffs(mask)
|
||||||
if maxval == 1:
|
if maxval == 1:
|
||||||
val = config.getboolean(config_name, default)
|
val = config.getboolean(config_name, default)
|
||||||
|
elif field_name in self.signed_fields:
|
||||||
|
val = config.getint(config_name, default,
|
||||||
|
minval=-(maxval//2 + 1), maxval=maxval//2)
|
||||||
else:
|
else:
|
||||||
val = config.getint(config_name, default, minval=0, maxval=maxval)
|
val = config.getint(config_name, default, minval=0, maxval=maxval)
|
||||||
return self.set_field(field_name, val)
|
return self.set_field(field_name, val)
|
||||||
def pretty_format(self, reg_name, value):
|
def pretty_format(self, reg_name, reg_value):
|
||||||
# Provide a string description of a register
|
# Provide a string description of a register
|
||||||
reg_fields = self.all_fields.get(reg_name, {})
|
reg_fields = self.all_fields.get(reg_name, {})
|
||||||
reg_fields = sorted([(mask, name) for name, mask in reg_fields.items()])
|
reg_fields = sorted([(mask, name) for name, mask in reg_fields.items()])
|
||||||
fields = []
|
fields = []
|
||||||
for mask, field_name in reg_fields:
|
for mask, field_name in reg_fields:
|
||||||
fval = (value & mask) >> ffs(mask)
|
field_value = self.get_field(field_name, reg_value, reg_name)
|
||||||
sval = self.field_formatters.get(field_name, str)(fval)
|
sval = self.field_formatters.get(field_name, str)(field_value)
|
||||||
if sval and sval != "0":
|
if sval and sval != "0":
|
||||||
fields.append(" %s=%s" % (field_name, sval))
|
fields.append(" %s=%s" % (field_name, sval))
|
||||||
return "%-11s %08x%s" % (reg_name + ":", value, "".join(fields))
|
return "%-11s %08x%s" % (reg_name + ":", reg_value, "".join(fields))
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -240,7 +241,8 @@ class TMC2130:
|
||||||
self.cmd_INIT_TMC, desc=self.cmd_INIT_TMC_help)
|
self.cmd_INIT_TMC, desc=self.cmd_INIT_TMC_help)
|
||||||
# Setup basic register values
|
# Setup basic register values
|
||||||
self.regs = collections.OrderedDict()
|
self.regs = collections.OrderedDict()
|
||||||
self.fields = FieldHelper(Fields, FieldFormatters, self.regs)
|
self.fields = FieldHelper(Fields, SignedFields, FieldFormatters,
|
||||||
|
self.regs)
|
||||||
vsense, irun, ihold, self.sense_resistor = get_config_current(config)
|
vsense, irun, ihold, self.sense_resistor = get_config_current(config)
|
||||||
self.fields.set_field("vsense", vsense)
|
self.fields.set_field("vsense", vsense)
|
||||||
self.fields.set_field("IHOLD", ihold)
|
self.fields.set_field("IHOLD", ihold)
|
||||||
|
@ -262,8 +264,7 @@ class TMC2130:
|
||||||
set_config_field(config, "PWM_GRAD", 4)
|
set_config_field(config, "PWM_GRAD", 4)
|
||||||
set_config_field(config, "pwm_freq", 1)
|
set_config_field(config, "pwm_freq", 1)
|
||||||
set_config_field(config, "pwm_autoscale", True)
|
set_config_field(config, "pwm_autoscale", True)
|
||||||
sgt = config.getint('driver_SGT', 0, minval=-64, maxval=63) & 0x7f
|
set_config_field(config, "sgt", 0)
|
||||||
self.fields.set_field("sgt", sgt)
|
|
||||||
self._init_registers()
|
self._init_registers()
|
||||||
def _init_registers(self, min_clock = 0):
|
def _init_registers(self, min_clock = 0):
|
||||||
# Send registers
|
# Send registers
|
||||||
|
|
|
@ -168,12 +168,13 @@ Fields["PWM_AUTO"] = {
|
||||||
"PWM_GRAD_AUTO": 0xff << 16
|
"PWM_GRAD_AUTO": 0xff << 16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SignedFields = ["CUR_A", "CUR_B", "PWM_SCALE_AUTO"]
|
||||||
|
|
||||||
FieldFormatters = dict(tmc2130.FieldFormatters)
|
FieldFormatters = dict(tmc2130.FieldFormatters)
|
||||||
FieldFormatters.update({
|
FieldFormatters.update({
|
||||||
"SEL_A": (lambda v: "%d(%s)" % (v, ["TMC222x", "TMC220x"][v])),
|
"SEL_A": (lambda v: "%d(%s)" % (v, ["TMC222x", "TMC220x"][v])),
|
||||||
"s2vsa": (lambda v: "1(LowSideShort_A!)" if v else ""),
|
"s2vsa": (lambda v: "1(LowSideShort_A!)" if v else ""),
|
||||||
"s2vsb": (lambda v: "1(LowSideShort_B!)" if v else ""),
|
"s2vsb": (lambda v: "1(LowSideShort_B!)" if v else ""),
|
||||||
"PWM_SCALE_AUTO": (lambda v: tmc2130.decode_signed_int(v, 9))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,7 +285,8 @@ class TMC2208:
|
||||||
# Setup basic register values
|
# Setup basic register values
|
||||||
self.ifcnt = None
|
self.ifcnt = None
|
||||||
self.regs = collections.OrderedDict()
|
self.regs = collections.OrderedDict()
|
||||||
self.fields = tmc2130.FieldHelper(Fields, FieldFormatters, self.regs)
|
self.fields = tmc2130.FieldHelper(Fields, SignedFields, FieldFormatters,
|
||||||
|
self.regs)
|
||||||
self.fields.set_field("pdn_disable", True)
|
self.fields.set_field("pdn_disable", True)
|
||||||
self.fields.set_field("mstep_reg_select", True)
|
self.fields.set_field("mstep_reg_select", True)
|
||||||
self.fields.set_field("multistep_filt", True)
|
self.fields.set_field("multistep_filt", True)
|
||||||
|
|
|
@ -104,6 +104,8 @@ Fields["READRSP@RDSEL2"] = {
|
||||||
"SE": 0x1f << 10
|
"SE": 0x1f << 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SignedFields = ["SGT"]
|
||||||
|
|
||||||
FieldFormatters = {
|
FieldFormatters = {
|
||||||
"MRES": (lambda v: "%d(%dusteps)" % (v, 0x100 >> v)),
|
"MRES": (lambda v: "%d(%dusteps)" % (v, 0x100 >> v)),
|
||||||
"DEDGE": (lambda v:
|
"DEDGE": (lambda v:
|
||||||
|
@ -111,7 +113,6 @@ FieldFormatters = {
|
||||||
"INTPOL": (lambda v: "1(On)" if v else "0(Off)"),
|
"INTPOL": (lambda v: "1(On)" if v else "0(Off)"),
|
||||||
"TOFF": (lambda v: ("%d" % v) if v else "0(Driver Disabled!)"),
|
"TOFF": (lambda v: ("%d" % v) if v else "0(Driver Disabled!)"),
|
||||||
"CHM": (lambda v: "1(constant toff)" if v else "0(spreadCycle)"),
|
"CHM": (lambda v: "1(constant toff)" if v else "0(spreadCycle)"),
|
||||||
"SGT": (lambda v: "%d" % (v)),
|
|
||||||
"SFILT": (lambda v: "1(Filtered mode)" if v else "0(Standard mode)"),
|
"SFILT": (lambda v: "1(Filtered mode)" if v else "0(Standard mode)"),
|
||||||
"VSENSE": (lambda v: "%d(%dmV)" % (v, 165 if v else 305)),
|
"VSENSE": (lambda v: "%d(%dmV)" % (v, 165 if v else 305)),
|
||||||
"SDOFF": (lambda v: "1(Step/Dir disabled" if v else "0(Step/dir enabled)"),
|
"SDOFF": (lambda v: "1(Step/Dir disabled" if v else "0(Step/dir enabled)"),
|
||||||
|
@ -150,7 +151,8 @@ class TMC2660:
|
||||||
self.cmd_INIT_TMC, desc=self.cmd_INIT_TMC_help)
|
self.cmd_INIT_TMC, desc=self.cmd_INIT_TMC_help)
|
||||||
# Setup driver registers
|
# Setup driver registers
|
||||||
self.regs = collections.OrderedDict()
|
self.regs = collections.OrderedDict()
|
||||||
self.fields = tmc2130.FieldHelper(Fields, FieldFormatters, self.regs)
|
self.fields = tmc2130.FieldHelper(Fields, SignedFields, FieldFormatters,
|
||||||
|
self.regs)
|
||||||
set_config_field = self.fields.set_config_field
|
set_config_field = self.fields.set_config_field
|
||||||
|
|
||||||
# DRVCTRL
|
# DRVCTRL
|
||||||
|
|
|
@ -211,8 +211,9 @@ fields["TSTEP"] = {
|
||||||
"TSTEP": 0xfffff << 0
|
"TSTEP": 0xfffff << 0
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldFormatters = dict(tmc2130.FieldFormatters)
|
SignedFields = ["CUR_A", "CUR_B", "sgt", "XACTUAL", "VACTUAL", "PWM_SCALE_AUTO"]
|
||||||
|
|
||||||
|
FieldFormatters = dict(tmc2130.FieldFormatters)
|
||||||
FieldFormatters.update({
|
FieldFormatters.update({
|
||||||
"reset": (lambda v: "1(reset)" if v else ""),
|
"reset": (lambda v: "1(reset)" if v else ""),
|
||||||
"drv_err": (lambda v: "1(ErrorShutdown!)" if v else ""),
|
"drv_err": (lambda v: "1(ErrorShutdown!)" if v else ""),
|
||||||
|
@ -274,7 +275,8 @@ class TMC5160:
|
||||||
self.cmd_INIT_TMC, desc=self.cmd_INIT_TMC_help)
|
self.cmd_INIT_TMC, desc=self.cmd_INIT_TMC_help)
|
||||||
# Setup basic register values
|
# Setup basic register values
|
||||||
self.regs = collections.OrderedDict()
|
self.regs = collections.OrderedDict()
|
||||||
self.fields = tmc2130.FieldHelper(fields, FieldFormatters, self.regs)
|
self.fields = tmc2130.FieldHelper(fields, SignedFields, FieldFormatters,
|
||||||
|
self.regs)
|
||||||
irun, ihold, self.sense_resistor = get_config_current(config)
|
irun, ihold, self.sense_resistor = get_config_current(config)
|
||||||
msteps, en_pwm, thresh = \
|
msteps, en_pwm, thresh = \
|
||||||
tmc2130.get_config_stealthchop(config, TMC_FREQUENCY)
|
tmc2130.get_config_stealthchop(config, TMC_FREQUENCY)
|
||||||
|
|
Loading…
Reference in New Issue