diff --git a/canopen/objectdictionary/eds.py b/canopen/objectdictionary/eds.py index d47a3019..1967b22e 100644 --- a/canopen/objectdictionary/eds.py +++ b/canopen/objectdictionary/eds.py @@ -204,19 +204,16 @@ def import_from_node(node_id: int, network: canopen.network.Network): return od -def _calc_bit_length(data_type): - if data_type == datatypes.INTEGER8: - return 8 - elif data_type == datatypes.INTEGER16: - return 16 - elif data_type == datatypes.INTEGER32: - return 32 - elif data_type == datatypes.INTEGER64: - return 64 - else: - raise ValueError( - f"Invalid data_type '{data_type}', expecting a signed integer data_type." - ) +_SIGNED_BIT_LENGTHS = { + datatypes.INTEGER8: 8, + datatypes.INTEGER16: 16, + datatypes.INTEGER24: 24, + datatypes.INTEGER32: 32, + datatypes.INTEGER40: 40, + datatypes.INTEGER48: 48, + datatypes.INTEGER56: 56, + datatypes.INTEGER64: 64, +} def _signed_int_from_hex(hex_str, bit_length): @@ -305,7 +302,7 @@ def build_variable( try: min_string = eds.get(section, "LowLimit") if var.data_type in datatypes.SIGNED_TYPES: - var.min = _signed_int_from_hex(min_string, _calc_bit_length(var.data_type)) + var.min = _signed_int_from_hex(min_string, _SIGNED_BIT_LENGTHS[var.data_type]) else: var.min = int(min_string, 0) except ValueError: @@ -314,7 +311,7 @@ def build_variable( try: max_string = eds.get(section, "HighLimit") if var.data_type in datatypes.SIGNED_TYPES: - var.max = _signed_int_from_hex(max_string, _calc_bit_length(var.data_type)) + var.max = _signed_int_from_hex(max_string, _SIGNED_BIT_LENGTHS[var.data_type]) else: var.max = int(max_string, 0) except ValueError: diff --git a/test/sample.eds b/test/sample.eds index ad00a12e..49c95ce7 100644 --- a/test/sample.eds +++ b/test/sample.eds @@ -976,6 +976,42 @@ HighLimit=0xFFFFFFFF LowLimit=0x80000000 PDOMapping=0 +[3031] +ParameterName=INTEGER24 value range -1 to 0 +ObjectType=0x7 +DataType=0x10 +AccessType=rw +HighLimit=0x000000 +LowLimit=0xFFFFFF +PDOMapping=0 + +[3032] +ParameterName=INTEGER40 value range -1 to 0 +ObjectType=0x7 +DataType=0x12 +AccessType=rw +HighLimit=0x0000000000 +LowLimit=0xFFFFFFFFFF +PDOMapping=0 + +[3033] +ParameterName=INTEGER48 value range -1 to 0 +ObjectType=0x7 +DataType=0x13 +AccessType=rw +HighLimit=0x000000000000 +LowLimit=0xFFFFFFFFFFFF +PDOMapping=0 + +[3034] +ParameterName=INTEGER56 value range -1 to 0 +ObjectType=0x7 +DataType=0x14 +AccessType=rw +HighLimit=0x00000000000000 +LowLimit=0xFFFFFFFFFFFFFF +PDOMapping=0 + [3040] ParameterName=INTEGER64 value range -10 to +10 ObjectType=0x7 diff --git a/test/test_eds.py b/test/test_eds.py index 7a19ffeb..ab7cf613 100644 --- a/test/test_eds.py +++ b/test/test_eds.py @@ -148,6 +148,11 @@ def test_record_with_limits(self): int64 = self.od[0x3040] self.assertEqual(int64.min, -10) self.assertEqual(int64.max, +10) + # Verify all remaining SIGNED_TYPES are handled (INTEGER24/40/48/56) + for index in (0x3031, 0x3032, 0x3033, 0x3034): + var = self.od[index] + self.assertEqual(var.min, -1, f"min mismatch at 0x{index:04X}") + self.assertEqual(var.max, 0, f"max mismatch at 0x{index:04X}") def test_signed_int_from_hex(self): for data_type, test_cases in self.test_data.items():