LLRF BSA IOC Novelty

The intended functionality of this IOC is to allow users to define PVs of variable bitwidths in the startup .cmd script.  Up until now, only 32-bit datatypes were accommodated (i.e. int32, uint32 and float32).  With this update, the following types are supported: uint2, uint16, int32, uint32 and float32.  Other types (always lower than 32 bits) can be added later on as needed.  Note that the software does not support types with bitwidths larger than 32.

Background Technical Information

In the following sections you will find a table with useful acronyms, a high-level overview of the data flow eventually reaching the LLRF BSA IOC and the specific formats of data payloads crossing various interfaces.

Acronyms

TermDescription

AMC

Advanced Mezzanine Card

ATCA

Advanced Telecommunications Computing Architecture

BSA

Beam Synchronous Acquisition

EPICS

Experimental Physics and Industrial Control System

FPGA

Field Programmable Gate Array

I / Q

In phase / In quadrature RF data

IOC

Input Output Controller

LLRF

Low Level Radio Frequency

MPS

Machine Protection System

PRC

Precision Receiver Chassis

The Big Picture

In the figure below, one can see a high level view of the system starting from the LLRF rack with the RF cavities and the Precision Receiver Chassis (PRC), to the AMC card and the carrier FPGA, leading ultimately to the EPICS-based IOC software running on a real-time Linux host machine.

An LLRF system consists of a multitude of RF stations and Precision Receiver Chassis.  An RF station generates the accelerating RF fields for its respective cavities.  A Precision Receiver Chassis collects RF measurements in terms of amplitudes and phases (referred to as BSA data) and --along with MPS data (machine status bits)-- passes them on to the ATCA board via a fiber link.  The data is stored temporarily in the FPGA DRAM until the software retrieves them.  From that point on, a typical ATCA-based acquisition system is set up to transfer the data via a typical UDP/RSSI interface and thus make them available to higher-level applications as regular EPICS PVs or in the form of NTTables.


LLRF_BSA_Overview

LLRF Rack Data Message Format

See below the data message format as seen by the firmware on the receiving end of the fiber link (ATCA AMC board).



Overall, each PRC will send 4 in-phase (i.e. I) and 4 quadrature (i.e. Q) 32-bit signals for each of the 4 cavities.  Hence, overall 32 BSA quantities (or signals) will be sent across to the SLAC ATCA system.  The firmware will then drop the lower 16 bits for each of these quantities, keeping only the upper 16 bits for a more economical management of the firmware resources.  Then, pairs of time-aligned 16-bit I and Q signals will be merged together to generate a 32-bit word that will be ultimately stored in the FPGA DRAM for retrieval later.  Once communication with software is established, these 32-bit values will be dumped on the diagnostic bus for transmission across the RSSI interface.

Firmware Diagnostic Bus Data Message Format

See below the format of the data message provided to software by the firmware, following the aforementioned pre-processing and temporary storage in the FPGA DRAM.



Overall, BSA quantities from 4 PRCs, hence from 16 cavities, are contained on the bus.  Current testing confirms that only channels with indices 0 to 23 on the bus will be populated with data (i.e. the first 24 channels), with the remaining 7 channels being unused.  Please note that among the first 24 channels, there are 8 spare channels with no meaningful data.  Those are clearly marked on the above data-layout map for the diagnostic-bus.

Integration With SharedPlatform (SP)

In the next few sub-sections, one can find references to the required databases, drivers and environment variables needed to successfully run this IOC.

Environment Variables

Environment variables to be defined in your startup script.

# ATCA env variables
epicsEnvSet("LOCA", "B15")
epicsEnvSet("LOCA_INDEX", "01")
epicsEnvSet("LOCATION", "cpu-b15-sp02")
epicsEnvSet("IOC_NAME", "SIOC:${LOCA}:RF23")
epicsEnvSet("SLOT", "5")
epicsEnvSet("FPGA_IP", "10.0.1.10${SLOT}")

epicsEnvSet("YAML_DIR"          ,"${IOC_DATA}/${IOC}/yaml")
epicsEnvSet("YAML_FILE"         ,"${YAML_DIR}/000TopLevel.yaml")
epicsEnvSet("YAML_DEFAULTS_FILE","${YAML_DIR}/config/defaults.yaml")
epicsEnvSet("YAML_LOCAL_DIR"    ,"firmware/AmcCarrierLlrfBsaMpsMsgRx/hash-0x04010000/")
epicsEnvSet("L2MPSASYN_PORT","L2MPSASYN_PORT")

# Load record instances
epicsEnvSet("SYS_PV", "TST:${LOCA}:RF23")
epicsEnvSet("IOC_PV", "SIOC:${LOCA}:RF23")
 
# GLOBAL macros for BSSS/BSAS
epicsEnvSet("GLOBAL_BSSS","TPG:B15:0")
epicsEnvSet("GLOBAL_BSAS","BSAS:B15:0")

# iocAdmin environment variables
epicsEnvSet("ENGINEER"   , "Marcio Donadio")
epicsEnvSet("IOC_RESTORE", "${IOC_DATA}/${IOC}/restore")
epicsEnvSet("IOC_BOOT"   , "${EPICS_IOC_APP}")
epicsEnvSet("STARTUP"    , "${EPICS_IOCS}/${IOC}")
epicsEnvSet("ST_CMD"     , "startup.cmd")
 
# Define subsystem, used by iocLogPrefix
epicsEnvSet("SUBSYS","b15")

# For large BSA waveforms
epicsEnvSet("EPICS_CA_MAX_ARRAY_BYTES", "21000000")

Standard Databases

Typical EPICS databases required by most IOCs.

#==============================================================
# Load standard databases
#==============================================================
cd ${TOP}
dbLoadDatabase("dbd/SharedPlatform.dbd")
SharedPlatform_registerRecordDeviceDriver(pdbbase)
 
# Load IOC Administration Databse
dbLoadRecords("db/iocAdminSoft.db","IOC=${IOC_NAME}")
 
# The following database is a result of a python parser
# which looks at RELEASE_SITE and RELEASE to discover
# versions of software your IOC is referencing
# The python parser is part of iocAdmin
dbLoadRecords("db/iocRelease.db"  ,"IOC=${IOC_NAME}")

# Timing related records:
dbLoadRecords("db/tprTrig.db",      "DEV=${IOC_PV}:0,LOCA=B15,IOC_UNIT=RF23,INST=0,PORT=trig0")

# Crossbar control record:
dbLoadRecords("db/crossbarCtrl.db", "DEV=${IOC_PV}:0,LOCA=B15,IOC_UNIT=RF23,INST=0,PORT=crossbar0")

YAML Files

Accessing and loading the YAML files.

# Change directory to YAML directory
cd ${YAML_DIR}
pwd()
 
# Download the YAML files from the FPGA
DownloadYamlFile("${FPGA_IP}", "${YAML_DIR}")

# Load FPGA hierarchy from YAML
cpswLoadYamlFile("${YAML_FILE}", "NetIODev", "", "${FPGA_IP}", "MyRoot0")

# ======================================================
# disable BLD/BSSS/BSAS temporally
# until the iocInit process is completed
# the services will be restored back by its control PVs
# =======================================================
cd ("${IOC_DATA}/${IOC}/yamlConfig")
cpswLoadConfigFile("./disable_bld_bsss_bsas.yaml", "mmio/AmcCarrierCore/AmcCarrierBsa")

Standard Asyn Drivers

Running the crossbarControl and tprTrigger Asyn drivers.

# Crossbar control Asyn driver 
crossbarControlAsynDriverConfigure("crossbar0", "mmio/AmcCarrierCore/AxiSy56040", "MyRoot0")

# Tpr trigger Asyn driver
tprTriggerAsynDriverConfigure("trig0", "mmio/AmcCarrierCore", "MyRoot0")

Adding BSA Channels

To add BSA channels for the phase and amplitude of a cavity associated with a link, the phase and amplitude need to be defined consecutively.   


For instance, the following two ways of defining the amp and phase PVs are correct:

addBsa("LINK1CAV1AMP",   "llrfAmp")
addBsa("LINK1CAV1PHASE", "llrfPhase") 

or 

addBsa("LINK1CAV1PHASE", "llrfPhase") 
addBsa("LINK1CAV1AMP",   "llrfAmp")
 


However, these two below are incorrect and the IOC will terminate :

addBsa("LINK1CAV1AMP", "llrfAmp")
addBsa("LINK1CAV2AMP", "llrfAmp") 

or

addBsa("LINK1CAV1PHASE", "llrfPhase") 
addBsa("LINK1CAV2PHASE", "llrfPhase")
 


Overall, for LLRF BSA, the software channels or PVs are defined as shown below:

# =================================================
# BSA Channels should use no more than 31 x 32 bits
# =================================================
addBsa("LINK1CAV1AMP",   "llrfAmp")
addBsa("LINK1CAV1PHASE", "llrfPhase")
addBsa("LINK1CAV2AMP",   "llrfAmp")
addBsa("LINK1CAV2PHASE", "llrfPhase")
addBsa("LINK1CAV3AMP",   "llrfAmp")
addBsa("LINK1CAV3PHASE", "llrfPhase")
addBsa("LINK1CAV4AMP",   "llrfAmp")
addBsa("LINK1CAV4PHASE", "llrfPhase")
addBsa("LINK1SPARE1",    "uint32")
addBsa("LINK1SPARE2",    "uint32")
addBsa("LINK2CAV1AMP",   "llrfAmp")
addBsa("LINK2CAV1PHASE", "llrfPhase")
addBsa("LINK2CAV2AMP",   "llrfAmp")
addBsa("LINK2CAV2PHASE", "llrfPhase")
addBsa("LINK2CAV3AMP",   "llrfAmp")
addBsa("LINK2CAV3PHASE", "llrfPhase")
addBsa("LINK2CAV4AMP",   "llrfAmp")
addBsa("LINK2CAV4PHASE", "llrfPhase")
addBsa("LINK2SPARE1",    "uint32")
addBsa("LINK2SPARE2",    "uint32")
addBsa("LINK3CAV1AMP",   "llrfAmp")
addBsa("LINK3CAV1PHASE", "llrfPhase")
addBsa("LINK3CAV2AMP",   "llrfAmp")
addBsa("LINK3CAV2PHASE", "llrfPhase")
addBsa("LINK3CAV3AMP",   "llrfAmp")
addBsa("LINK3CAV3PHASE", "llrfPhase")
addBsa("LINK3CAV4AMP",   "llrfAmp")
addBsa("LINK3CAV4PHASE", "llrfPhase")
addBsa("LINK3SPARE1",    "uint32")
addBsa("LINK3SPARE2",    "uint32")
addBsa("LINK4CAV1AMP",   "llrfAmp")
addBsa("LINK4CAV1PHASE", "llrfPhase")
addBsa("LINK4CAV2AMP",   "llrfAmp")
addBsa("LINK4CAV2PHASE", "llrfPhase")
addBsa("LINK4CAV3AMP",   "llrfAmp")
addBsa("LINK4CAV3PHASE", "llrfPhase")
addBsa("LINK4CAV4AMP",   "llrfAmp")
addBsa("LINK4CAV4PHASE", "llrfPhase")                                                                                        
addBsa("LINK4SPARE1",    "uint32")
addBsa("LINK4SPARE2",    "uint32")

Adding BSSS Channels

To add BSSS channels, simply associate BSSS with the BSA port and the copying will be done automatically.

#  Initialize BSSS driver
#  make association with BSA channels: bsssAssociateBsaChannels(<BSA port name>)
bsssAssociateBsaChannels("bsaPort")

Adding BSAS Channels

Similarly for BSAS, with the difference that the user may select to import a limited number of channels to BSAS.

#  Initialize BSSS driver
#  make association with BSA channels: bsssAssociateBsaChannels(<BSA port name>)
bsasAssociateBsaChannels("bsaPort")

# base name assign for the BSAS channels
# bsasBaseName(<BSAS data channel, BsaKey>, <base PV name>)
bsasBaseName("LINK1CAV1AMP",   "${SYS_PV}:LINK1CAV1AMP")
bsasBaseName("LINK1CAV1PHASE", "${SYS_PV}:LINK1CAV1PHASE")
bsasBaseName("LINK1CAV2AMP",   "${SYS_PV}:LINK1CAV2AMP")
bsasBaseName("LINK1CAV2PHASE", "${SYS_PV}:LINK1CAV2PHASE")
bsasBaseName("LINK1CAV3AMP",   "${SYS_PV}:LINK1CAV3AMP")
bsasBaseName("LINK1CAV3PHASE", "${SYS_PV}:LINK1CAV3PHASE")
bsasBaseName("LINK1CAV4AMP",   "${SYS_PV}:LINK1CAV4AMP")
bsasBaseName("LINK1CAV4PHASE", "${SYS_PV}:LINK1CAV4PHASE")
bsasBaseName("LINK1SPARE1",    "${SYS_PV}:LINK1SPARE1")
bsasBaseName("LINK1SPARE2",    "${SYS_PV}:LINK1SPARE2")
bsasBaseName("LINK2CAV1AMP",   "${SYS_PV}:LINK2CAV1AMP")
bsasBaseName("LINK2CAV1PHASE", "${SYS_PV}:LINK2CAV1PHASE")
bsasBaseName("LINK2CAV2AMP",   "${SYS_PV}:LINK2CAV2AMP")
bsasBaseName("LINK2CAV2PHASE", "${SYS_PV}:LINK2CAV2PHASE")
bsasBaseName("LINK2CAV3AMP",   "${SYS_PV}:LINK2CAV3AMP")
bsasBaseName("LINK2CAV3PHASE", "${SYS_PV}:LINK2CAV3PHASE")
bsasBaseName("LINK2CAV4AMP",   "${SYS_PV}:LINK2CAV4AMP")
bsasBaseName("LINK2CAV4PHASE", "${SYS_PV}:LINK2CAV4PHASE")
bsasBaseName("LINK2SPARE1",    "${SYS_PV}:LINK2SPARE1")
bsasBaseName("LINK2SPARE2",    "${SYS_PV}:LINK2SPARE2")
bsasBaseName("LINK3CAV1AMP",   "${SYS_PV}:LINK3CAV1AMP")
bsasBaseName("LINK3CAV1PHASE", "${SYS_PV}:LINK3CAV1PHASE")
bsasBaseName("LINK3CAV2AMP",   "${SYS_PV}:LINK3CAV2AMP")
bsasBaseName("LINK3CAV2PHASE", "${SYS_PV}:LINK3CAV2PHASE")
bsasBaseName("LINK3CAV3AMP",   "${SYS_PV}:LINK3CAV3AMP")
bsasBaseName("LINK3CAV3PHASE", "${SYS_PV}:LINK3CAV3PHASE")
bsasBaseName("LINK3CAV4AMP",   "${SYS_PV}:LINK3CAV4AMP")
bsasBaseName("LINK3CAV4PHASE", "${SYS_PV}:LINK3CAV4PHASE")
bsasBaseName("LINK3SPARE1",    "${SYS_PV}:LINK3SPARE1")
bsasBaseName("LINK3SPARE2",    "${SYS_PV}:LINK3SPARE2")
bsasBaseName("LINK4CAV1AMP",   "${SYS_PV}:LINK4CAV1AMP")
bsasBaseName("LINK4CAV1PHASE", "${SYS_PV}:LINK4CAV1PHASE")
bsasBaseName("LINK4CAV2AMP",   "${SYS_PV}:LINK4CAV2AMP")
bsasBaseName("LINK4CAV2PHASE", "${SYS_PV}:LINK4CAV2PHASE")
bsasBaseName("LINK4CAV3AMP",   "${SYS_PV}:LINK4CAV3AMP")
bsasBaseName("LINK4CAV3PHASE", "${SYS_PV}:LINK4CAV3PHASE")
bsasBaseName("LINK4CAV4AMP",   "${SYS_PV}:LINK4CAV4AMP")
bsasBaseName("LINK4CAV4PHASE", "${SYS_PV}:LINK4CAV4PHASE")
bsasBaseName("LINK4SPARE1",    "${SYS_PV}:LINK4SPARE1")
bsasBaseName("LINK4SPARE2",    "${SYS_PV}:LINK4SPARE2")

Acquisition Service Databases

TBD

BSA

Loading BSA databases/PVs.

# BSA PVs
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV1AMP,   SECN=LINK1CAV1AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV1PHASE, SECN=LINK1CAV1PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV2AMP,   SECN=LINK1CAV2AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV2PHASE, SECN=LINK1CAV2PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV3AMP,   SECN=LINK1CAV3AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV3PHASE, SECN=LINK1CAV3PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV4AMP,   SECN=LINK1CAV4AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1CAV4PHASE, SECN=LINK1CAV4PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1SPARE1,    SECN=LINK1SPARE1")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK1SPARE2,    SECN=LINK1SPARE2")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV1AMP,   SECN=LINK2CAV1AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV1PHASE, SECN=LINK2CAV1PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV2AMP,   SECN=LINK2CAV2AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV2PHASE, SECN=LINK2CAV2PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV3AMP,   SECN=LINK2CAV3AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV3PHASE, SECN=LINK2CAV3PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV4AMP,   SECN=LINK2CAV4AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2CAV4PHASE, SECN=LINK2CAV4PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2SPARE1,    SECN=LINK2SPARE1")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK2SPARE2,    SECN=LINK2SPARE2")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV1AMP,   SECN=LINK3CAV1AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV1PHASE, SECN=LINK3CAV1PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV2AMP,   SECN=LINK3CAV2AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV2PHASE, SECN=LINK3CAV2PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV3AMP,   SECN=LINK3CAV3AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV3PHASE, SECN=LINK3CAV3PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV4AMP,   SECN=LINK3CAV4AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3CAV4PHASE, SECN=LINK3CAV4PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3SPARE1,    SECN=LINK3SPARE1")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK3SPARE2,    SECN=LINK3SPARE2")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK4CAV1AMP,   SECN=LINK4CAV1AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK4CAV1PHASE, SECN=LINK4CAV1PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK4CAV2AMP,   SECN=LINK4CAV2AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK4CAV2PHASE, SECN=LINK4CAV2PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK4CAV3AMP,   SECN=LINK4CAV3AMP")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK4CAV3PHASE, SECN=LINK4CAV3PHASE")
dbLoadRecords("db/bsa.db", "DEV=${SYS_PV},PORT=bsaPort,BSAKEY=LINK4CAV4AMP,   SECN=LINK4CAV4AMP")

BSSS

Loading BSSS databases/PVs.

# BSSS Control/Monintoring PVs
dbLoadRecords("db/bsssCtrl.db", "GLOBAL=${GLOBAL_BSSS},DEV=${SYS_PV},SERVICE=BSSS,PORT=bsssPort")

# BSSS Scalar PVs
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV1AMP,   SECN=LINK1CAV1AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV1PHASE, SECN=LINK1CAV1PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV2AMP,   SECN=LINK1CAV2AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV2PHASE, SECN=LINK1CAV2PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV3AMP,   SECN=LINK1CAV3AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV3PHASE, SECN=LINK1CAV3PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV4AMP,   SECN=LINK1CAV4AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1CAV4PHASE, SECN=LINK1CAV4PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1SPARE1,    SECN=LINK1SPARE1")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK1SPARE2,    SECN=LINK1SPARE2")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV1AMP,   SECN=LINK2CAV1AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV1PHASE, SECN=LINK2CAV1PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV2AMP,   SECN=LINK2CAV2AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV2PHASE, SECN=LINK2CAV2PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV3AMP,   SECN=LINK2CAV3AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV3PHASE, SECN=LINK2CAV3PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV4AMP,   SECN=LINK2CAV4AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2CAV4PHASE, SECN=LINK2CAV4PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2SPARE1,    SECN=LINK2SPARE1")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK2SPARE2,    SECN=LINK2SPARE2")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV1AMP,   SECN=LINK3CAV1AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV1PHASE, SECN=LINK3CAV1PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV2AMP,   SECN=LINK3CAV2AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV2PHASE, SECN=LINK3CAV2PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV3AMP,   SECN=LINK3CAV3AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV3PHASE, SECN=LINK3CAV3PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV4AMP,   SECN=LINK3CAV4AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3CAV4PHASE, SECN=LINK3CAV4PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3SPARE1,    SECN=LINK3SPARE1")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK3SPARE2,    SECN=LINK3SPARE2")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV1AMP,   SECN=LINK4CAV1AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV1PHASE, SECN=LINK4CAV1PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV2AMP,   SECN=LINK4CAV2AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV2PHASE, SECN=LINK4CAV2PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV3AMP,   SECN=LINK4CAV3AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV3PHASE, SECN=LINK4CAV3PHASE")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV4AMP,   SECN=LINK4CAV4AMP")
dbLoadRecords("db/bsss.db", "DEV=${SYS_PV},PORT=bsssPort,BSAKEY=LINK4CAV4PHASE, SECN=LINK4CAV4PHASE")                                                         

BSAS

Loading BSAS databases/PVs.

#BSAS Control/Monintoring PVs
dbLoadRecords("db/bsasCtrl.db", "GLOBAL=${GLOBAL_BSAS},DEV=${SYS_PV},PORT=bsasPort")
 
#BSAS Scalar PVs
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV1AMP,   SECN=LINK1CAV1AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV1PHASE, SECN=LINK1CAV1PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV2AMP,   SECN=LINK1CAV2AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV2PHASE, SECN=LINK1CAV2PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV3AMP,   SECN=LINK1CAV3AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV3PHASE, SECN=LINK1CAV3PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV4AMP,   SECN=LINK1CAV4AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1CAV4PHASE, SECN=LINK1CAV4PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1SPARE1,    SECN=LINK1SPARE1")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK1SPARE2,    SECN=LINK1SPARE2")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV1AMP,   SECN=LINK2CAV1AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV1PHASE, SECN=LINK2CAV1PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV2AMP,   SECN=LINK2CAV2AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV2PHASE, SECN=LINK2CAV2PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV3AMP,   SECN=LINK2CAV3AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV3PHASE, SECN=LINK2CAV3PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV4AMP,   SECN=LINK2CAV4AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2CAV4PHASE, SECN=LINK2CAV4PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2SPARE1,    SECN=LINK2SPARE1")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK2SPARE2,    SECN=LINK2SPARE2")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV1AMP,   SECN=LINK3CAV1AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV1PHASE, SECN=LINK3CAV1PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV2AMP,   SECN=LINK3CAV2AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV2PHASE, SECN=LINK3CAV2PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV3AMP,   SECN=LINK3CAV3AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV3PHASE, SECN=LINK3CAV3PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV4AMP,   SECN=LINK3CAV4AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3CAV4PHASE, SECN=LINK3CAV4PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3SPARE1,    SECN=LINK3SPARE1")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK3SPARE2,    SECN=LINK3SPARE2")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV1AMP,   SECN=LINK4CAV1AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV1PHASE, SECN=LINK4CAV1PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV2AMP,   SECN=LINK4CAV2AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV2PHASE, SECN=LINK4CAV2PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV3AMP,   SECN=LINK4CAV3AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV3PHASE, SECN=LINK4CAV3PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV4AMP,   SECN=LINK4CAV4AMP")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4CAV4PHASE, SECN=LINK4CAV4PHASE")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4SPARE1,    SECN=LINK4SPARE1")
dbLoadRecords("db/bsas.db", "DEV=${SYS_PV},PORT=bsasPort,BSAKEY=LINK4SPARE2,    SECN=LINK4SPARE2")

Acquisition Service Asyn Drivers

TBD

BSA

Run the BSA Asyn driver.

# Initialize the BSA driver
bsaAsynDriverConfigure("bsaPort", "mmio/AmcCarrierCore/AmcCarrierBsa","strm/AmcCarrierDRAM/dram")

BSSS

Run the BSSS Asyn driver

# configure BSSS driver: bsssAsynDriverConfigure(<bsss port>, <register path>)
bsssAsynDriverConfigure("bsssPort", "mmio/AmcCarrierCore/AmcCarrierBsa/Bsss")

BSAS

Run the BSAS Asyn driver.

# configure BSAS driver: bsasAsynDriverConfigure(<bsas port>, <register path>, <NTTable PV1>, <NTTable PV2>, <NTTable PV3>, <NTTable PV4>, [named_root (option    al)])
bsasAsynDriverConfigure("bsasPort", "mmio/AmcCarrierCore/AmcCarrierBsa/Bsas", "${SYS_PV}:SC_HXR", "${SYS_PV}:SC_SXR", "${SYS_PV}:SC_BSYD","${SYS_PV}:SC_DIAG0"     )

Crossbar Control Settings

Set the crossbar switch to backplane.

# crossbar control ('output', 'inpput')
#    output: 'RTM_OUT0' | 'FPGA' | 'BP' | 'RTM_OUT1'
#    input:  'RTM_IN0' ['LCLS1'] | 'FPGA' | 'BP' | 'RTM_IN1' ['LCLS2']
################################################################################
crossbarControl("FPGA", "BP")

Configure callback & scanOnce Queues

Use 12,000 as the size of the queues.

# Increase callback and scanOnce quese sizes
# Note: must do after db load but before iocInit
callbackSetQueueSize(12000)
scanOnceSetQueueSize(12000)

Conversion To Phases/Amplitudes

See the link below for a high-level view of the algorithm processing channel data.

LLRF - Amplitude & Phase Computation


In summary, the phase amplitude are calculated as shown below:

  • Amplitude  = sqrt( I2 + Q2 )
  • Phase = atan2( Q / I ) * 180.0 / π

Setting Channel Mask (BSAS/BSSS only)

A hardware channel will be disabled only if the user chooses to disable all software channels (i.e. PVs) associated with that hardware channel (i.e. all PVs that get their data from that hardware channel).  Until then, the hardware channel will be enabled and populating all dependent PVs with data as before.  

To set the mask for a particular BSAS/BSSS PV, one will need to set the appropriate PVs to the desired values.  For instance, see below the mask PVs corresponding to Link-1/Cav-4 Amplitude/Phase PVs (i.e. hardware channel 4, index = 3):

sioc-b15-rf23>dbgrep *LINK1CAV4*MASK*
TST:B15:RF23:LINK1CAV4AMPBSSSCHNMASK
TST:B15:RF23:LINK1CAV4PHASEBSSSCHNMASK
TST:B15:RF23:LINK1CAV4AMPBSASCHNMASK
TST:B15:RF23:LINK1CAV4PHASEBSASCHNMASK

Setting Channel Severity

The severity of a hardware channel will be set as soon as we set the severity of any of its software channels (i.e. any of the software channels, aka PVs, that get their data from that hardware channel).  Hence, changing the severity of one of the dependent PVs results in changing the severity of all dependent PVs.  

To set the severity for BSA, use the corresponding TPG screen for a particular BSA buffer.  To set the severity for BSAS/BSSS, it suffices to set the appropriate PVs.  For instance, see below the severity PVs corresponding to Link-1/Cav-4 Amplitude/Phase PVs (i.e. hardware channel 4, index = 3):

sioc-b15-rf23>dbgrep *LINK1CAV4*SEVR*
TST:B15:RF23:LINK1CAV4AMPBSSSCHNSEVR
TST:B15:RF23:LINK1CAV4PHASEBSSSCHNSEVR
TST:B15:RF23:LINK1CAV4AMPBSASCHNSEVR
TST:B15:RF23:LINK1CAV4PHASEBSASCHNSEVR

The BSA firmware will filter data based upon the channel severity comparison with the user's configuration.

The BSAS firmware will filter data based upon the channel severity equating to 0.
The BSSS firmware does not filter data, but it passes the severity to software.  Then the software proceeds to filter data out as needed.  This is done by comparing the data severity from firmware against the desired data severity selected by the user.


Verification Results

Verification of this IOC is performed on various fronts.  First, we verify that the splitting algorithm functions as expected.  Then, we look at verifying performance with respect to resource constraints such as memory used and thread CPU load (primarily).  After that, it is important to ensure that the user retains the ability to add and remove channels as needed.  For this, we look at verifying the firmware channel mask, following a change in a (software) PV.  Lastly, we verify computation of phases and amplitudes from their corresponding in-phase (I) and in-quadrature (Q) signals.

Data Partitioning Verification

For this test, we add BSA channels as shown below.  This stage of verification preceded the conversion of Is & Qs to phases and amplitudes.  The objective is to verify that the bit extraction is performed correctly.

addBsa("SIGNAL00",    "uint32" )
addBsa("SIGNAL01a",    "uint2" )
addBsa("SIGNAL01b",    "uint2" )
addBsa("SIGNAL01c",    "uint2" )
addBsa("SIGNAL01d",    "uint2" )
addBsa("SIGNAL01e",    "uint2" )
addBsa("SIGNAL01f",    "uint2" )
addBsa("SIGNAL01g",    "uint2" )
addBsa("SIGNAL01h",    "uint2" )
addBsa("SIGNAL01k",    "uint16")
addBsa("SIGNAL02a",    "uint16")
addBsa("SIGNAL02b",    "uint16")
addBsa("SIGNAL03",     "int32" )
addBsa("SIGNAL04",     "int32" )
...
addBsa("SIGNAL30",     "int32" )


The above are 40 BSA channels.  We will be looking to verify some of the following channels: 

SIGNAL01a, SIGNAL01b, SIGNAL01c, SIGNAL01d, SIGNAL01e, SIGNAL01f, SIGNAL01g, SIGNAL01h, SIGNAL01k, SIGNAL02a and SIGNAL02b.


Since the data we examine are simply counter values, hardware channels with indices 1, 2 and 3 were previously confirmed to have identical values.  This allows us to compare data extracted from channels with indices 1 or 2 with the original data in channel index 3.


1.  Data splitting for BSA - we look at all of the BSA channels SIGNAL01* and compare them with the original data (identical to data in SIGNAL03SCH1H).  Note that we start counting and extracting bits from the LSB position of the hardware channel data and in the order in which the BSA channels were defined in the IOC startup script.  The timestamped results below show that the splitting works as intended.

skoufis@lcls-dev3  $ camonitor TST:SYS2:04:SIGNAL01aHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01bHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01dHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01eHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01fHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01gHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01hHSTSCH1H.[-1] TST:SYS2:04:SIGNAL01kHSTSCH1H.[-1] TST:SYS2:04:SIGNAL03HSTSCH1H.[-1] -lb

TST:SYS2:04:SIGNAL01aHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 1  
TST:SYS2:04:SIGNAL01bHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 10  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 1  
TST:SYS2:04:SIGNAL01dHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 11  
TST:SYS2:04:SIGNAL01eHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 10  
TST:SYS2:04:SIGNAL01fHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 1  
TST:SYS2:04:SIGNAL01gHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 10  
TST:SYS2:04:SIGNAL01hHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 0  
TST:SYS2:04:SIGNAL01kHSTSCH1H.[-1] 2023-03-01 18:55:23.785349 1  
TST:SYS2:04:SIGNAL03HSTSCH1H.[-1] 2023-03-01 18:55:23.785349 10010011011011001

TST:SYS2:04:SIGNAL01aHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 1  
TST:SYS2:04:SIGNAL01bHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 10  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 11  
TST:SYS2:04:SIGNAL01dHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 11  
TST:SYS2:04:SIGNAL01eHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 10  
TST:SYS2:04:SIGNAL01fHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 1  
TST:SYS2:04:SIGNAL01gHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 11  
TST:SYS2:04:SIGNAL01hHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 1  
TST:SYS2:04:SIGNAL01kHSTSCH1H.[-1] 2023-03-01 18:55:29.665303 0  
TST:SYS2:04:SIGNAL03HSTSCH1H.[-1] 2023-03-01 18:55:29.665303 111011011111001
 
TST:SYS2:04:SIGNAL01aHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 1  
TST:SYS2:04:SIGNAL01bHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 10  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 0  
TST:SYS2:04:SIGNAL01dHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 11  
TST:SYS2:04:SIGNAL01eHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 1  
TST:SYS2:04:SIGNAL01fHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 10  
TST:SYS2:04:SIGNAL01gHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 10  
TST:SYS2:04:SIGNAL01hHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 10  
TST:SYS2:04:SIGNAL01kHSTSCH1H.[-1] 2023-03-01 18:55:36.525321 1  
TST:SYS2:04:SIGNAL03HSTSCH1H.[-1] 2023-03-01 18:55:36.525321 11010100111001001


2.  Data splitting for BSSS - we look at the BSSS channels SIGNAL01* and compare them with the original data (identical to data in SIGNAL03SCH1H). 

As before, we start splitting from the LSB position in the order in which the BSSS channels were defined in the IOC startup script.  Looking at the timestamped results, no issues were found.

skoufis@lcls-dev3  $ camonitor TST:SYS2:04:SIGNAL01aSCH1H TST:SYS2:04:SIGNAL01bSCH1H TST:SYS2:04:SIGNAL01cSCH1H TST:SYS2:04:SIGNAL01dSCH1H TST:SYS2:04:SIGNAL01eSCH1H TST:SYS2:04:SIGNAL01fSCH1H TST:SYS2:04:SIGNAL01gSCH1H TST:SYS2:04:SIGNAL01hSCH1H TST:SYS2:04:SIGNAL01kSCH1H TST:SYS2:04:SIGNAL03SCH1H -lb

TST:SYS2:04:SIGNAL01aSCH1H   2023-03-01 18:40:55.505267 1  
TST:SYS2:04:SIGNAL01bSCH1H   2023-03-01 18:40:55.505267 10  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 18:40:55.505267 11  
TST:SYS2:04:SIGNAL01dSCH1H   2023-03-01 18:40:55.505267 10  
TST:SYS2:04:SIGNAL01eSCH1H   2023-03-01 18:40:55.505267 1  
TST:SYS2:04:SIGNAL01fSCH1H   2023-03-01 18:40:55.505267 10  
TST:SYS2:04:SIGNAL01gSCH1H   2023-03-01 18:40:55.505267 1  
TST:SYS2:04:SIGNAL01hSCH1H   2023-03-01 18:40:55.505267 10  
TST:SYS2:04:SIGNAL01kSCH1H   2023-03-01 18:40:55.505267 0  
TST:SYS2:04:SIGNAL03SCH1H   2023-03-01 18:40:55.505267 1001100110111001
 
TST:SYS2:04:SIGNAL01aSCH1H   2023-03-01 18:40:56.485272 1  
TST:SYS2:04:SIGNAL01bSCH1H   2023-03-01 18:40:56.485272 10  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 18:40:56.485272 10  
TST:SYS2:04:SIGNAL01dSCH1H   2023-03-01 18:40:56.485272 1  
TST:SYS2:04:SIGNAL01eSCH1H   2023-03-01 18:40:56.485272 0  
TST:SYS2:04:SIGNAL01fSCH1H   2023-03-01 18:40:56.485272 11  
TST:SYS2:04:SIGNAL01gSCH1H   2023-03-01 18:40:56.485272 11  
TST:SYS2:04:SIGNAL01hSCH1H   2023-03-01 18:40:56.485272 1  
TST:SYS2:04:SIGNAL01kSCH1H   2023-03-01 18:40:56.485272 0  
TST:SYS2:04:SIGNAL03SCH1H   2023-03-01 18:40:56.485272 1111100011010

TST:SYS2:04:SIGNAL01aSCH1H   2023-03-01 18:40:57.465277 1  
TST:SYS2:04:SIGNAL01bSCH1H   2023-03-01 18:40:57.465277 10  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 18:40:57.465277 1  
TST:SYS2:04:SIGNAL01dSCH1H   2023-03-01 18:40:57.465277 0  
TST:SYS2:04:SIGNAL01eSCH1H   2023-03-01 18:40:57.465277 11  
TST:SYS2:04:SIGNAL01fSCH1H   2023-03-01 18:40:57.465277 11  
TST:SYS2:04:SIGNAL01gSCH1H   2023-03-01 18:40:57.465277 1  
TST:SYS2:04:SIGNAL01hSCH1H   2023-03-01 18:40:57.465277 1  
TST:SYS2:04:SIGNAL01kSCH1H   2023-03-01 18:40:57.465277 0  
TST:SYS2:04:SIGNAL03SCH1H   2023-03-01 18:40:57.465277 101111100011001


3.  Comparing BSA with BSSS - Note that the timestamps here don't match.  This is because of a latency inherent in the design.

skoufis@lcls-dev3  $ camonitor TST:SYS2:04:SIGNAL01cSCH1H TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1]

TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 19:02:06.565232 2  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 19:02:06.565302 2  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 19:02:12.445224 0  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 19:02:12.445294 0  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 19:02:18.325226 2  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 19:02:18.325296 2  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 19:02:24.205252 0  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 19:02:24.205322 0  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 19:02:30.085252 2  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 19:02:30.085322 2  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 19:02:35.965253 0  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 19:02:35.965323 0

4. Comparing BSA/BSSS with splitted data in BSAS - we get the following.

Note that we print the BSAS table with this command:

pvmonitor TST:SYS2:04:SC_HXR

(I) For BSA/BSSS SIGNAL01c:
skoufis@lcls-dev3  $ camonitor TST:SYS2:04:SIGNAL01cPIDSCH1H TST:SYS2:04:SIGNAL01cSCH1H TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1]

TST:SYS2:04:SIGNAL01cPIDSCH1H 2023-03-01 19:26:09.125322 291258015159960  
TST:SYS2:04:SIGNAL01cSCH1H   2023-03-01 19:26:09.125322 2  
TST:SYS2:04:SIGNAL01cHSTSCH1H.[-1] 2023-03-01 19:26:09.125392 2

For BSAS SIGNAL01c, we extract from the table:
secondsPastEpoch nanoseconds         pulseId             ... TST:SYS2:04:SIGNAL01c.VAL
      1046575569   125321905 291258015159960  ...                                                  2

(II) For BSA/BSSS SIGNAL01g:
skoufis@lcls-dev3  $ camonitor TST:SYS2:04:SIGNAL01gPIDSCH1H TST:SYS2:04:SIGNAL01gSCH1H TST:SYS2:04:SIGNAL01gHSTSCH1H.[-1]

TST:SYS2:04:SIGNAL01gPIDSCH1H 2023-03-01 19:41:35.225357 291258875109960  
TST:SYS2:04:SIGNAL01gSCH1H   2023-03-01 19:41:35.225357 1  
TST:SYS2:04:SIGNAL01gHSTSCH1H.[-1] 2023-03-01 19:41:35.225427 1

For BSAS SIGNAL01g, we extract from the table:
secondsPastEpoch nanoseconds         pulseId             ... TST:SYS2:04:SIGNAL01g.VAL
      1046576495   225357441 291258875109960 ...                                                  1

(III) For BSA/BSSS SIGNAL01k:
skoufis@lcls-dev3  $ camonitor TST:SYS2:04:SIGNAL01kPIDSCH1H TST:SYS2:04:SIGNAL01kSCH1H TST:SYS2:04:SIGNAL01kHSTSCH1H.[-1]

TST:SYS2:04:SIGNAL01kPIDSCH1H  2023-03-01 19:49:33.465302 291259319189960  
TST:SYS2:04:SIGNAL01kSCH1H     2023-03-01 19:49:33.465302 1  
TST:SYS2:04:SIGNAL01kHSTSCH1H.[-1] 2023-03-01 19:49:33.465372 1  

For BSAS SIGNAL01k, we extract from the table:
secondsPastEpoch nanoseconds         pulseId             ... TST:SYS2:04:SIGNAL01k.VAL
      1046576973   465302088 291259319189960 ...                                                  1

(IV) For BSA/BSSS signal SIGNAL02a:
skoufis@lcls-dev3  $ camonitor TST:SYS2:04:SIGNAL02aPIDSCH1H TST:SYS2:04:SIGNAL02aSCH1H TST:SYS2:04:SIGNAL02aHSTSCH1H.[-1]

TST:SYS2:04:SIGNAL02aPIDSCH1H  2023-03-01 19:55:14.505221 291259635869960  
TST:SYS2:04:SIGNAL02aSCH1H     2023-03-01 19:55:14.505221 40409  
TST:SYS2:04:SIGNAL02aHSTSCH1H.[-1] 2023-03-01 19:55:14.505291 40409  

For BSAS SIGNAL02a, we extract from the table:
secondsPastEpoch nanoseconds         pulseId             ... TST:SYS2:04:SIGNAL02a.VAL
      1046577314   505220931 291259635869960 ...                                          40409 (edited) 

Performance Constraints Verification

As far as performance, we look at memory usage and BSA thread CPU load.


Memory usage was measured to be 12.6G and no memory leaks were noted.

 PID  USER      PR  NI    VIRT    RES  %CPU  %MEM     TIME+ S COMMAND                                                                                            
 9167 laci      20   0   12.6g   9.7g  19.2  62.4 895:13.36 S      `- /afs/slac/g/lcls/epics/iocCommon/sioc-b15-rf23/iocSpecificRelease/iocBoot/dev/sioc-b15-rf2+


The BSA CPU thread load stabilized at 11.9% 24 hours after IOC boot up.

[ laci@cpu-b15-sp02]$ ps -Leo pid,ppid,tid,rtprio,pcpu,stat,comm,nwchan,wchan | grep bsaDrvPoll
 9167  9166  9226     50 11.9 SLsl+ bsaDrvPoll          1 hrtimer_nanosleep

Channel Mask Setting Verification (BSAS/BSSS)

This test is to verify that the user-requested channel disabling works as expected, although under certain constraints. (TBD)

Channel Severity Setting Verification

This test is to verify that the user-requested channel severity works as expected. (TBD)

LLRF Rack Phase & Amplitude Verification

This test is to verify (together with the LLRF team) that the amplitudes and phases obtained on the software side match the LLRF rack settings. (TBD)

Deliverables - Tagged Releases

Package

Refer to package timing/bsa R2.4.0-XX

Module

Refer to module bsaDriver R3.1.0-XX

Firmware

Refer to tag release AmcCarrierLlrfBsaMpsMsgRx v4.1.1

Find the firmware release page here https://github.com/slaclab/lcls2-llrf/releases


  • No labels