From c87f1cceb66916f3653b159610eb8235035ba922 Mon Sep 17 00:00:00 2001 From: Sven Sager Date: Tue, 31 Oct 2023 17:29:22 +0100 Subject: [PATCH] fix: Check if the length of the previous IO overlaps with the new IO When applying the PiCtory configuration, all IOs are now checked to see if they overlap with the previous ones. If an overlap is detected, the IO is ignored and a warning is given to the user. Signed-off-by: Sven Sager --- src/revpimodio2/io.py | 50 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/revpimodio2/io.py b/src/revpimodio2/io.py index 262283c..b78dfd7 100644 --- a/src/revpimodio2/io.py +++ b/src/revpimodio2/io.py @@ -5,6 +5,7 @@ __copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "LGPLv2" import struct +import warnings from re import match as rematch from threading import Event @@ -242,11 +243,10 @@ class IOList(object): "attribute {0} already exists - can not set io".format(new_io._name) ) - if type(new_io) is StructIO: + do_replace = type(new_io) is StructIO + if do_replace: self.__private_replace_oldio_with_newio(new_io) - object.__setattr__(self, new_io._name, new_io) - # Bytedict für Adresszugriff anpassen if new_io._bitshift: if len(self.__dict_iobyte[new_io.address]) != 8: @@ -261,10 +261,54 @@ class IOList(object): None, None, ] + # Check for overlapping IOs + if ( + not do_replace + and self.__dict_iobyte[new_io.address][new_io._bitaddress] is not None + ): + warnings.warn( + "ignore io '{0}', as an io already exists at the address '{1} Bit {2}'. " + "this can be caused by an incorrect pictory configuration.".format( + new_io.name, + new_io.address, + new_io._bitaddress, + ), + Warning, + ) + return + self.__dict_iobyte[new_io.address][new_io._bitaddress] = new_io else: + # Search the previous IO to calculate the length + offset_end = new_io.address + search_index = new_io.address + while search_index >= 0: + previous_io = self.__dict_iobyte[search_index] + if len(previous_io) == 8: + # Bits on this address are always 1 byte + offset_end -= 1 + elif len(previous_io) == 1: + # Found IO, calculate offset + length of IO + offset_end = previous_io[0].address + previous_io[0].length + break + search_index -= 1 + + # Check if the length of the previous IO overlaps with the new IO + if offset_end > new_io.address: + warnings.warn( + "ignore io '{0}', as an io already exists at the address '{1}'. " + "this can be caused by an incorrect pictory configuration.".format( + new_io.name, + new_io.address, + ), + Warning, + ) + return + self.__dict_iobyte[new_io.address].append(new_io) + object.__setattr__(self, new_io._name, new_io) + if type(new_io) is StructIO: new_io._parentdevice._update_my_io_list() else: