def closeSockets(self): """Allows you to manually close any sockets that may have been opened.""" try: self._socket.close() chipsLog.debug("Socket closed successfully.") except: chipsLog.warn("Error closing socket!")
def _blockOrFifoRead(self, name, depth, addrOffset, isFifo = False): """Common code for either a block read or a FIFO read.""" if depth <= 0: chipsLog.warn("Ignoring read with depth = 0 from register '" + name + "'!") return if depth > ChipsBus.MAX_BLOCK_TRANSFER_DEPTH: return self._oversizeBlockOrFifoRead(name, depth, addrOffset, isFifo) addrTableItem = self.addrTable.getItem(name) # Get the details of the relevant item from the addr table. if addrTableItem.getMask() != 0xffffffff: raise ChipsException("Block/FIFO read error: cannot perform block or FIFO read on a masked register address!") try: if not addrTableItem.getReadFlag(): raise ChipsException("Read transaction creation error: read is not allowed on register '" + addrTableItem.getName() + "'.") # create and run the transaction and get the response transaction = self._makeAndRunTransaction( [self._createReadTransactionElement(addrTableItem, depth, addrOffset, isFifo)] ) except ChipsException as err: raise ChipsException("Block/FIFO read error on register '" + name + "':\n\t" + str(err)) blockReadResponse = transaction.responses[-1] # Block read response will be last in list chipsLog.debug("Block/FIFO read success! Register '" + name + "' (addrOffset=0x" + uInt32HexStr(addrOffset) + ") was read successfully." ) return blockReadResponse.getBody().tolist()
def _blockOrFifoWrite(self, name, dataList, addrOffset, isFifo = False): """Common code for either a block write or a FIFO write.""" depth = len(dataList) addrTableItem = self.addrTable.getItem(name) # Get the details of the relevant item from the addr table. if addrTableItem.getMask() != 0xffffffff: raise ChipsException("Block/FIFO write error: cannot perform block or FIFO write on a masked register address!") if depth == 0: chipsLog.warn("Ignoring block/FIFO write to register '" + name + "': dataList is empty!"); return elif depth > ChipsBus.MAX_BLOCK_TRANSFER_DEPTH: return self._oversizeBlockOrFifoWrite(name, dataList, addrOffset, isFifo) try: if not addrTableItem.getWriteFlag(): raise ChipsException("Write transaction creation error: write is not allowed on register '" + addrTableItem.getName() + "'.") # create and run the transaction and get the response self._makeAndRunTransaction( [self._createWriteTransactionElement(addrTableItem, dataList, addrOffset, isFifo)] ) except ChipsException as err: raise ChipsException("Block/FIFO write error on register '" + name + "':\n\t" + str(err)) chipsLog.debug("Block/FIFO write success! " + str(depth) + " 32-bit words were written to '" + name + "' (addrOffset=0x" + uInt32HexStr(addrOffset) + ")")
def deserialise(self, packetPayloadString): '''Deserialises a packet payload ASCII string into list of transaction elements''' # 1) Unpack the string into unsigned integers try: rawU32Array = array('I', packetPayloadString) # Unpack string to an unsigned 32-bit array except Exception as err: raise ChipsException("Deserialisation error:\n\t" + str(err)) # 2) Debug output of the raw packet if chipsLog.level <= logging.DEBUG: msg = "\nRaw received packet content is:\n" for u32 in rawU32Array: msg += " 0x" + uInt32HexStr(u32) + "\n" chipsLog.debug(msg) # 3) Detect if we need to do a byte-reorder firstWord = rawU32Array[0] firstWordMasked = firstWord & 0xf00000f0 # This selects only the bits relevant for detecting the byte ordering if firstWordMasked == 0x200000f0: chipsLog.debug("Packet header detected: no byte-reorder is required.") elif firstWordMasked == 0xf0000020: chipsLog.debug("Packet header detected: a byte-reorder will be performed.") self._doByteReorder = True else: chipsLog.warn("Warning: No packet header (or unknown protocol version)! First word = 0x" + uInt32HexStr(firstWord) + ". Will hope for the best!...") # 4) Do the byte-reorder if necessary if self._doByteReorder: rawU32Array.byteswap() # 5) Now deserialise into a list of TransactionElements transactionElementList = [] # The list all the deserialised transaction elements will go into appendToTransactionElementList = transactionElementList.append # This is needed for a speed optimisation iU32 = 1 # Index for moving through the rawU32Array # TEMPORARY IPBUS V2.x HACK! Skip the first word which is now a packet ID rawU32ArraySize = len(rawU32Array) while iU32 < rawU32ArraySize: expectedBodySize = getExpectedBodySize(rawU32Array[iU32]) if rawU32ArraySize - iU32 - 1 - expectedBodySize < 0: raise ChipsException("Deserialisation error: packet not correctly formatted " \ "or does not contain the expected amount of data!") appendToTransactionElementList(TransactionElement(rawU32Array[iU32: iU32 + 1 + expectedBodySize])) iU32 += (1 + expectedBodySize) # 6) Debug output of deserialised packet content if chipsLog.level <= logging.DEBUG: msg = "\nDeserialised packet content is:\n" \ + reprTransactionElementList(transactionElementList) chipsLog.debug(msg) return transactionElementList
def _blockOrFifoRead(self, name, depth, addrOffset, isFifo = False): """Common code for either a block read or a FIFO read.""" if depth <= 0: chipsLog.warn("Ignoring read with depth = 0 from register '" + name + "'!") return if depth > ChipsBus.MAX_BLOCK_TRANSFER_DEPTH: return self._oversizeBlockOrFifoRead(name, depth, addrOffset, isFifo) addrTableItem = self.addrTable.getItem(name) # Get the details of the relevant item from the addr table. if addrTableItem.getMask() != 0xffffffff: raise ChipsException("Block/FIFO read error: cannot perform block or FIFO read on a masked register address!") try: if not addrTableItem.getReadFlag(): raise ChipsException("Read transaction creation error: read is not allowed on register '" + addrTableItem.getName() + "'.") # create and run the transaction and get the response transaction = self._makeAndRunTransaction( [self._createReadTransactionElement(addrTableItem, depth, addrOffset, isFifo)] ) except ChipsException, err: raise ChipsException("Block/FIFO read error on register '" + name + "':\n\t" + str(err))
def _blockOrFifoWrite(self, name, dataList, addrOffset, isFifo = False): """Common code for either a block write or a FIFO write.""" depth = len(dataList) addrTableItem = self.addrTable.getItem(name) # Get the details of the relevant item from the addr table. if addrTableItem.getMask() != 0xffffffff: raise ChipsException("Block/FIFO write error: cannot perform block or FIFO write on a masked register address!") if depth == 0: chipsLog.warn("Ignoring block/FIFO write to register '" + name + "': dataList is empty!"); return elif depth > ChipsBus.MAX_BLOCK_TRANSFER_DEPTH: return self._oversizeBlockOrFifoWrite(name, dataList, addrOffset, isFifo) try: if not addrTableItem.getWriteFlag(): raise ChipsException("Write transaction creation error: write is not allowed on register '" + addrTableItem.getName() + "'.") # create and run the transaction and get the response self._makeAndRunTransaction( [self._createWriteTransactionElement(addrTableItem, dataList, addrOffset, isFifo)] ) except ChipsException, err: raise ChipsException("Block/FIFO write error on register '" + name + "':\n\t" + str(err))
class SerDes(object): '''Class for serialising/deserialising IPbus transaction data Can serialise a list of TransactionElements into a string, or deserialise a string into a list of TransactionElements. The deserialisation stage checks the byte-ordering by looking for a byte-order header, and deals with the byte-reordering as appropriate. If a byte-reorder was required on the deserialisation stage, then the serialisation stage will also perform a reorder in order to respond correctly. Byte-reordering is off by default, as it's obviously a waste of CPU. ''' def __init__(self): '''Constructor - no arguments''' object.__init__(self) self._doByteReorder = False def serialise(self, transactionElementList): '''Serialises a list of transaction elements into an ASCII string for transmission''' if chipsLog.level <= logging.DEBUG: msg = "\nSerialising the following packet content:\n" msg += reprTransactionElementList(transactionElementList) chipsLog.debug(msg) allTransactionsArray = array( 'I', [0x200000f0] ) # TEMPORARY IPBUS V2.x HACK! Add a packet header of [0x200000f0] to the beginning of each packet. extendFunc = allTransactionsArray.extend for element in transactionElementList: extendFunc(element.getAll()) if self._doByteReorder: allTransactionsArray.byteswap() return allTransactionsArray.tostring() def deserialise(self, packetPayloadString): '''Deserialises a packet payload ASCII string into list of transaction elements''' # 1) Unpack the string into unsigned integers try: rawU32Array = array('I', packetPayloadString ) # Unpack string to an unsigned 32-bit array except Exception, err: raise ChipsException("Deserialisation error:\n\t" + str(err)) # 2) Debug output of the raw packet if chipsLog.level <= logging.DEBUG: msg = "\nRaw received packet content is:\n" for u32 in rawU32Array: msg += " 0x" + uInt32HexStr(u32) + "\n" chipsLog.debug(msg) # 3) Detect if we need to do a byte-reorder firstWord = rawU32Array[0] firstWordMasked = firstWord & 0xf00000f0 # This selects only the bits relevant for detecting the byte ordering if firstWordMasked == 0x200000f0: chipsLog.debug( "Packet header detected: no byte-reorder is required.") elif firstWordMasked == 0xf0000020: chipsLog.debug( "Packet header detected: a byte-reorder will be performed.") self._doByteReorder = True else: chipsLog.warn( "Warning: No packet header (or unknown protocol version)! First word = 0x" + uInt32HexStr(firstWord) + ". Will hope for the best!...") # 4) Do the byte-reorder if necessary if self._doByteReorder: rawU32Array.byteswap() # 5) Now deserialise into a list of TransactionElements transactionElementList = [ ] # The list all the deserialised transaction elements will go into appendToTransactionElementList = transactionElementList.append # This is needed for a speed optimisation iU32 = 1 # Index for moving through the rawU32Array # TEMPORARY IPBUS V2.x HACK! Skip the first word which is now a packet ID rawU32ArraySize = len(rawU32Array) while iU32 < rawU32ArraySize: expectedBodySize = getExpectedBodySize(rawU32Array[iU32]) if rawU32ArraySize - iU32 - 1 - expectedBodySize < 0: raise ChipsException("Deserialisation error: packet not correctly formatted " \ "or does not contain the expected amount of data!") appendToTransactionElementList( TransactionElement(rawU32Array[iU32:iU32 + 1 + expectedBodySize])) iU32 += (1 + expectedBodySize) # 6) Debug output of deserialised packet content if chipsLog.level <= logging.DEBUG: msg = "\nDeserialised packet content is:\n" \ + reprTransactionElementList(transactionElementList) chipsLog.debug(msg) return transactionElementList