def __init__(self, name="DataFromFile", description="Data from file source", **kwargs): pyrogue.Device.__init__(self, name=name, description=description, **kwargs) self._data_master = DataMaster() self.add( pyrogue.LocalVariable(name='FileName', description='Path to the data file', mode='RW', value='/tmp/fw/x.dat')) self.add( pyrogue.LocalVariable(name='FrameCnt', description='Number of sent frames', mode='RO', value=0, localGet=self._data_master.get_frame_cnt)) self.add( pyrogue.LocalCommand(name='SendData', description='Send data', function=self._send_data))
def _decorator(func): if 'name' not in kwargs: kwargs['name'] = func.__name__ self.add(pr.LocalCommand(function=func, **kwargs)) return func
def __init__(self, name="myDevice", description='My device', **kargs): super().__init__(name=name, description=description, **kargs) # This command calls _DelayFunction in the foreground self.add( pyrogue.LocalCommand( name='cmd_fg', description='Command running in the foreground', function=self._DelayFunction)) # This command calls _DelayFunction in the background self.add( pyrogue.LocalCommand( name='cmd_bg', description='Command running in the background', background=True, function=self._DelayFunction))
def __init__(self, name="AppCore", description="AMC Carrier Cryo Demo Board Application", offset=0x00000000, numRxLanes=[0, 0], numTxLanes=[0, 0], **kwargs): super().__init__(name=name, description=description, offset=offset, **kwargs) self._numRxLanes = numRxLanes self._numTxLanes = numTxLanes self.add( pr.LocalCommand(name='Init', description='Init', function=self.init)) self.add( pr.LocalCommand(name='Disable', description='Disable', function=self.disable))
def __init__(self, **kwargs): pyrogue.Device.__init__(self, **kwargs) self._reader = rogue.utilities.fileio.StreamReader() self.add( pyrogue.LocalVariable(name='DataFile', description='Data File', mode='RW', value='')) self.add( pyrogue.LocalCommand(name='Open', function=self._open, description='Open data file.')) self.add( pyrogue.LocalCommand(name='Close', function=self._close, description='Close data file.')) self.add( pyrogue.LocalVariable(name='isOpen', function=self._isOpen, description='Data file is open.'))
def __init__(self, name="DataToFile", description="Data to file writer", **kwargs): pyrogue.Device.__init__(self, name=name, description=description, **kwargs) self._data_slave = DataSlave() self._meta_slave = MetaSlave() self.add(pyrogue.LocalVariable( name='FileName', description='Path to the data file', mode='RW', value='/tmp/fw/y.dat')) self.add(pyrogue.LocalCommand( name='WriteData', description='Write data to disk', function=self._write_data))
def __init__(self, *, name, description, maxDepth=0, trimSize=0, noCopy=False, **kwargs): pyrogue.Device.__init__(self, name=name, description=description, **kwargs) self._fifo = rogue.interfaces.stream.Fifo(maxDepth, trimSize, noCopy) # Maximum Depth self.add( pyrogue.LocalVariable(name='MaxDepth', description='Maximum depth of the Fifo', mode='RO', value=maxDepth)) # Number of elements in the Fifo self.add( pyrogue.LocalVariable(name='Size', description='Number of elements in the Fifo', mode='RO', value=0, typeStr='UInt64', pollInterval=1, localGet=self._fifo.size)) # Number of dropped frames self.add( pyrogue.LocalVariable(name='FrameDropCnt', description='Number of dropped frames', mode='RO', value=0, typeStr='UInt64', pollInterval=1, localGet=self._fifo.dropCnt)) # Command to clear all the counters self.add( pyrogue.LocalCommand(name='ClearCnt', description='Clear all counters', function=self._fifo.clearCnt))
def __init__(self, **kwargs): super().__init__(**kwargs) self.addRemoteVariables( name='Regs', description='Registers', offset=(0 << 2), bitSize=8, mode='RW', number=256, stride=4, verify=False, # hidden = True, hidden=False) self.add( pr.LocalCommand(name='program', description='[119MHz, 185.7MHz]', function=self._program))
def __init__(self, name, device, **kwargs): pyrogue.Device.__init__(self, name=name, description='SMuRF Data Unwrapper', **kwargs) self.device = device # Add "Disable" variable self.add( pyrogue.LocalVariable( name='Disable', description= 'Disable the processing block. Data will just pass thorough to the next slave.', mode='RW', value=False, localSet=lambda value: self.device.setUnwrapperDisable(value), localGet=self.device.getUnwrapperDisable)) # Command to reset the unwrapper self.add( pyrogue.LocalCommand(name='reset', description='Reset the unwrapper', function=self.device.resetUnwrapper))
def __init__(self, name, **kwargs): pyrogue.Device.__init__(self, name=name, description='SMuRF Data BaseTransmitter', **kwargs) self._transmitter = smurf.core.transmitters.BaseTransmitter() # Add "Disable" variable self.add(pyrogue.LocalVariable( name='Disable', description='Disable the processing block. Data will just pass thorough to the next slave.', mode='RW', value=False, localSet=lambda value: self._transmitter.setDisable(value), localGet=self._transmitter.getDisable)) # Add the data dropped counter variable self.add(pyrogue.LocalVariable( name='dataDropCnt', description='Number of data frame dropped', mode='RO', value=0, pollInterval=1, localGet=self._transmitter.getDataDropCnt)) # Add the metaData dropped counter variable self.add(pyrogue.LocalVariable( name='metaDropCnt', description='Number of metadata frame dropped', mode='RO', value=0, pollInterval=1, localGet=self._transmitter.getMetaDropCnt)) # Command to clear all the counters self.add(pyrogue.LocalCommand( name='clearCnt', description='Clear all counters', function=self._transmitter.clearCnt))
def __init__( self, *, config_file=None, epics_prefix="EpicsPrefix", polling_en=True, pv_dump_file=None, txDevice=None, fpgaTopLevel=None, stream_pv_size=2**19, # Not sub-classed stream_pv_type='Int16', # Not sub-classed configure=False, VariableGroups=None, server_port=0, **kwargs): pyrogue.Root.__init__(self, name="AMCc", initRead=True, pollEn=polling_en, streamIncGroups='stream', serverPort=server_port, **kwargs) ######################################################################################### # The following interfaces are expected to be defined at this point by a sub-class # self._streaming_stream # Data stream interface # self._ddr_streams # 4 DDR Interface Streams # self._fpga = Top level FPGA # Add PySmurf Application Block self.add(pysmurf.core.devices.SmurfApplication()) # Add FPGA self.add(self._fpga) # File writer for streaming interfaces # DDR interface (TDEST 0x80 - 0x87) self._stm_data_writer = pyrogue.utilities.fileio.StreamWriter( name='streamDataWriter') self.add(self._stm_data_writer) # Streaming interface (TDEST 0xC0 - 0xC7) self._stm_interface_writer = pyrogue.utilities.fileio.StreamWriter( name='streamingInterface') self.add(self._stm_interface_writer) # Add the SMuRF processor device self._smurf_processor = pysmurf.core.devices.SmurfProcessor( name="SmurfProcessor", description="Process the SMuRF Streaming Data Stream", root=self, txDevice=txDevice) self.add(self._smurf_processor) # Connect smurf processor pyrogue.streamConnect(self._streaming_stream, self._smurf_processor) # Add data streams (0-3) to file channels (0-3) for i in range(4): ## DDR streams pyrogue.streamConnect(self._ddr_streams[i], self._stm_data_writer.getChannel(i)) ## Streaming interface streams # We have already connected TDEST 0xC1 to the smurf_processor receiver, # so we need to tapping it to the data writer. pyrogue.streamTap(self._streaming_stream, self._stm_interface_writer.getChannel(0)) # TES Bias Update Function # smurf_processor bias index 0 = TesBiasDacDataRegCh[2] - TesBiasDacDataRegCh[1] # smurf_processor bias index l = TesBiasDacDataRegCh[4] - TesBiasDacDataRegCh[3] def _update_tes_bias(idx): v1 = self.FpgaTopLevel.AppTop.AppCore.RtmCryoDet.RtmSpiMax.node( f'TesBiasDacDataRegCh[{(2*idx)+2}]').value() v2 = self.FpgaTopLevel.AppTop.AppCore.RtmCryoDet.RtmSpiMax.node( f'TesBiasDacDataRegCh[{(2*idx)+1}]').value() val = (v1 - v2) // 2 # Pass to data processor self._smurf_processor.setTesBias(index=idx, val=val) # Register TesBias values configuration to update stream processor # Bias values are ranged 1 - 32, matching tes bias indexes 0 - 16 for i in range(1, 33): idx = (i - 1) // 2 try: v = self.FpgaTopLevel.AppTop.AppCore.RtmCryoDet.RtmSpiMax.node( f'TesBiasDacDataRegCh[{i}]') v.addListener( lambda path, value, lidx=idx: _update_tes_bias(lidx)) except Exception: print(f"TesBiasDacDataRegCh[{i}] not found... Skipping!") # Run control for streaming interfaces self.add( pyrogue.RunControl(name='streamRunControl', description='Run controller', cmd=self._fpga.SwDaqMuxTrig, rates={ 1: '1 Hz', 10: '10 Hz', 30: '30 Hz' })) # lcaPut limits the maximun lenght of a string to 40 chars, as defined # in the EPICS R3.14 CA reference manual. This won't allowed to use the # command 'ReadConfig' with a long file path, which is usually the case. # This function is a workaround to that problem. Fomr matlab one can # just call this function without arguments an the function ReadConfig # will be called with a predefined file passed during startup # However, it can be usefull also win the GUI, so it is always added. self._config_file = config_file self.add( pyrogue.LocalCommand(name='setDefaults', description='Set default configuration', function=self._set_defaults_cmd)) # Flag that indicates if the default configuration should be loaded # once the root is started. self._configure = configure # Variable groups self._VariableGroups = VariableGroups # Add epics interface self._epics = None if epics_prefix: print("Starting EPICS server using prefix \"{}\"".format( epics_prefix)) from pyrogue.protocols import epics self._epics = epics.EpicsCaServer(base=epics_prefix, root=self) self._pv_dump_file = pv_dump_file # PVs for stream data # This should be replaced with DataReceiver objects if stream_pv_size: print( "Enabling stream data on PVs (buffer size = {} points, data type = {})" .format(stream_pv_size, stream_pv_type)) self._stream_fifos = [] self._stream_slaves = [] for i in range(4): self._stream_slaves.append( self._epics.createSlave(name="AMCc:Stream{}".format(i), maxSize=stream_pv_size, type=stream_pv_type)) # Calculate number of bytes needed on the fifo if '16' in stream_pv_type: fifo_size = stream_pv_size * 2 else: fifo_size = stream_pv_size * 4 self._stream_fifos.append( rogue.interfaces.stream.Fifo(1000, fifo_size, True)) # changes pyrogue.streamConnect(self._stream_fifos[i], self._stream_slaves[i]) pyrogue.streamTap(self._ddr_streams[i], self._stream_fifos[i]) # Update SaveState to not read before saving self.SaveState.replaceFunction( lambda arg: self.saveYaml(name=arg, readFirst=False, modes=['RW', 'RO', 'WO'], incGroups=None, excGroups='NoState', autoPrefix='state', autoCompress=True)) # Update SaveConfig to not read before saving self.SaveConfig.replaceFunction( lambda arg: self.saveYaml(name=arg, readFirst=False, modes=['RW', 'WO'], incGroups=None, excGroups='NoConfig', autoPrefix='config', autoCompress=False))
def __init__(self, name, device, **kwargs): pyrogue.Device.__init__(self, name=name, description='SMuRF Data GeneralAnalogFilter', **kwargs) self.device = device # Add "Disable" variable self.add( pyrogue.LocalVariable( name='Disable', description= 'Disable the processing block. Data will just pass thorough to the next slave.', mode='RW', value=False, localSet=lambda value: self.device.setFilterDisable(value), localGet=self.device.getFilterDisable)) # Add the filter order variable self.add( pyrogue.LocalVariable( name='Order', description='Filter order', mode='RW', value=4, localSet=lambda value: self.device.setOrder(value), localGet=self.device.getOrder)) # Add the filter gain variable self.add( pyrogue.LocalVariable( name='Gain', description='Filter gain', mode='RW', value=1.0, localSet=lambda value: self.device.setGain(value), localGet=self.device.getGain)) # Add the filter a coefficients variable # Rogue doesn't allow to have an empty list here. Also, the EPICS PV is created # with the initial size of this list, and can not be changed later, so we are doing # it big enough at this point (we are probably not going to use an order > 10) self.add( pyrogue.LocalVariable( name='A', description='Filter a coefficients', mode='RW', value=[1.0, -3.74145562, 5.25726624, -3.28776591, 0.77203984] + [0] * 11, localSet=lambda value: self.device.setA(value), localGet=self.device.getA)) # Add the filter b coefficients variable # Rogue doesn't allow to have an empty list here. Also, the EPICS PV is created # with the initial size of this list, and can not be changed later, so we are doing # it big enough at this point (we are probably not going to use an order > 10) self.add( pyrogue.LocalVariable( name='B', description='Filter b coefficients', mode='RW', value=[ 5.28396689e-06, 2.11358676e-05, 3.17038014e-05, 2.11358676e-05, 5.28396689e-06 ] + [0] * 11, localSet=lambda value: self.device.setB(value), localGet=self.device.getB)) # Command to reset the filter self.add( pyrogue.LocalCommand(name='reset', description='Reset the unwrapper', function=self.device.resetFilter))
def __init__(self, *, sendCount=False, width=None, taps=None, stream=None, **kwargs): pyrogue.Device.__init__(self, description='PRBS Software Transmitter', **kwargs) self._prbs = rogue.utilities.Prbs() if width is not None: self._prbs.setWidth(width) if taps is not None: self._prbs.setTaps(taps) if stream is not None: pyrogue.streamConnect(self, stream) self._prbs.sendCount(sendCount) self.add( pyrogue.LocalVariable(name='txSize', description='PRBS Frame Size', units='Bytes', localSet=self._txSize, mode='RW', value=1024, typeStr='UInt32')) self.add( pyrogue.LocalVariable(name='txEnable', description='PRBS Run Enable', mode='RW', value=False, localSet=self._txEnable)) self.add( pyrogue.LocalCommand(name='genFrame', description='Generate n frames', value=1, function=self._genFrame)) self.add( pyrogue.LocalVariable(name='txErrors', description='TX Error Count', mode='RO', pollInterval=1, value=0, typeStr='UInt32', localGet=self._prbs.getTxErrors)) self.add( pyrogue.LocalVariable(name='txCount', description='TX Count', mode='RO', pollInterval=1, value=0, typeStr='UInt32', localGet=self._prbs.getTxCount)) self.add( pyrogue.LocalVariable(name='txBytes', description='TX Bytes', mode='RO', pollInterval=1, value=0, typeStr='UInt32', localGet=self._prbs.getTxBytes)) self.add( pyrogue.LocalVariable(name='genPayload', description='Payload Generate Enable', mode='RW', value=True, localSet=self._plEnable)) self.add( pyrogue.LocalVariable(name='txRate', description='TX Rate', disp="{:.3e}", mode='RO', pollInterval=1, value=0.0, units='Frames/s', localGet=self._prbs.getTxRate)) self.add( pyrogue.LocalVariable(name='txBw', description='TX BW', disp="{:.3e}", mode='RO', pollInterval=1, value=0.0, units='Bytes/s', localGet=self._prbs.getTxBw))
def __init__( self, description="AXI-Lite Micron N25Q and Micron MT25Q PROM", addrMode=True, # False = 24-bit Address mode, True = 32-bit Address Mode tryCount=5, **kwargs): self._useVars = rogue.Version.greaterThanEqual('5.4.0') if self._useVars: size = 0 else: size = (0x1 << 10) super().__init__(description=description, size=size, **kwargs) self._mcs = surf.misc.McsReader() self._addrMode = addrMode self._progDone = False self._tryCount = tryCount ############################## # Setup variables ############################## if self._useVars: self.add( pr.RemoteVariable( name='PasswordLock', offset=0x00, base=pr.UInt, bitSize=32, bitOffset=0, retryCount=tryCount, updateNotify=False, bulkOpEn=False, hidden=True, verify=False, )) self.add( pr.RemoteVariable( name='ModeReg', offset=0x04, base=pr.UInt, bitSize=32, bitOffset=0, retryCount=tryCount, updateNotify=False, bulkOpEn=False, hidden=True, verify=False, )) self.add( pr.RemoteVariable( name='AddrReg', offset=0x08, base=pr.UInt, bitSize=32, bitOffset=0, retryCount=tryCount, updateNotify=False, bulkOpEn=False, hidden=True, verify=False, )) self.add( pr.RemoteVariable( name='CmdReg', offset=0x0C, base=pr.UInt, bitSize=32, bitOffset=0, retryCount=tryCount, updateNotify=False, bulkOpEn=False, hidden=True, verify=False, )) self.add( pr.RemoteVariable( name='DataReg', offset=0x200, base=pr.UInt, bitSize=32 * 64, bitOffset=0, numValues=64, valueBits=32, valueStride=32, retryCount=tryCount, updateNotify=False, bulkOpEn=False, hidden=True, verify=False, )) ############################## # Constants ############################## self.READ_3BYTE_CMD = (0x03 << 16) self.READ_4BYTE_CMD = (0x13 << 16) self.FLAG_STATUS_REG = (0x70 << 16) self.FLAG_STATUS_RDY = (0x80) self.WRITE_ENABLE_CMD = (0x06 << 16) self.WRITE_DISABLE_CMD = (0x04 << 16) self.ADDR_ENTER_CMD = (0xB7 << 16) self.ADDR_EXIT_CMD = (0xE9 << 16) self.ERASE_3BYTE_CMD = (0xD8 << 16) self.ERASE_4BYTE_CMD = self.ERASE_3BYTE_CMD self.WRITE_3BYTE_CMD = (0x02 << 16) self.WRITE_4BYTE_CMD = self.WRITE_3BYTE_CMD self.STATUS_REG_WR_CMD = (0x01 << 16) self.STATUS_REG_RD_CMD = (0x05 << 16) self.DEV_ID_RD_CMD = (0x9F << 16) self.WRITE_NONVOLATILE_CONFIG = (0xB1 << 16) self.WRITE_VOLATILE_CONFIG = (0x81 << 16) self.READ_NONVOLATILE_CONFIG = (0xB5 << 16) self.READ_VOLATILE_CONFIG = (0x85 << 16) ########################## ## Configuration Register: ########################## ## BIT[15:12] Number of dummy clock cycles = 0xF (default) ## BIT[11:09] XIP mode at power-on reset = 0x7 (default) ## BIT[08:06] Output driver strength = x7 (default) ## BIT[05:05] Double transfer rate protocol = 0x1 (default) ## BIT[04:04] Reset/hold = 0x1 (default) ## BIT[03:03] Quad I/O protocol = 0x1 (default) ## BIT[02:02] Dual I/O protocol = 0x1 (default) ## BIT[01:01] 128Mb segment select = 0x1 (default) ## BIT[00:00] 1 = Enable 3-byte address mode (default) ## BIT[00:00] 0 = Enable 4-byte address mode self.DEFAULT_3BYTE_CONFIG = 0xFFFF self.DEFAULT_4BYTE_CONFIG = 0xFFFE self.READ_MASK = 0x00000000 self.WRITE_MASK = 0x80000000 self.VERIFY_MASK = 0x40000000 self.add( pr.LocalCommand( name='LoadMcsFile', function=self._LoadMcsFile, description='Load the .MCS into PROM', value='', ))
def __init__(self, *, host, port, size=None, jumbo=False, wait=True, packVer=1, pollInterval=1, **kwargs): super(self.__class__, self).__init__(**kwargs) self._host = host self._port = port if size is not None: self._log.critical("Size arg is deprecated. Use jumbo arg instead") self._udp = rogue.protocols.udp.Client(host, port, jumbo) self._rssi = rogue.protocols.rssi.Client(self._udp.maxPayload()) if packVer == 2: self._pack = rogue.protocols.packetizer.CoreV2( False, True) # ibCRC = False, obCRC = True else: self._pack = rogue.protocols.packetizer.Core() self._udp._setSlave(self._rssi.transport()) self._rssi.transport()._setSlave(self._udp) self._rssi.application()._setSlave(self._pack.transport()) self._pack.transport()._setSlave(self._rssi.application()) self._rssi.start() if wait: curr = int(time.time()) last = curr while not self._rssi.getOpen(): time.sleep(.0001) curr = int(time.time()) if last != curr: self._log.warning( "host=%s, port=%d -> Establishing link ..." % (host, port)) last = curr self._udp.setRxBufferCount(self._rssi.curMaxBuffers()) # Add variables self.add( pr.LocalVariable( name='rssiOpen', mode='RO', localGet=lambda: self._rssi.getOpen(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='rssiDownCount', mode='RO', localGet=lambda: self._rssi.getDownCount(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='rssiDropCount', mode='RO', localGet=lambda: self._rssi.getDropCount(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='rssiRetranCount', mode='RO', localGet=lambda: self._rssi.getRetranCount(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='locBusy', mode='RO', localGet=lambda: self._rssi.getLocBusy(), hidden=True, pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='locBusyCnt', mode='RO', localGet=lambda: self._rssi.getLocBusyCnt(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='remBusy', mode='RO', localGet=lambda: self._rssi.getRemBusy(), hidden=True, pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='remBusyCnt', mode='RO', localGet=lambda: self._rssi.getRemBusyCnt(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='locTryPeriod', mode='RW', localGet=lambda: self._rssi.getLocTryPeriod(), localSet=lambda value: self._rssi.setLocTryPeriod(value))) self.add( pr.LocalVariable( name='locBusyThold', mode='RW', localGet=lambda: self._rssi.getLocBusyThold(), localSet=lambda value: self._rssi.setLocBusyThold(value))) self.add( pr.LocalVariable( name='locMaxBuffers', mode='RW', localGet=lambda: self._rssi.getLocMaxBuffers(), localSet=lambda value: self._rssi.setLocMaxBuffers(value))) self.add( pr.LocalVariable( name='locMaxSegment', mode='RW', localGet=lambda: self._rssi.getLocMaxSegment(), localSet=lambda value: self._rssi.setLocMaxSegment(value))) self.add( pr.LocalVariable( name='locCumAckTout', mode='RW', localGet=lambda: self._rssi.getLocCumAckTout(), localSet=lambda value: self._rssi.setLocCumAckTout(value))) self.add( pr.LocalVariable( name='locRetranTout', mode='RW', localGet=lambda: self._rssi.getLocRetranTout(), localSet=lambda value: self._rssi.setLocRetranTout(value))) self.add( pr.LocalVariable( name='locNullTout', mode='RW', localGet=lambda: self._rssi.getLocNullTout(), localSet=lambda value: self._rssi.setLocNullTout(value))) self.add( pr.LocalVariable( name='locMaxRetran', mode='RW', localGet=lambda: self._rssi.getLocMaxRetran(), localSet=lambda value: self._rssi.setLocMaxRetran(value))) self.add( pr.LocalVariable( name='locMaxCumAck', mode='RW', localGet=lambda: self._rssi.getLocMaxCumAck(), localSet=lambda value: self._rssi.setLocMaxCumAck(value))) self.add( pr.LocalVariable(name='curMaxBuffers', mode='RO', localGet=lambda: self._rssi.curMaxBuffers(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curMaxSegment', mode='RO', localGet=lambda: self._rssi.curMaxSegment(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curCumAckTout', mode='RO', localGet=lambda: self._rssi.curCumAckTout(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curRetranTout', mode='RO', localGet=lambda: self._rssi.curRetranTout(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curNullTout', mode='RO', localGet=lambda: self._rssi.curNullTout(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curMaxRetran', mode='RO', localGet=lambda: self._rssi.curMaxRetran(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curMaxCumAck', mode='RO', localGet=lambda: self._rssi.curMaxCumAck(), pollInterval=pollInterval)) self.add(pr.LocalCommand(name='stop', function=self._stop)) self.add( pr.LocalCommand(name='start', function=lambda: self._rssi.start()))
def __init__(self, *, name=None, description=''): """Init the node with passed attributes""" rogue.interfaces.stream.Master.__init__(self) # Create log listener to add to systemlog variable formatter = logging.Formatter("%(msg)s") handler = RootLogHandler(root=self) handler.setLevel(logging.ERROR) handler.setFormatter(formatter) self._logger = logging.getLogger('pyrogue') self._logger.addHandler(handler) # Running status self._running = False # Polling worker self._pollQueue = None # Remote object export self._pyroThread = None self._pyroDaemon = None # List of variable listeners self._varListeners = [] self._varListenLock = threading.Lock() # Variable update worker self._updateQueue = queue.Queue() self._updateThread = None # Init pr.Device.__init__(self, name=name, description=description) # Variables self.add( pr.LocalVariable( name='SystemLog', value='', mode='RO', hidden=True, description= 'String containing newline seperated system logic entries')) self.add( pr.LocalVariable( name='ForceWrite', value=False, mode='RW', hidden=True, description='Configuration Flag To Control Write All Block')) # Commands self.add( pr.LocalCommand(name='WriteAll', function=self._write, description='Write all values to the hardware')) self.add( pr.LocalCommand(name="ReadAll", function=self._read, description='Read all values from the hardware')) self.add( pr.LocalCommand( name='WriteConfig', value='', function=self._writeConfig, description= 'Write configuration to passed filename in YAML format')) self.add( pr.LocalCommand( name='ReadConfig', value='', function=self._readConfig, description= 'Read configuration from passed filename in YAML format')) self.add( pr.LocalCommand( name='SoftReset', function=self._softReset, description='Generate a soft reset to each device in the tree') ) self.add( pr.LocalCommand( name='HardReset', function=self._hardReset, description='Generate a hard reset to each device in the tree') ) self.add( pr.LocalCommand( name='CountReset', function=self._countReset, description='Generate a count reset to each device in the tree' )) self.add( pr.LocalCommand( name='ClearLog', function=self._clearLog, description= 'Clear the message log cntained in the SystemLog variable'))
def __init__(self, *, port, host='127.0.0.1', jumbo=False, wait=True, packVer=1, pollInterval=1, enSsi=True, server=False, **kwargs): super(self.__class__, self).__init__(**kwargs) self._host = host self._port = port if server: self._udp = rogue.protocols.udp.Server(port, jumbo) self._rssi = rogue.protocols.rssi.Server(self._udp.maxPayload()) else: self._udp = rogue.protocols.udp.Client(host, port, jumbo) self._rssi = rogue.protocols.rssi.Client(self._udp.maxPayload()) if packVer == 2: self._pack = rogue.protocols.packetizer.CoreV2( False, True, enSsi) # ibCRC = False, obCRC = True else: self._pack = rogue.protocols.packetizer.Core(enSsi) self._udp == self._rssi.transport() self._rssi.application() == self._pack.transport() self._rssi._start() if wait and not server: curr = int(time.time()) last = curr cnt = 0 while not self._rssi.getOpen(): time.sleep(.0001) curr = int(time.time()) if last != curr: last = curr if jumbo: cnt += 1 if cnt < 10: self._log.warning( "host=%s, port=%d -> Establishing link ..." % (host, port)) else: self._log.warning( 'host=%s, port=%d -> Failing to connect using jumbo frames! Be sure to check interface MTU settings with ifconig -a' % (host, port)) self._udp.setRxBufferCount(self._rssi.curMaxBuffers()) # Add variables self.add( pr.LocalVariable( name='rssiOpen', mode='RO', value=False, localGet=lambda: self._rssi.getOpen(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='rssiDownCount', mode='RO', value=0, typeStr='UInt32', localGet=lambda: self._rssi.getDownCount(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='rssiDropCount', mode='RO', value=0, typeStr='UInt32', localGet=lambda: self._rssi.getDropCount(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='rssiRetranCount', mode='RO', value=0, typeStr='UInt32', localGet=lambda: self._rssi.getRetranCount(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='locBusy', mode='RO', value=True, localGet=lambda: self._rssi.getLocBusy(), hidden=True, pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='locBusyCnt', mode='RO', value=0, typeStr='UInt32', localGet=lambda: self._rssi.getLocBusyCnt(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='remBusy', mode='RO', value=True, localGet=lambda: self._rssi.getRemBusy(), hidden=True, pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='remBusyCnt', mode='RO', value=0, typeStr='UInt32', localGet=lambda: self._rssi.getRemBusyCnt(), pollInterval=pollInterval, )) self.add( pr.LocalVariable( name='locTryPeriod', mode='RW', value=self._rssi.getLocTryPeriod(), typeStr='UInt32', localGet=lambda: self._rssi.getLocTryPeriod(), localSet=lambda value: self._rssi.setLocTryPeriod(value))) self.add( pr.LocalVariable( name='locMaxBuffers', mode='RW', value=self._rssi.getLocMaxBuffers(), typeStr='UInt8', localGet=lambda: self._rssi.getLocMaxBuffers(), localSet=lambda value: self._rssi.setLocMaxBuffers(value))) self.add( pr.LocalVariable( name='locMaxSegment', mode='RW', value=self._rssi.getLocMaxSegment(), typeStr='UInt16', localGet=lambda: self._rssi.getLocMaxSegment(), localSet=lambda value: self._rssi.setLocMaxSegment(value))) self.add( pr.LocalVariable( name='locCumAckTout', mode='RW', value=self._rssi.getLocCumAckTout(), typeStr='UInt16', localGet=lambda: self._rssi.getLocCumAckTout(), localSet=lambda value: self._rssi.setLocCumAckTout(value))) self.add( pr.LocalVariable( name='locRetranTout', mode='RW', value=self._rssi.getLocRetranTout(), typeStr='UInt16', localGet=lambda: self._rssi.getLocRetranTout(), localSet=lambda value: self._rssi.setLocRetranTout(value))) self.add( pr.LocalVariable( name='locNullTout', mode='RW', value=self._rssi.getLocNullTout(), typeStr='UInt16', localGet=lambda: self._rssi.getLocNullTout(), localSet=lambda value: self._rssi.setLocNullTout(value))) self.add( pr.LocalVariable( name='locMaxRetran', mode='RW', value=self._rssi.getLocMaxRetran(), typeStr='UInt8', localGet=lambda: self._rssi.getLocMaxRetran(), localSet=lambda value: self._rssi.setLocMaxRetran(value))) self.add( pr.LocalVariable( name='locMaxCumAck', mode='RW', value=self._rssi.getLocMaxCumAck(), typeStr='UInt8', localGet=lambda: self._rssi.getLocMaxCumAck(), localSet=lambda value: self._rssi.setLocMaxCumAck(value))) self.add( pr.LocalVariable(name='curMaxBuffers', mode='RO', value=0, typeStr='UInt8', localGet=lambda: self._rssi.curMaxBuffers(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curMaxSegment', mode='RO', value=0, typeStr='UInt16', localGet=lambda: self._rssi.curMaxSegment(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curCumAckTout', mode='RO', value=0, typeStr='UInt16', localGet=lambda: self._rssi.curCumAckTout(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curRetranTout', mode='RO', value=0, typeStr='UInt16', localGet=lambda: self._rssi.curRetranTout(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curNullTout', mode='RO', value=0, typeStr='UInt16', localGet=lambda: self._rssi.curNullTout(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curMaxRetran', mode='RO', value=0, typeStr='UInt8', localGet=lambda: self._rssi.curMaxRetran(), pollInterval=pollInterval)) self.add( pr.LocalVariable(name='curMaxCumAck', mode='RO', value=0, typeStr='UInt8', localGet=lambda: self._rssi.curMaxCumAck(), pollInterval=pollInterval)) self.add(pr.LocalCommand(name='stop', function=self._stop)) self.add( pr.LocalCommand(name='start', function=lambda: self._rssi._start()))
def __init__(self, *, name=None, description=''): """Init the node with passed attributes""" rogue.interfaces.stream.Master.__init__(self) # Create log listener to add to systemlog variable formatter = logging.Formatter("%(msg)s") handler = RootLogHandler(root=self) handler.setLevel(logging.ERROR) handler.setFormatter(formatter) self._logger = logging.getLogger('pyrogue') self._logger.addHandler(handler) # Running status self._running = False # Polling worker self._pollQueue = None # Zeromq server self._zmqServer = None self._structure = "" # List of variable listeners self._varListeners = [] self._varListenLock = threading.Lock() # Variable update worker self._updateQueue = queue.Queue() self._updateThread = None # Init pr.Device.__init__(self, name=name, description=description) # Variables self.add(pr.LocalVariable(name='SystemLog', value='', mode='RO', hidden=True, description='String containing newline seperated system logic entries')) self.add(pr.LocalVariable(name='ForceWrite', value=False, mode='RW', hidden=True, description='Configuration Flag To Always Write Non Stale Blocks For WriteAll, LoadConfig and setYaml')) self.add(pr.LocalVariable(name='InitAfterConfig', value=False, mode='RW', hidden=True, description='Configuration Flag To Execute Initialize after LoadConfig or setYaml')) self.add(pr.LocalVariable(name='Time', value=0.0, mode='RO', hidden=True, localGet=lambda: time.time(), pollInterval=1.0, description='Current Time In Seconds Since EPOCH UTC')) self.add(pr.LocalVariable(name='LocalTime', value='', mode='RO', hidden=False, localGet=lambda: time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time())), pollInterval=1.0, description='Local Time')) # Commands self.add(pr.LocalCommand(name='WriteAll', function=self._write, hidden=True, description='Write all values to the hardware')) self.add(pr.LocalCommand(name="ReadAll", function=self._read, hidden=True, description='Read all values from the hardware')) self.add(pr.LocalCommand(name='SaveState', value='', function=self._saveState, hidden=True, description='Save state to passed filename in YAML format')) self.add(pr.LocalCommand(name='SaveConfig', value='', function=self._saveConfig, hidden=True, description='Save configuration to passed filename in YAML format')) self.add(pr.LocalCommand(name='LoadConfig', value='', function=self._loadConfig, hidden=True, description='Read configuration from passed filename in YAML format')) self.add(pr.LocalCommand(name='Initialize', function=self.initialize, hidden=True, description='Generate a soft reset to each device in the tree')) self.add(pr.LocalCommand(name='HardReset', function=self.hardReset, hidden=True, description='Generate a hard reset to each device in the tree')) self.add(pr.LocalCommand(name='CountReset', function=self.countReset, hidden=True, description='Generate a count reset to each device in the tree')) self.add(pr.LocalCommand(name='ClearLog', function=self._clearLog, hidden=True, description='Clear the message log cntained in the SystemLog variable')) self.add(pr.LocalCommand(name='SetYamlConfig', value='', function=lambda arg: self._setYaml(arg,False,['RW','WO']), hidden=True, description='Set configuration from passed YAML string')) self.add(pr.LocalCommand(name='GetYamlConfig', value=True, function=lambda arg: self._getYaml(arg,['RW','WO']), hidden=True, description='Get current configuration as YAML string. Pass read first arg.')) self.add(pr.LocalCommand(name='GetYamlState', value=True, function=lambda arg: self._getYaml(arg,['RW','RO','WO']), hidden=True, description='Get current state as YAML string. Pass read first arg.')) self.add(pr.LocalCommand(name='Restart', function=self._restart, hidden=False, description='Restart and reload the server application')) self.add(pr.LocalCommand(name='Exit', function=self._exit, hidden=False, description='Exit the server application'))
def __init__( self, *, name=None, description='', expand=True, timeout=1.0, initRead=False, initWrite=False, pollEn=True, serverPort=0, # 9099 is the default, 0 for auto sqlUrl=None, maxLog=1000, streamIncGroups=None, streamExcGroups=['NoStream'], sqlIncGroups=None, sqlExcGroups=['NoSql']): """Init the node with passed attributes""" rogue.interfaces.stream.Master.__init__(self) # Store startup parameters self._timeout = timeout self._initRead = initRead self._initWrite = initWrite self._pollEn = pollEn self._serverPort = serverPort self._sqlUrl = sqlUrl self._maxLog = maxLog self._streamIncGroups = streamIncGroups self._streamExcGroups = streamExcGroups self._sqlIncGroups = sqlIncGroups self._sqlExcGroups = sqlExcGroups self._doHeartbeat = True # Backdoor flag # Create log listener to add to SystemLog variable formatter = logging.Formatter("%(msg)s") handler = RootLogHandler(root=self) handler.setFormatter(formatter) self._logger = logging.getLogger('pyrogue') self._logger.addHandler(handler) # Running status self._running = False # Polling worker self._pollQueue = self._pollQueue = pr.PollQueue(root=self) # Zeromq server self._zmqServer = None # List of variable listeners self._varListeners = [] self._varListenLock = threading.Lock() # Variable update worker self._updateQueue = queue.Queue() self._updateThread = None self._updateLock = threading.Lock() self._updateTrack = {} # SQL URL self._sqlLog = None # Init pr.Device.__init__(self, name=name, description=description, expand=expand) # Variables self.add( pr.LocalVariable(name='RogueVersion', value=rogue.Version.current(), mode='RO', hidden=False, description='Rogue Version String')) self.add( pr.LocalVariable(name='RogueDirectory', value=os.path.dirname(pr.__file__), mode='RO', hidden=False, description='Rogue Library Directory')) self.add( pr.LocalVariable( name='SystemLog', value=SystemLogInit, mode='RO', hidden=True, groups=['NoStream', 'NoSql', 'NoState'], description= 'String containing newline separated system logic entries')) self.add( pr.LocalVariable( name='ForceWrite', value=False, mode='RW', hidden=True, description= 'Configuration Flag To Always Write Non Stale Blocks For WriteAll, LoadConfig and setYaml' )) self.add( pr.LocalVariable( name='InitAfterConfig', value=False, mode='RW', hidden=True, description= 'Configuration Flag To Execute Initialize after LoadConfig or setYaml' )) self.add( pr.LocalVariable( name='Time', value=0.0, mode='RO', hidden=True, description='Current Time In Seconds Since EPOCH UTC')) self.add( pr.LinkVariable( name='LocalTime', value='', mode='RO', groups=['NoStream', 'NoSql', 'NoState'], linkedGet=lambda: time.strftime( "%Y-%m-%d %H:%M:%S %Z", time.localtime(self.Time.value())), dependencies=[self.Time], description='Local Time')) self.add( pr.LocalVariable( name='PollEn', value=False, mode='RW', groups=['NoStream', 'NoSql', 'NoState'], localSet=lambda value: self._pollQueue.pause(not value), localGet=lambda: not self._pollQueue.paused())) # Commands self.add( pr.LocalCommand(name='WriteAll', function=self._write, hidden=True, description='Write all values to the hardware')) self.add( pr.LocalCommand(name="ReadAll", function=self._read, hidden=True, description='Read all values from the hardware')) self.add( pr.LocalCommand( name='SaveState', value='', function=lambda arg: self.saveYaml(name=arg, readFirst=True, modes=['RW', 'RO', 'WO'], incGroups=None, excGroups='NoState', autoPrefix='state', autoCompress=True), hidden=True, description='Save state to passed filename in YAML format')) self.add( pr.LocalCommand( name='SaveConfig', value='', function=lambda arg: self.saveYaml(name=arg, readFirst=True, modes=['RW', 'WO'], incGroups=None, excGroups='NoConfig', autoPrefix='config', autoCompress=False), hidden=True, description= 'Save configuration to passed filename in YAML format')) self.add( pr.LocalCommand( name='LoadConfig', value='', function=lambda arg: self.loadYaml(name=arg, writeEach=False, modes=['RW', 'WO'], incGroups=None, excGroups='NoConfig'), hidden=True, description= 'Read configuration from passed filename in YAML format')) self.add( pr.LocalCommand( name='RemoteVariableDump', value='', function=lambda arg: self.remoteVariableDump( name=arg, modes=['RW', 'WO', 'RO'], readFirst=True), hidden=True, description='Save a dump of the remote variable state')) self.add( pr.LocalCommand( name='RemoteConfigDump', value='', function=lambda arg: self.remoteVariableDump( name=arg, modes=['RW', 'WO'], readFirst=True), hidden=True, description='Save a dump of the remote variable state')) self.add( pr.LocalCommand( name='Initialize', function=self.initialize, hidden=True, description='Generate a soft reset to each device in the tree') ) self.add( pr.LocalCommand( name='HardReset', function=self.hardReset, hidden=True, description='Generate a hard reset to each device in the tree') ) self.add( pr.LocalCommand( name='CountReset', function=self.countReset, hidden=True, description='Generate a count reset to each device in the tree' )) self.add( pr.LocalCommand( name='ClearLog', function=self._clearLog, hidden=True, description= 'Clear the message log contained in the SystemLog variable')) self.add( pr.LocalCommand( name='SetYamlConfig', value='', function=lambda arg: self.setYaml(yml=arg, writeEach=False, modes=['RW', 'WO'], incGroups=None, excGroups='NoConfig'), hidden=True, description='Set configuration from passed YAML string')) self.add( pr.LocalCommand( name='GetYamlConfig', value=True, retValue='', function=lambda arg: self.getYaml(readFirst=arg, modes=['RW', 'WO'], incGroups=None, excGroups='NoConfig'), hidden=True, description= 'Get current configuration as YAML string. Pass read first arg.' )) self.add( pr.LocalCommand( name='GetYamlState', value=True, retValue='', function=lambda arg: self.getYaml(readFirst=arg, modes=['RW', 'RO', 'WO'], incGroups=None, excGroups='NoState'), hidden=True, description= 'Get current state as YAML string. Pass read first arg.'))
def __init__(self, *, hidden=True, **kwargs): """Initialize device class""" Device.__init__(self, hidden=hidden, **kwargs) self.add( pr.LocalVariable( name='dataFile', mode='RW', value='', description= 'Data file for storing frames for connected streams.')) self.add( pr.LocalVariable(name='open', mode='RW', value=False, localSet=self._setOpen, description='Data file open state')) self.add( pr.LocalVariable( name='bufferSize', mode='RW', value=0, localSet=self._setBufferSize, description= 'File buffering size. Enables caching of data before call to file system.' )) self.add( pr.LocalVariable( name='maxFileSize', mode='RW', value=0, localSet=self._setMaxFileSize, description= 'Maximum size for an individual file. Setting to a non zero splits the run data into multiple files.' )) self.add( pr.LocalVariable( name='fileSize', mode='RO', value=0, pollInterval=1, localGet=self._getFileSize, description= 'Size of data files(s) for current open session in bytes.')) self.add( pr.LocalVariable( name='frameCount', mode='RO', value=0, pollInterval=1, localGet=self._getFrameCount, description= 'Frame in data file(s) for current open session in bytes.')) self.add( pr.LocalCommand( name='autoName', function=self._genFileName, description='Auto create data file name using data and time.'))
def __init__(self, *, name=None, description='', memBase=None, offset=0, size=0, hidden=False, blockSize=None, expand=True, enabled=True, defaults=None, enableDeps=None, hubMin=0, hubMax=0): """Initialize device class""" if name is None: name = self.__class__.__name__ # Hub.__init__ must be called first for _setSlave to work below rim.Hub.__init__(self, offset, hubMin, hubMax) # Blocks self._blocks = [] self._memBase = memBase self._memLock = threading.RLock() self._size = size self._blockSize = blockSize self._defaults = defaults if defaults is not None else {} self.forceCheckEach = False # Connect to memory slave if memBase: self._setSlave(memBase) # Node.__init__ can't be called until after self._memBase is created pr.Node.__init__(self, name=name, hidden=hidden, description=description, expand=expand) self._log.info("Making device {:s}".format(name)) # Convenience methods self.addRemoteCommands = ft.partial(self.addNodes, pr.RemoteCommand) # Variable interface to enable flag self.add(EnableVariable(enabled=enabled, deps=enableDeps)) self.add( pr.LocalCommand( name='ReadDevice', value=False, hidden=True, function=lambda arg: self.readAndCheckBlocks(recurse=arg), description='Force read of device without recursion')) self.add( pr.LocalCommand( name='WriteDevice', value='', hidden=True, function=lambda arg: self.writeAndVerifyBlocks(force=True, recurse=arg), description='Force write of device without recursion'))
def __init__(self, name, **kwargs): pyrogue.Device.__init__(self, name=name, description='SMuRF Data CustomTransmitter', **kwargs) self._transmitter = MyModule.MyTransmitter() # Add "Disable" variable self.add( pyrogue.LocalVariable( name='Disable', description= 'Disable the processing block. Data will just pass thorough to the next device.', mode='RW', value=False, localSet=lambda value: self._transmitter.setDisable(value), localGet=self._transmitter.getDisable)) # Add a variable for the debugData flag self.add( pyrogue.LocalVariable( name='DebugData', description='Set the debug mode, for the data', mode='RW', value=False, localSet=lambda value: self._transmitter.setDebugData(value), localGet=self._transmitter.getDebugData)) # Add a variable for the debugMeta flag self.add( pyrogue.LocalVariable( name='DebugMeta', description='Set the debug mode, for the metadata', mode='RW', value=False, localSet=lambda value: self._transmitter.setDebugMeta(value), localGet=self._transmitter.getDebugMeta)) # Add the data dropped counter variable self.add( pyrogue.LocalVariable(name='DataDropCnt', description='Number of data frame dropped', mode='RO', value=0, pollInterval=1, localGet=self._transmitter.getDataDropCnt)) # Add the metadata dropped counter variable self.add( pyrogue.LocalVariable( name='MetaDropCnt', description='Number of metadata frame dropped', mode='RO', value=0, pollInterval=1, localGet=self._transmitter.getMetaDropCnt)) # Command to clear all the counters self.add( pyrogue.LocalCommand(name='clearCnt', description='Clear all counters', function=self._transmitter.clearCnt))
def __init__(self, ip_addr, config_file, server_mode, group_name, epics_prefix,\ polling_en, comm_type, pcie_rssi_link, stream_pv_size, stream_pv_type,\ pv_dump_file, disable_bay0, disable_bay1, disable_gc, windows_title, pcie_dev): try: pyrogue.Root.__init__(self, name='AMCc', description='AMC Carrier') # File writer for streaming interfaces # DDR interface (TDEST 0x80 - 0x87) stm_data_writer = pyrogue.utilities.fileio.StreamWriter( name='streamDataWriter') self.add(stm_data_writer) # Streaming interface (TDEST 0xC0 - 0xC7) stm_interface_writer = pyrogue.utilities.fileio.StreamWriter( name='streamingInterface') self.add(stm_interface_writer) # Workaround to FpgaTopLelevel not supporting rssi = None if pcie_rssi_link == None: pcie_rssi_link = 0 # Instantiate Fpga top level fpga = FpgaTopLevel(ipAddr=ip_addr, commType=comm_type, pcieRssiLink=pcie_rssi_link, disableBay0=disable_bay0, disableBay1=disable_bay1) # Add devices self.add(fpga) # Create stream interfaces self.ddr_streams = [] # DDR streams self.streaming_streams = [] # Streaming interface streams # If the packetizer is being used, the FpgaTopLevel class will defined a 'stream' interface exposing it. # Otherwise, we are using DMA engine without packetizer. Create the stream interface accordingly. if hasattr(fpga, 'stream'): for i in range(8): self.ddr_streams.append(fpga.stream.application(0x80 + i)) self.streaming_streams.append( fpga.stream.application(0xC0 + i)) else: for i in range(8): self.ddr_streams.append( rogue.hardware.axi.AxiStreamDma( pcie_dev, (pcie_rssi_link * 0x100 + 0x80 + i), True)) self.streaming_streams.append( rogue.hardware.axi.AxiStreamDma( pcie_dev, (pcie_rssi_link * 0x100 + 0xC0 + i), True)) # Our smurf_processor receiver # The data stream comes from TDEST 0xC1 # We use a FIFO between the stream data and the receiver: # Stream -> FIFO -> smurf_processor receiver self.smurf_processor = Smurf.SmurfProcessor() self.smurf_processor.setDebug(False) self.smurf_processor_fifo = rogue.interfaces.stream.Fifo( 1000, 0, True) pyrogue.streamConnect(self.streaming_streams[1], self.smurf_processor_fifo) pyrogue.streamConnect(self.smurf_processor_fifo, self.smurf_processor) # Add data streams (0-7) to file channels (0-7) for i in range(8): ## DDR streams pyrogue.streamConnect(self.ddr_streams[i], stm_data_writer.getChannel(i)) ## Streaming interface streams # We have already connected TDEST 0xC1 to the smurf_processor receiver, # so we need to tapping it to the data writer. if i == 1: pyrogue.streamTap(self.streaming_streams[i], stm_interface_writer.getChannel(i)) # The rest of channels are connected directly to the data writer. else: pyrogue.streamConnect(self.streaming_streams[i], stm_interface_writer.getChannel(i)) # Look for the TesBias registers # TesBias register are located on # FpgaTopLevel.AppTop.AppCore.RtmCryoDet.RtmSpiMax # And their name is TesBiasDacDataRegCh[n], where x = [0:31] self.TestBiasVars = [] self.TestBiasRegEx = re.compile('.*TesBiasDacDataRegCh\[(\d+)\]$') for var in self.FpgaTopLevel.AppTop.AppCore.RtmCryoDet.RtmSpiMax.variableList: m = self.TestBiasRegEx.match(var.name) if m: reg_index = int(m[1]) - 1 if reg_index < 32: print( f'Found TesBias register: {var.name}, with index {reg_index}' ) self.TestBiasVars.append(var) # Check that we have all 32 TesBias registers if len(self.TestBiasVars) == 32: print( f'Found 32 TesBias registers. Assigning listener functions' ) # Add listener to the TesBias registers for var in self.TestBiasVars: var.addListener(self.send_test_bias) # Prepare a buffer to holds the TesBias register values self.TesBiasValue = [0] * 32 else: print( f'Error: {len(self.TestBiasVars)} TesBias register were found instead of 32. Aborting' ) # Run control for streaming interfaces self.add( pyrogue.RunControl(name='streamRunControl', description='Run controller', cmd=fpga.SwDaqMuxTrig, rates={ 1: '1 Hz', 10: '10 Hz', 30: '30 Hz' })) # PVs for stream data, used on PCAS-based EPICS server if epics_prefix and stream_pv_size: if use_pcas: print("Enabling stream data on PVs (buffer size = {} points, data type = {})"\ .format(stream_pv_size,stream_pv_type)) # Add data streams (0-7) to local variables so they are expose as PVs # Also add PVs to select the data format self.stream_fifos = [] self.data_buffers = [] for i in range(8): # Calculate number of bytes needed on the fifo if '16' in stream_pv_type: fifo_size = stream_pv_size * 2 else: fifo_size = stream_pv_size * 4 # Setup a FIFO tapped to the steram data and a Slave data buffer # Local variables will talk to the data buffer directly. self.stream_fifos.append( rogue.interfaces.stream.Fifo(0, fifo_size, 0)) stream_fifo = self.stream_fifos[i] self.data_buffers.append( DataBuffer(size=stream_pv_size, data_type=stream_pv_type)) data_buffer = self.data_buffers[i] stream_fifo._setSlave(data_buffer) #pyrogue.streamTap(fpga.stream.application(0x80 + i), stream_fifo) # Variable to read the stream data stream_var = pyrogue.LocalVariable( name='Stream{}'.format(i), description='Stream {}'.format(i), mode='RO', value=0, localGet=data_buffer.read, update=False, hidden=True) # Set the buffer callback to update the variable data_buffer.set_callback(stream_var.updated) # Variable to set the data format data_format_var = pyrogue.LocalVariable( name='StreamDataFormat{}'.format(i), description='Type of data being unpacked', mode='RW', value=0, enum={ i: j for i, j in enumerate( data_buffer.get_data_format_list()) }, localSet=data_buffer.set_data_format, localGet=data_buffer.get_data_format, hidden=True) # Variable to set the data byte order byte_order_var = pyrogue.LocalVariable( name='StreamDataByteOrder{}'.format(i), description='Byte order of data being unpacked', mode='RW', value=0, enum={ i: j for i, j in enumerate( data_buffer.get_data_byte_order_list()) }, localSet=data_buffer.set_data_byte_order, localGet=data_buffer.get_data_byte_order, hidden=True) # Variable to read the data format string format_string_var = pyrogue.LocalVariable( name='StreamDataFormatString{}'.format(i), description='Format string used to unpack the data', mode='RO', value=0, localGet=data_buffer.get_data_format_string, hidden=True) # Add listener to update the format string readback variable # when the data format or data byte order is changed data_format_var.addListener(format_string_var) byte_order_var.addListener(format_string_var) # Add the local variable to self self.add(stream_var) self.add(data_format_var) self.add(byte_order_var) self.add(format_string_var) # lcaPut limits the maximun lenght of a string to 40 chars, as defined # in the EPICS R3.14 CA reference manual. This won't allowed to use the # command 'ReadConfig' with a long file path, which is usually the case. # This function is a workaround to that problem. Fomr matlab one can # just call this function without arguments an the function ReadConfig # will be called with a predefined file passed during startup # However, it can be usefull also win the GUI, so it is always added. self.config_file = config_file self.add( pyrogue.LocalCommand(name='setDefaults', description='Set default configuration', function=self.set_defaults_cmd)) # If Garbage collection was disable, add this local variable to allow users # to manually run the garbage collection. if disable_gc: self.add( pyrogue.LocalCommand(name='runGarbageCollection', description='runGarbageCollection', function=self.run_garbage_collection)) self.add( pyrogue.LocalVariable( name='smurfProcessorDebug', description='Enable smurf processor transmit debug', mode='RW', value=False, localSet=lambda value: self.smurf_processor.setDebug(value ), hidden=False)) # Lost frame counter from smurf_processor self.add( pyrogue.LocalVariable( name='frameLossCnt', description='Lost frame Counter', mode='RO', value=0, localGet=self.smurf_processor.getFrameLossCnt, pollInterval=1, hidden=False)) # Received frame counter from smurf_processor self.add( pyrogue.LocalVariable( name='frameRxCnt', description='Received frame Counter', mode='RO', value=0, localGet=self.smurf_processor.getFrameRxCnt, pollInterval=1, hidden=False)) # Out-of-order frame counter from smurf_processor self.add( pyrogue.LocalVariable( name='frameOutOrderCnt', description= 'Number of time out-of-order frames are detected', mode='RO', value=0, localGet=self.smurf_processor.getFrameOutOrderCnt, pollInterval=1, hidden=False)) # Command to clear all the frame counters on smurf_processor self.add( pyrogue.LocalCommand( name='clearFrameCnt', description='Clear all frame counters', function=self.smurf_processor.clearFrameCnt)) # Start the root if group_name: # Start with Pyro4 server host_name = get_host_name() print( "Starting rogue server with Pyro using group name \"{}\"". format(group_name)) self.start(pollEn=polling_en, pyroGroup=group_name, pyroHost=host_name, pyroNs=None) else: # Start without Pyro4 server print("Starting rogue server") self.start(pollEn=polling_en) self.ReadAll() # Call the get() method on the tesBias variable to force the call to # send_test_bias and update the array in Smurf2MCE for var in self.TestBiasVars: var.get() except KeyboardInterrupt: print("Killing server creation...") super(LocalServer, self).stop() exit() # Show image build information try: print("") print("FPGA image build information:") print("===================================") print("BuildStamp : {}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.BuildStamp.get())) print("FPGA Version : 0x{:x}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.FpgaVersion.get())) print("Git hash : 0x{:x}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.GitHash.get())) except AttributeError as attr_error: print("Attibute error: {}".format(attr_error)) print("") # Start the EPICS server if epics_prefix: print("Starting EPICS server using prefix \"{}\"".format( epics_prefix)) # Choose the appropiate epics module: if use_pcas: self.epics = pyrogue.epics.EpicsCaServer(base=epics_prefix, root=self) else: self.epics = pyrogue.protocols.epics.EpicsCaServer( base=epics_prefix, root=self) # PVs for stream data, used on GDD-based EPICS server if stream_pv_size: print("Enabling stream data on PVs (buffer size = {} points, data type = {})"\ .format(stream_pv_size,stream_pv_type)) self.stream_fifos = [] self.stream_slaves = [] for i in range(8): self.stream_slaves.append( self.epics.createSlave( name="AMCc:Stream{}".format(i), maxSize=stream_pv_size, type=stream_pv_type)) # Calculate number of bytes needed on the fifo if '16' in stream_pv_type: fifo_size = stream_pv_size * 2 else: fifo_size = stream_pv_size * 4 self.stream_fifos.append( rogue.interfaces.stream.Fifo( 1000, fifo_size, True)) # changes self.stream_fifos[i]._setSlave(self.stream_slaves[i]) pyrogue.streamTap(self.ddr_streams[i], self.stream_fifos[i]) self.epics.start() # Dump the PV list to the especified file if pv_dump_file: try: # Try to open the output file f = open(pv_dump_file, "w") except IOError: print("Could not open the PV dump file \"{}\"".format( pv_dump_file)) else: with f: print("Dumping PV list to \"{}\"...".format( pv_dump_file)) try: try: # Redirect the stdout to the output file momentarily original_stdout, sys.stdout = sys.stdout, f self.epics.dump() finally: sys.stdout = original_stdout print("Done!") except: # Capture error from epics.dump() if any print("Errors were found during epics.dump()") # If no in server Mode, start the GUI if not server_mode: create_gui(self, title=windows_title) else: # Stop the server when Crtl+C is pressed print("") print("Running in server mode now. Press Ctrl+C to stop...") try: # Wait for Ctrl+C while True: time.sleep(1) except KeyboardInterrupt: pass
def __init__(self, ip_addr, config_file, server_mode, epics_prefix,\ polling_en, comm_type, pcie_rssi_lane, stream_pv_size, stream_pv_type,\ pv_dump_file, disable_bay0, disable_bay1, disable_gc, windows_title,\ pcie_dev_rssi, pcie_dev_data): try: pyrogue.Root.__init__(self, name='AMCc', description='AMC Carrier') # File writer for streaming interfaces # DDR interface (TDEST 0x80 - 0x87) stm_data_writer = pyrogue.utilities.fileio.StreamWriter(name='streamDataWriter') self.add(stm_data_writer) # Streaming interface (TDEST 0xC0 - 0xC7) stm_interface_writer = pyrogue.utilities.fileio.StreamWriter(name='streamingInterface') self.add(stm_interface_writer) # Workaround to FpgaTopLelevel not supporting rssi = None if pcie_rssi_lane == None: pcie_rssi_lane = 0 # Instantiate Fpga top level fpga = FpgaTopLevel(ipAddr=ip_addr, commType=comm_type, pcieRssiLink=pcie_rssi_lane, disableBay0=disable_bay0, disableBay1=disable_bay1) # Add devices self.add(fpga) # Create stream interfaces self.ddr_streams = [] # DDR streams # Our smurf2mce receiver # The data stream comes from TDEST 0xC1 self.smurf2mce = MceTransmit.Smurf2MCE() self.smurf2mce.setDebug( False ) # Check if we are using PCIe or Ethernet communication. if 'pcie-' in comm_type: # If we are suing PCIe communication, used AxiStreamDmas to get the DDR and streaming streams. # DDR streams. We are only using the first 2 channel of each AMC daughter card, i.e. # channels 0, 1, 4, 5. for i in [0, 1, 4, 5]: self.ddr_streams.append( rogue.hardware.axi.AxiStreamDma(pcie_dev_rssi,(pcie_rssi_lane*0x100 + 0x80 + i), True)) # Streaming interface stream self.streaming_stream = \ rogue.hardware.axi.AxiStreamDma(pcie_dev_data,(pcie_rssi_lane*0x100 + 0xC1), True) # When PCIe communication is used, we connect the stream data directly to the receiver: # Stream -> smurf2mce receiver pyrogue.streamConnect(self.streaming_stream, self.smurf2mce) else: # If we are using Ethernet: DDR streams comes over the RSSI+packetizer channel, and # the streaming streams comes over a pure UDP channel. # DDR streams. The FpgaTopLevel class will defined a 'stream' interface exposing them. # We are only using the first 2 channel of each AMC daughter card, i.e. channels 0, 1, 4, 5. for i in [0, 1, 4, 5]: self.ddr_streams.append(fpga.stream.application(0x80 + i)) # Streaming interface stream. It comes over UDP, port 8195, without RSSI, # so we use an UDP Client receiver. self.streaming_stream = rogue.protocols.udp.Client(ip_addr, 8195, True) # When Ethernet communication is used, We use a FIFO between the stream data and the receiver: # Stream -> FIFO -> smurf2mce receiver self.smurf2mce_fifo = rogue.interfaces.stream.Fifo(100000,0,True) pyrogue.streamConnect(self.streaming_stream, self.smurf2mce_fifo) pyrogue.streamConnect(self.smurf2mce_fifo, self.smurf2mce) # Create a KeepAlive object and connect it to the UDP Client. # It is used to keep the UDP connection open. This in only needed when # using Ethernet communication, as the PCIe FW implements this functionality. self.keep_alive = KeepAlive() pyrogue.streamConnect(self.keep_alive, self.streaming_stream) # Start the KeepAlive thread self.keep_alive.start() # Add data streams (0-3) to file channels (0-3) for i in range(4): ## DDR streams pyrogue.streamConnect(self.ddr_streams[i], stm_data_writer.getChannel(i)) ## Streaming interface streams # We have already connected it to the smurf2mce receiver, # so we need to tapping it to the data writer. pyrogue.streamTap(self.streaming_stream, stm_interface_writer.getChannel(0)) # Add Local variable to set the TesBias scale factor. The variable has a listener function # which is called when a new value is written to it. self.add(pyrogue.LocalVariable( name='TesBiasSF', description='Scale factor apply to the TesBias values before writing it to the MCE header', value=1.0, mode='RW')) self.TesBiasSF.addListener(self.send_test_bias_sf) # Look for the TesBias registers # TesBias register are located on # FpgaTopLevel.AppTop.AppCore.RtmCryoDet.RtmSpiMax # And their name is TesBiasDacDataRegCh[n], where x = [0:31] self.TestBiasVars = [] self.TestBiasRegEx = re.compile('.*TesBiasDacDataRegCh\[(\d+)\]$') for var in self.FpgaTopLevel.AppTop.AppCore.RtmCryoDet.RtmSpiMax.variableList: m = self.TestBiasRegEx.match(var.name) if m: reg_index = int(m[1]) - 1 if reg_index < 32: print(f'Found TesBias register: {var.name}, with index {reg_index}') self.TestBiasVars.append(var) # Check that we have all 32 TesBias registers if len(self.TestBiasVars) == 32: print(f'Found 32 TesBias registers. Assigning listener functions') # Add listener to the TesBias registers for var in self.TestBiasVars: var.addListener(self.send_test_bias) # Prepare a buffer to holds the TesBias register values self.TesBiasValue = [0] * 32 else: print(f'Error: {len(self.TestBiasVars)} TesBias register were found instead of 32. Aborting') # Run control for streaming interfaces self.add(pyrogue.RunControl( name='streamRunControl', description='Run controller', cmd=fpga.SwDaqMuxTrig, rates={ 1: '1 Hz', 10: '10 Hz', 30: '30 Hz'})) # lcaPut limits the maximun lenght of a string to 40 chars, as defined # in the EPICS R3.14 CA reference manual. This won't allowed to use the # command 'ReadConfig' with a long file path, which is usually the case. # This function is a workaround to that problem. Fomr matlab one can # just call this function without arguments an the function ReadConfig # will be called with a predefined file passed during startup # However, it can be usefull also win the GUI, so it is always added. self.config_file = config_file self.add(pyrogue.LocalCommand( name='setDefaults', description='Set default configuration', function=self.set_defaults_cmd)) # If Garbage collection was disable, add this local variable to allow users # to manually run the garbage collection. if disable_gc: self.add(pyrogue.LocalCommand( name='runGarbageCollection', description='runGarbageCollection', function=self.run_garbage_collection)) self.add(pyrogue.LocalVariable( name='mcetransmitDebug', description='Enable mce transmit debug', mode='RW', value=False, localSet=lambda value: self.smurf2mce.setDebug(value), hidden=False)) # Lost frame counter from smurf2mce self.add(pyrogue.LocalVariable( name='frameLossCnt', description='Lost frame Counter', mode='RO', value=0, localGet=self.smurf2mce.getFrameLossCnt, pollInterval=1, hidden=False)) # Received frame counter from smurf2mce self.add(pyrogue.LocalVariable( name='frameRxCnt', description='Received frame Counter', mode='RO', value=0, localGet=self.smurf2mce.getFrameRxCnt, pollInterval=1, hidden=False)) # Out-of-order frame counter from smurf2mce self.add(pyrogue.LocalVariable( name='frameOutOrderCnt', description='Number of time out-of-order frames are detected', mode='RO', value=0, localGet=self.smurf2mce.getFrameOutOrderCnt, pollInterval=1, hidden=False)) # Bad frame counter self.add(pyrogue.LocalVariable( name='badFrameCnt', description='Number of lost frames due to a bad frame', mode='RO', value=0, localGet=self.smurf2mce.getBadFrameCnt, pollInterval=1, hidden=False)) # Command to clear all the frame counters on smurf2mce self.add(pyrogue.LocalCommand( name='clearFrameCnt', description='Clear all the frame counters', function=self.smurf2mce.clearFrameCnt)) # Start the root print("Starting rogue server") self.start(pollEn=polling_en) self.ReadAll() # Call the get() method on the tesBias variable to force the call to # send_test_bias and update the array in Smurf2MCE for var in self.TestBiasVars: var.get() # Call the get method on the tesBias variable to force the call to # send_tes_bias_sf and update the factor in Smurf2MCE self.TesBiasSF.get() except KeyboardInterrupt: print("Killing server creation...") super(LocalServer, self).stop() exit() # Show image build information try: print("") print("FPGA image build information:") print("===================================") print("BuildStamp : {}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.BuildStamp.get())) print("FPGA Version : 0x{:x}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.FpgaVersion.get())) print("Git hash : 0x{:x}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.GitHash.get())) except AttributeError as attr_error: print("Attibute error: {}".format(attr_error)) print("") # Start the EPICS server if epics_prefix: print("Starting EPICS server using prefix \"{}\"".format(epics_prefix)) self.epics = pyrogue.protocols.epics.EpicsCaServer(base=epics_prefix, root=self) # PVs for stream data if stream_pv_size: print("Enabling stream data on PVs (buffer size = {} points, data type = {})"\ .format(stream_pv_size,stream_pv_type)) self.stream_fifos = [] self.stream_slaves = [] for i in range(4): self.stream_slaves.append(self.epics.createSlave(name="AMCc:Stream{}".format(i), maxSize=stream_pv_size, type=stream_pv_type)) # Calculate number of bytes needed on the fifo if '16' in stream_pv_type: fifo_size = stream_pv_size * 2 else: fifo_size = stream_pv_size * 4 self.stream_fifos.append(rogue.interfaces.stream.Fifo(1000, fifo_size, True)) # changes self.stream_fifos[i]._setSlave(self.stream_slaves[i]) pyrogue.streamTap(self.ddr_streams[i], self.stream_fifos[i]) self.epics.start() # Dump the PV list to the specified file if pv_dump_file: try: # Try to open the output file f = open(pv_dump_file, "w") except IOError: print("Could not open the PV dump file \"{}\"".format(pv_dump_file)) else: with f: print("Dumping PV list to \"{}\"...".format(pv_dump_file)) try: try: # Redirect the stdout to the output file momentarily original_stdout, sys.stdout = sys.stdout, f self.epics.dump() finally: sys.stdout = original_stdout print("Done!") except: # Capture error from epics.dump() if any print("Errors were found during epics.dump()") # If no in server Mode, start the GUI if not server_mode: create_gui(self, title=windows_title) else: # Stop the server when Crtl+C is pressed print("") print("Running in server mode now. Press Ctrl+C to stop...") try: # Wait for Ctrl+C while True: time.sleep(1) except KeyboardInterrupt: pass
def __init__(self, name, **kwargs): self._FrameStatistics = smurf.core.counters.FrameStatistics() pyrogue.Device.__init__(self, name=name, description='SMuRF Frame Statistics', **kwargs) # Add "Disable" variable self.add( pyrogue.LocalVariable( name='Disable', description= 'Disable the processing block. Data will just pass thorough to the next slave.', mode='RW', value=False, localSet=lambda value: self._FrameStatistics.setDisable(value), localGet=self._FrameStatistics.getDisable)) # Add the frame counter variable self.add( pyrogue.LocalVariable(name='FrameCnt', description='Frame counter', mode='RO', value=0, pollInterval=1, localGet=self._FrameStatistics.getFrameCnt)) # Add the last frame size variable self.add( pyrogue.LocalVariable(name='FrameSize', description='Last frame size (bytes)', mode='RO', value=0, pollInterval=1, localGet=self._FrameStatistics.getFrameSize)) # Add the frame lost counter variable self.add( pyrogue.LocalVariable( name='FrameLossCnt', description='Number of lost frames', mode='RO', value=0, pollInterval=1, localGet=self._FrameStatistics.getFrameLossCnt)) # Add the out-of-order frame counter variable self.add( pyrogue.LocalVariable( name='FrameOutOrderCnt', description= 'Number of time we have received out-of-order frames', mode='RO', value=0, pollInterval=1, localGet=self._FrameStatistics.getFrameOutOrderCnt)) # Add the bad frame counter variable self.add( pyrogue.LocalVariable( name='BadFrameCnt', description='Number of bad frames', mode='RO', value=0, pollInterval=1, localGet=self._FrameStatistics.getBadFrameCnt)) # Command to clear all the counters self.add( pyrogue.LocalCommand(name='clearCnt', description='Clear all counters', function=self._FrameStatistics.clearCnt))
def __init__(self, *, name=None, description='', memBase=None, offset=0, size=0, hidden=False, groups=None, expand=False, enabled=True, defaults=None, enableDeps=None, hubMin=0, hubMax=0, guiGroup=None): """Initialize device class""" if name is None: name = self.__class__.__name__ # Hub.__init__ must be called first for _setSlave to work below rim.Hub.__init__(self, offset, hubMin, hubMax) # Blocks self._blocks = [] self._custBlocks = [] self._memBase = memBase self._memLock = threading.RLock() self._size = size self._defaults = defaults if defaults is not None else {} if size != 0: print("") print("============ Deprecation Warning =========================") print(f" Detected non zero size for Device {name}") print(" Creating devices with a non zero size to enable rawWrite ") print(" and rawRead is now deprecated. ") print(" The Device size attribute will be removed in a future ") print(" Rogue release ") print("==========================================================") self._ifAndProto = [] self.forceCheckEach = False # Connect to memory slave if memBase: self._setSlave(memBase) # Node.__init__ can't be called until after self._memBase is created pr.Node.__init__(self, name=name, hidden=hidden, groups=groups, description=description, expand=expand, guiGroup=guiGroup) self._log.info("Making device {:s}".format(name)) # Convenience methods self.addRemoteCommands = ft.partial(self.addNodes, pr.RemoteCommand) # Variable interface to enable flag self.add(EnableVariable(enabled=enabled, deps=enableDeps)) self.add( pr.LocalCommand( name='ReadDevice', value=False, hidden=True, function=lambda arg: self.readAndCheckBlocks(recurse=arg), description='Force read of device without recursion')) self.add( pr.LocalCommand( name='WriteDevice', value='', hidden=True, function=lambda arg: self.writeAndVerifyBlocks(force=True, recurse=arg), description='Force write of device without recursion'))
def __init__(self, ip_addr, config_file, server_mode, group_name, epics_prefix,\ polling_en, comm_type, pcie_rssi_link, stream_pv_size, stream_pv_type,\ pv_dump_file): try: pyrogue.Root.__init__(self, name='AMCc', description='AMC Carrier') # File writer for streaming interfaces # DDR interface (TDEST 0x80 - 0x87) stm_data_writer = pyrogue.utilities.fileio.StreamWriter( name='streamDataWriter') self.add(stm_data_writer) # Streaming interface (TDEST 0xC0 - 0xC7) stm_interface_writer = pyrogue.utilities.fileio.StreamWriter( name='streamingInterface') self.add(stm_interface_writer) # Workaround to FpgaTopLelevel not supporting rssi = None if pcie_rssi_link == None: pcie_rssi_link = 0 # Instantiate Fpga top level fpga = FpgaTopLevel(ipAddr=ip_addr, commType=comm_type, pcieRssiLink=pcie_rssi_link) # Add devices self.add(fpga) # Add data streams (0-7) to file channels (0-7) for i in range(8): # DDR streams pyrogue.streamConnect(fpga.stream.application(0x80 + i), stm_data_writer.getChannel(i)) # Streaming interface streams #pyrogue.streamConnect(fpga.stream.application(0xC0 + i), # new commended out # stm_interface_writer.getChannel(i)) # Our receiver data_fifo = rogue.interfaces.stream.Fifo(1000, 0, 1) # new self.my_processor = MyModule.MyProcessor() self.my_processor.setDebug(False) #pyrogue.streamConnect(base.FpgaTopLevel.stream.application(0xC1), data_fifo) # new #pyrogue.streamConnect(base.FpgaTopLevel.stream.Application(0xC1), data_fifo) # new pyrogue.streamConnect(fpga.stream.application(0xC1), data_fifo) pyrogue.streamConnect(data_fifo, self.my_processor) #pyrogue.streamTap(fpga.stream.application(0xC1), rx) # Run control for streaming interfaces self.add( pyrogue.RunControl(name='streamRunControl', description='Run controller', cmd=fpga.SwDaqMuxTrig, rates={ 1: '1 Hz', 10: '10 Hz', 30: '30 Hz' })) # PVs for stream data, used on PCAS-based EPICS server if epics_prefix and stream_pv_size: if use_pcas: print("Enabling stream data on PVs (buffer size = {} points, data type = {})"\ .format(stream_pv_size,stream_pv_type)) # Add data streams (0-7) to local variables so they are expose as PVs # Also add PVs to select the data format for i in range(8): # Calculate number of bytes needed on the fifo if '16' in stream_pv_type: fifo_size = stream_pv_size * 2 else: fifo_size = stream_pv_size * 4 # Setup a FIFO tapped to the steram data and a Slave data buffer # Local variables will talk to the data buffer directly. stream_fifo = rogue.interfaces.stream.Fifo( 0, fifo_size, 0) data_buffer = DataBuffer(size=stream_pv_size, data_type=stream_pv_type) stream_fifo._setSlave(data_buffer) #pyrogue.streamTap(fpga.stream.application(0x80 + i), stream_fifo) # Variable to read the stream data stream_var = pyrogue.LocalVariable( name='Stream{}'.format(i), description='Stream {}'.format(i), mode='RO', value=0, localGet=data_buffer.read, update=False, hidden=True) # Set the buffer callback to update the variable data_buffer.set_callback(stream_var.updated) # Variable to set the data format data_format_var = pyrogue.LocalVariable( name='StreamDataFormat{}'.format(i), description='Type of data being unpacked', mode='RW', value=0, enum={ i: j for i, j in enumerate( data_buffer.get_data_format_list()) }, localSet=data_buffer.set_data_format, localGet=data_buffer.get_data_format, hidden=True) # Variable to set the data byte order byte_order_var = pyrogue.LocalVariable( name='StreamDataByteOrder{}'.format(i), description='Byte order of data being unpacked', mode='RW', value=0, enum={ i: j for i, j in enumerate( data_buffer.get_data_byte_order_list()) }, localSet=data_buffer.set_data_byte_order, localGet=data_buffer.get_data_byte_order, hidden=True) # Variable to read the data format string format_string_var = pyrogue.LocalVariable( name='StreamDataFormatString{}'.format(i), description='Format string used to unpack the data', mode='RO', value=0, localGet=data_buffer.get_data_format_string, hidden=True) # Add listener to update the format string readback variable # when the data format or data byte order is changed data_format_var.addListener(format_string_var) byte_order_var.addListener(format_string_var) # Add the local variable to self self.add(stream_var) self.add(data_format_var) self.add(byte_order_var) self.add(format_string_var) # lcaPut limits the maximun lenght of a string to 40 chars, as defined # in the EPICS R3.14 CA reference manual. This won't allowed to use the # command 'ReadConfig' with a long file path, which is usually the case. # This function is a workaround to that problem. Fomr matlab one can # just call this function without arguments an the function ReadConfig # will be called with a predefined file passed during startup # However, it can be usefull also win the GUI, so it is always added. self.config_file = config_file self.add( pyrogue.LocalCommand(name='setDefaults', description='Set default configuration', function=self.set_defaults_cmd)) self.add( pyrogue.LocalCommand(name='runGarbageCollection', description='runGarbageCollection', function=self.run_garbage_collection)) self.add( pyrogue.LocalVariable( name='smurfProcessorDebug', description='Enable smurf processor transmit debug', mode='RW', value=False, localSet=lambda value: self.my_processor.setDebug(value), hidden=False)) # Start the root if group_name: # Start with Pyro4 server host_name = get_host_name() print( "Starting rogue server with Pyro using group name \"{}\"". format(group_name)) self.start(pollEn=polling_en, pyroGroup=group_name, pyroHost=host_name, pyroNs=None) else: # Start without Pyro4 server print("Starting rogue server") self.start(pollEn=polling_en) self.ReadAll() except KeyboardInterrupt: print("Killing server creation...") super(LocalServer, self).stop() exit() # Show image build information try: print("") print("FPGA image build information:") print("===================================") print("BuildStamp : {}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.BuildStamp.get())) print("FPGA Version : 0x{:x}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.FpgaVersion.get())) print("Git hash : 0x{:x}"\ .format(self.FpgaTopLevel.AmcCarrierCore.AxiVersion.GitHash.get())) except AttributeError as attr_error: print("Attibute error: {}".format(attr_error)) print("") # Start the EPICS server if epics_prefix: print("Starting EPICS server using prefix \"{}\"".format( epics_prefix)) # Choose the appropiate epics module: if use_pcas: self.epics = pyrogue.epics.EpicsCaServer(base=epics_prefix, root=self) else: self.epics = pyrogue.protocols.epics.EpicsCaServer( base=epics_prefix, root=self) # PVs for stream data, used on GDD-based EPICS server if stream_pv_size: print("Enabling stream data on PVs (buffer size = {} points, data type = {})"\ .format(stream_pv_size,stream_pv_type)) for i in range(8): stream_slave = self.epics.createSlave( name="AMCc:Stream{}".format(i), maxSize=stream_pv_size, type=stream_pv_type) # Calculate number of bytes needed on the fifo if '16' in stream_pv_type: fifo_size = stream_pv_size * 2 else: fifo_size = stream_pv_size * 4 stream_fifo = rogue.interfaces.stream.Fifo( 0, fifo_size, 0) # chnages stream_fifo._setSlave(stream_slave) pyrogue.streamTap(fpga.stream.application(0x80 + i), stream_fifo) self.epics.start() # Dump the PV list to the especified file if pv_dump_file: try: # Try to open the output file f = open(pv_dump_file, "w") except IOError: print("Could not open the PV dump file \"{}\"".format( pv_dump_file)) else: with f: print("Dumping PV list to \"{}\"...".format( pv_dump_file)) try: try: # Redirect the stdout to the output file momentarily original_stdout, sys.stdout = sys.stdout, f self.epics.dump() finally: sys.stdout = original_stdout print("Done!") except: # Capture error from epics.dump() if any print("Errors were found during epics.dump()") # If no in server Mode, start the GUI if not server_mode: create_gui(self) else: # Stop the server when Crtl+C is pressed print("") print("Running in server mode now. Press Ctrl+C to stop...") try: # Wait for Ctrl+C while True: time.sleep(1) except KeyboardInterrupt: pass
def __init__( self, name="AxiMicronN25Q", description="AXI-Lite Micron N25Q and Micron MT25Q PROM", addrMode=False, # False = 24-bit Address mode, True = 32-bit Address Mode tryCount=5, **kwargs): super().__init__(name=name, description=description, size=(0x1 << 10), **kwargs) self._mcs = misc.McsReader() self._addrMode = addrMode self._progDone = False self._tryCount = tryCount ############################## # Constants ############################## self.READ_3BYTE_CMD = (0x03 << 16) self.READ_4BYTE_CMD = (0x13 << 16) self.FLAG_STATUS_REG = (0x70 << 16) self.FLAG_STATUS_RDY = (0x80) self.WRITE_ENABLE_CMD = (0x06 << 16) self.WRITE_DISABLE_CMD = (0x04 << 16) self.ADDR_ENTER_CMD = (0xB7 << 16) self.ADDR_EXIT_CMD = (0xE9 << 16) self.ERASE_CMD = (0xD8 << 16) self.WRITE_CMD = (0x02 << 16) self.STATUS_REG_WR_CMD = (0x01 << 16) self.STATUS_REG_RD_CMD = (0x05 << 16) self.DEV_ID_RD_CMD = (0x9F << 16) self.WRITE_NONVOLATILE_CONFIG = (0xB1 << 16) self.WRITE_VOLATILE_CONFIG = (0x81 << 16) self.READ_NONVOLATILE_CONFIG = (0xB5 << 16) self.READ_VOLATILE_CONFIG = (0x85 << 16) ########################## ## Configuration Register: ########################## ## BIT[15:12] Number of dummy clock cycles = 0xF (default) ## BIT[11:09] XIP mode at power-on reset = 0x7 (default) ## BIT[08:06] Output driver strength = x7 (default) ## BIT[05:05] Double transfer rate protocol = 0x1 (default) ## BIT[04:04] Reset/hold = 0x1 (default) ## BIT[03:03] Quad I/O protocol = 0x1 (default) ## BIT[02:02] Dual I/O protocol = 0x1 (default) ## BIT[01:01] 128Mb segment select = 0x1 (default) ## BIT[00:00] 1 = Enable 3-byte address mode (default) ## BIT[00:00] 0 = Enable 4-byte address mode self.DEFAULT_3BYTE_CONFIG = 0xFFFF self.DEFAULT_4BYTE_CONFIG = 0xFFFE self.READ_MASK = 0x00000000 self.WRITE_MASK = 0x80000000 self.VERIFY_MASK = 0x40000000 self.add( pr.LocalCommand( name='LoadMcsFile', function=self._LoadMcsFile, description='Load the .MCS into PROM', value='', ))
def __init__(self, *, argVariable=None, returnVariable=None, function=None, **kwargs): pr.Device.__init__(self, **kwargs) self._lock = threading.Lock() self._thread = None self._runEn = False self._argVar = argVariable self._retVar = returnVariable self._function = function self._functionWrap = pr.functionWrapper( function=self._function, callArgs=['root', 'dev', 'arg']) self.add( pr.LocalCommand(name='Start', function=self._startProcess, description='Start process.')) self.add( pr.LocalCommand(name='Stop', function=self._stopProcess, description='Stop process.')) self.add( pr.LocalVariable(name='Running', mode='RO', value=False, pollInterval=1.0, description='Operation is running.')) self.add( pr.LocalVariable(name='Progress', mode='RO', units='Pct', value=0.0, disp='{:1.2f}', minimum=0.0, maximum=1.0, pollInterval=1.0, description='Percent complete: 0.0 - 1.0.')) self.add( pr.LocalVariable( name='Message', mode='RO', value='', pollInterval=1.0, description= 'Process status message. Prefix with Error: if an error occurred.' )) # Add arg variable if not already added if self._argVar is not None and self._argVar not in self: self.add(self._argVar) # Add return variable if not already added if self._retVar is not None and self._retVar not in self: self.add(self._retVar)