def _handleGetReservedAddrInfoRequest(self, request): chipsLog.debug("Reserved Address Info transaction requested") # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode(request.getHeader(), IPbusHeader.INFO_CODE_RESPONSE) responseHeader = IPbusHeader.updateWords(responseHeader, 2) # Returning zeros for the response body, as no real idea what else it should be. return TransactionElement.makeFromHeaderAndBody(responseHeader, [0,0])
def _handleReadRequest(self, request): requestHeader = request.getHeader() words = IPbusHeader.getWords(requestHeader) baseAddr = request.getBody()[0] chipsLog.debug("Read requested on Addr=0x" + uInt32HexStr(baseAddr)) # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode( requestHeader, IPbusHeader.INFO_CODE_RESPONSE) # The (baseAddr & 0xffffffff) forces baseAddr to be in unsigned form (i.e. 0xfffffffc, say, rather than -4) if ( baseAddr & 0xffffffff ) == 0xffffffff: # A read on this register is a Dummy Hardware Reset Request. chipsLog.info( "** Dummy Hardware reset request received! Zeroing all registers. **" ) self._registers.clear() responseBody = [] appendToResponseBody = responseBody.append # This is for a speed optimisation for offset in range(words): currentReg = baseAddr + offset # Create these registers if they don't already exist. if currentReg not in self._registers: self._registers[currentReg] = 0 appendToResponseBody(self._registers[currentReg]) return TransactionElement.makeFromHeaderAndBody( responseHeader, responseBody)
def _handleGetReservedAddrInfoRequest(self, request): chipsLog.debug("Reserved Address Info transaction requested") # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode( request.getHeader(), IPbusHeader.INFO_CODE_RESPONSE) responseHeader = IPbusHeader.updateWords(responseHeader, 2) # Returning zeros for the response body, as no real idea what else it should be. return TransactionElement.makeFromHeaderAndBody(responseHeader, [0, 0])
def _handleWriteRequest(self, request): requestHeader = request.getHeader() words = IPbusHeader.getWords(requestHeader) requestBody = request.getBody() baseAddr = requestBody[0] chipsLog.debug("Write requested on Addr=0x" + uInt32HexStr(baseAddr)) # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode(requestHeader, IPbusHeader.INFO_CODE_RESPONSE) for offset in range(words): currentReg = baseAddr + offset self._registers[currentReg] = requestBody[offset + 1] return TransactionElement.makeFromHeaderAndBody(responseHeader)
def _handleWriteRequest(self, request): requestHeader = request.getHeader() words = IPbusHeader.getWords(requestHeader) requestBody = request.getBody() baseAddr = requestBody[0] chipsLog.debug("Write requested on Addr=0x" + uInt32HexStr(baseAddr)) # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(requestHeader, 1) for offset in range(words): currentReg = baseAddr + offset self._registers[currentReg] = requestBody[offset + 1] return TransactionElement.makeFromHeaderAndBody(responseHeader)
def _handleWriteRequest(self, request): requestHeader = request.getHeader() words = IPbusHeader.getWords(requestHeader) requestBody = request.getBody() baseAddr = requestBody[0] chipsLog.debug("Write requested on Addr=0x" + uInt32HexStr(baseAddr)) # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode( requestHeader, IPbusHeader.INFO_CODE_RESPONSE) for offset in range(words): currentReg = baseAddr + offset self._registers[currentReg] = requestBody[offset + 1] return TransactionElement.makeFromHeaderAndBody(responseHeader)
def _createWriteTransactionElement(self, addrTableItem, dataList, addrOffset=0, isFifo=False): """Returns a Write Request transaction element (i.e. unmasked/block write) addrTableItem: The relevant address table item you want to perform the write transaction on. dataList: The list of 32-bit numbers you want to write (the list size defines the write depth) addrOffset: The offset on the address specified within the address table item, default is 0. isFifo: False gives a normal write transaction; True gives a non-incrementing write transaction (i.e. same addr many times). """ for value in dataList: if not uInt32Compatible(value): raise ChipsException("Write transaction creation error: cannot create a write transaction with data " \ "values (" + hex(value) +") that are not valid 32-bit unsigned integers!") typeId = IPbusHeader.TYPE_ID_WRITE if isFifo: typeId = IPbusHeader.TYPE_ID_NON_INCR_WRITE writeHeader = IPbusHeader.makeHeader(ChipsBusBase.IPBUS_PROTOCOL_VER, self._getTransactionId(), len(dataList), typeId, IPbusHeader.INFO_CODE_REQUEST) writeBody = [addrTableItem.getAddress() + addrOffset] + dataList return TransactionElement.makeFromHeaderAndBody(writeHeader, writeBody)
def _createByteOrderTransactionElement(self): """Returns a Byte-Order Request transaction element. Note: Byte-order transactions will always and exclusively have transactionId = 0. """ byteOrderHeader = IPbusHeader.makeHeader(ChipsBusBase.IPBUS_PROTOCOL_VER, 0, 0, IPbusHeader.TYPE_ID_BYTE_ORDER, 0, 0) return TransactionElement.makeFromHeaderAndBody(byteOrderHeader)
def _handleFifoReadRequest(self, request): requestHeader = request.getHeader() words = IPbusHeader.getWords(requestHeader) fifoAddr = request.getBody()[0] chipsLog.debug("FIFO read requested on Addr=0x" + uInt32HexStr(fifoAddr)) # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(requestHeader, 1) # Create the register if they don't already exist in our memory space if fifoAddr not in self._registers: self._registers[fifoAddr] = 0 # Obviously we don't really have a FIFO, so we'll just have to return the value stored # at the FIFO's address many times... value = self._registers[fifoAddr] responseBody = [value for iReads in range(words)] return TransactionElement.makeFromHeaderAndBody(responseHeader, responseBody)
def _handleFifoReadRequest(self, request): requestHeader = request.getHeader() words = IPbusHeader.getWords(requestHeader) fifoAddr = request.getBody()[0] chipsLog.debug("FIFO read requested on Addr=0x" + uInt32HexStr(fifoAddr)) # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode( requestHeader, IPbusHeader.INFO_CODE_RESPONSE) # Create the register if they don't already exist in our memory space if fifoAddr not in self._registers: self._registers[fifoAddr] = 0 # Obviously we don't really have a FIFO, so we'll just have to return the value stored # at the FIFO's address many times... value = self._registers[fifoAddr] responseBody = [value for iReads in range(words)] return TransactionElement.makeFromHeaderAndBody( responseHeader, responseBody)
def _createReadTransactionElement(self, addrTableItem, readDepth = 1, addrOffset = 0, isFifo = False): """Returns a Read Request transaction element addrTableItem: The relevant address table item you want to perform the write transaction on. readDepth: The depth of the read; default is 1, which would be a single 32-bit register read. addrOffset: The offset on the address specified within the address table item, default is 0. isFifo: False gives a normal read transaction; True gives a non-incrementing read transaction (i.e. same addr many times). """ typeId = IPbusHeader.TYPE_ID_READ if isFifo: typeId = IPbusHeader.TYPE_ID_NON_INCR_READ readHeader = IPbusHeader.makeHeader(ChipsBusBase.IPBUS_PROTOCOL_VER, self._getTransactionId(), readDepth, typeId, IPbusHeader.INFO_CODE_REQUEST) readBody = [addrTableItem.getAddress() + addrOffset] return TransactionElement.makeFromHeaderAndBody(readHeader, readBody)
def _handleReadRequest(self, request): requestHeader = request.getHeader() words = IPbusHeader.getWords(requestHeader) baseAddr = request.getBody()[0] chipsLog.debug("Read requested on Addr=0x" + uInt32HexStr(baseAddr)) # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(requestHeader, 1) # The (baseAddr & 0xffffffff) forces baseAddr to be in unsigned form (i.e. 0xfffffffc, say, rather than -4) if (baseAddr & 0xffffffff) == 0xffffffff: # A read on this register is a Dummy Hardware Reset Request. chipsLog.info("** Dummy Hardware reset request received! Zeroing all registers. **") self._registers.clear() responseBody = [] appendToResponseBody = responseBody.append # This is for a speed optimisation for offset in range(words): currentReg = baseAddr + offset # Create these registers if they don't already exist. if currentReg not in self._registers: self._registers[currentReg] = 0 appendToResponseBody(self._registers[currentReg]) return TransactionElement.makeFromHeaderAndBody(responseHeader, responseBody)
def _handleFifoWriteRequest(self, request): requestHeader = request.getHeader() requestBody = request.getBody() fifoAddr = requestBody[0] chipsLog.debug("FIFO write requested on Addr=0x" + uInt32HexStr(fifoAddr)) # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(requestHeader, 1) # Obviously we don't really have a FIFO, we just have a single register at the address of the supposed # FIFO. So, whatever the last value written into the FIFO is, this will be the value this register will # take. We ignore all the previous "writes" to the FIFO. self._registers[fifoAddr] = requestBody[-1] return TransactionElement.makeFromHeaderAndBody(responseHeader)
def _handleReadModifyWriteSumRequest(self, request): requestBody = request.getBody() addr = requestBody[0] addend = requestBody[1] # The value we add to the existing value chipsLog.debug("Read/Modify/Write-sum requested on Addr=0x" + uInt32HexStr(addr)) # Create the register if it doesn't already exist. if addr not in self._registers: self._registers[addr] = 0 updatedValue = (self._registers[addr] + addend) & 0xffffffff self._registers[addr] = updatedValue # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(request.getHeader(), 1) return TransactionElement.makeFromHeaderAndBody(responseHeader, [updatedValue])
def _handleFifoWriteRequest(self, request): requestHeader = request.getHeader() requestBody = request.getBody() fifoAddr = requestBody[0] chipsLog.debug("FIFO write requested on Addr=0x" + uInt32HexStr(fifoAddr)) # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode( requestHeader, IPbusHeader.INFO_CODE_RESPONSE) # Obviously we don't really have a FIFO, we just have a single register at the address of the supposed # FIFO. So, whatever the last value written into the FIFO is, this will be the value this register will # take. We ignore all the previous "writes" to the FIFO. self._registers[fifoAddr] = requestBody[-1] return TransactionElement.makeFromHeaderAndBody(responseHeader)
def _handleReadModifyWriteBitsRequest(self, request): requestBody = request.getBody() addr = requestBody[0] andTerm = requestBody[1] # The and term is the bitwise complement of the register mask (i.e. mask = ~andTerm) orTerm = requestBody[2] chipsLog.debug("Read/Modify/Write-bits requested on Addr=0x" + uInt32HexStr(addr)) # Create the register if it doesn't already exist. if addr not in self._registers: self._registers[addr] = 0 updatedValue = (self._registers[addr] & andTerm) | (orTerm) self._registers[addr] = updatedValue # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(request.getHeader(), 1) return TransactionElement.makeFromHeaderAndBody(responseHeader, [updatedValue])
def _createRMWBitsTransactionElement(self, addrTableItem, dataU32, addrOffset = 0): """Returns a Read/Modify/Write Bits Request transaction element (i.e. masked write) addrTableItem: The relevant address table item you want to perform the RMWBits transaction on. dataU32: The data (32 bits max, or equal in width to the bit-mask). addrOffset: The offset on the address specified within the address table item, default is 0. """ if not uInt32Compatible(dataU32): raise ChipsException("Read-Modify-Write Bits transaction creation error: cannot create a RMW-bits " \ "transaction with data values (" + hex(dataU32) +") that are not valid 32-bit " \ "unsigned integers!") rmwHeader = IPbusHeader.makeHeader(ChipsBus.IPBUS_PROTOCOL_VER, self._getTransactionId(), 1, IPbusHeader.TYPE_ID_RMW_BITS, IPbusHeader.INFO_CODE_REQUEST) rmwBody = [addrTableItem.getAddress() + addrOffset, \ uInt32BitFlip(addrTableItem.getMask()), \ addrTableItem.shiftDataToMask(dataU32)] return TransactionElement.makeFromHeaderAndBody(rmwHeader, rmwBody)
def _createWriteTransactionElement(self, addrTableItem, dataList, addrOffset = 0, isFifo = False): """Returns a Write Request transaction element (i.e. unmasked/block write) addrTableItem: The relevant address table item you want to perform the write transaction on. dataList: The list of 32-bit numbers you want to write (the list size defines the write depth) addrOffset: The offset on the address specified within the address table item, default is 0. isFifo: False gives a normal write transaction; True gives a non-incrementing write transaction (i.e. same addr many times). """ for value in dataList: if not uInt32Compatible(value): raise ChipsException("Write transaction creation error: cannot create a write transaction with data " \ "values (" + hex(value) +") that are not valid 32-bit unsigned integers!") typeId = IPbusHeader.TYPE_ID_WRITE if isFifo: typeId = IPbusHeader.TYPE_ID_NON_INCR_WRITE writeHeader = IPbusHeader.makeHeader(ChipsBusBase.IPBUS_PROTOCOL_VER, self._getTransactionId(), len(dataList), typeId, IPbusHeader.INFO_CODE_REQUEST) writeBody = [addrTableItem.getAddress() + addrOffset] + dataList return TransactionElement.makeFromHeaderAndBody(writeHeader, writeBody)
def _actAndRespond(self, transaction): """Performs the required action and returns the response for a given transaction""" self._transactionCounter += 1 chipsLog.debug("*** Performing transaction #" + str(self._transactionCounter) + " ***") try: transaction.deserialiseRequests() for request in transaction.requests: transaction.appendResponse(self._requestTypeHandlerMap[IPbusHeader.getTypeId(request.getHeader())](request)) transaction.serialiseResponses() chipsLog.debug("Sending response packet") self._socketSend(transaction) chipsLog.debug("Response packet sent!") chipsLog.debug("*** Transaction #" + str(self._transactionCounter) + " completed! ***\n") except ChipsException, err: chipsLog.error("ERROR! Transaction #" + str(self._transactionCounter) + " could not be successfully processed:\n\t" + str(err))
def _handleReadModifyWriteSumRequest(self, request): requestBody = request.getBody() addr = requestBody[0] addend = requestBody[1] # The value we add to the existing value chipsLog.debug("Read/Modify/Write-sum requested on Addr=0x" + uInt32HexStr(addr)) # Create the register if it doesn't already exist. if addr not in self._registers: self._registers[addr] = 0 updatedValue = (self._registers[addr] + addend) & 0xffffffff self._registers[addr] = updatedValue # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode( request.getHeader(), IPbusHeader.INFO_CODE_RESPONSE) return TransactionElement.makeFromHeaderAndBody( responseHeader, [updatedValue])
def _handleReadModifyWriteBitsRequest(self, request): requestBody = request.getBody() addr = requestBody[0] andTerm = requestBody[ 1] # The and term is the bitwise complement of the register mask (i.e. mask = ~andTerm) orTerm = requestBody[2] chipsLog.debug("Read/Modify/Write-bits requested on Addr=0x" + uInt32HexStr(addr)) # Create the register if it doesn't already exist. if addr not in self._registers: self._registers[addr] = 0 updatedValue = (self._registers[addr] & andTerm) | (orTerm) self._registers[addr] = updatedValue # Response header is the request header but with the Info Code field changed to INFO_CODE_RESPONSE responseHeader = IPbusHeader.updateInfoCode( request.getHeader(), IPbusHeader.INFO_CODE_RESPONSE) return TransactionElement.makeFromHeaderAndBody( responseHeader, [updatedValue])
def _actAndRespond(self, transaction): """Performs the required action and returns the response for a given transaction""" self._transactionCounter += 1 chipsLog.debug("*** Performing transaction #" + str(self._transactionCounter) + " ***") try: transaction.deserialiseRequests() for request in transaction.requests: transaction.appendResponse( self._requestTypeHandlerMap[IPbusHeader.getTypeId( request.getHeader())](request)) transaction.serialiseResponses() chipsLog.debug("Sending response packet") self._socketSend(transaction) chipsLog.debug("Response packet sent!") chipsLog.debug("*** Transaction #" + str(self._transactionCounter) + " completed! ***\n") except ChipsException, err: chipsLog.error("ERROR! Transaction #" + str(self._transactionCounter) + " could not be successfully processed:\n\t" + str(err))
def _handleByteOrderRequest(self, request): chipsLog.debug("Byte-order transaction requested") # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(request.getHeader(), 1) return TransactionElement.makeFromHeaderAndBody(responseHeader)
def _handleGetReservedAddrInfoRequest(self, request): # Response header is the request header with direction bit changed responseHeader = IPbusHeader.updateDirection(request.getHeader(), 1) responseHeader = IPbusHeader.updateWords(responseHeader, 2) # Returning zeros for the response body, as no real idea what else it should be. return TransactionElement.makeFromHeaderAndBody(responseHeader, [0,0])
def validBodySize(self): '''Returns true/false if the current body size matches the size inferred by the header.''' return (len(self._rawData) - 1) == IPbusHeader.getExpectedBodySize(self.getHeader())
def validBodySize(self): """Returns true/false if the current body size matches the size inferred by the header.""" return (len(self._rawData) - 1) == IPbusHeader.getExpectedBodySize(self.getHeader())