From ef23f44e06d37d38ac220a43cae68f22bfb13bfd Mon Sep 17 00:00:00 2001 From: Mauricio Donatti Date: Wed, 27 Sep 2023 14:26:51 -0300 Subject: [PATCH 1/6] .gitignore: add python cache files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 9db9870..b90863a 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ documentation/*/*.log documentation/*/*.out documentation/*/*.toc documentation/*/*.pdf + +# Python cache files +*.pyc \ No newline at end of file From 8be7665a8ab2cb5001be797bec07b26f7b9c7a61 Mon Sep 17 00:00:00 2001 From: Mauricio Donatti Date: Mon, 18 Sep 2023 10:06:51 -0300 Subject: [PATCH 2/6] sinap_socket.py: add script to test sinap socket the socket can be tested using UDP forcing local port or not and TCP --- scripts/get_status_firmware.py | 18 ++++ scripts/lib/sinap.py | 158 +++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100755 scripts/get_status_firmware.py create mode 100644 scripts/lib/sinap.py diff --git a/scripts/get_status_firmware.py b/scripts/get_status_firmware.py new file mode 100755 index 0000000..056ba39 --- /dev/null +++ b/scripts/get_status_firmware.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +from lib.sinap import EVO +import argparse + +parser = argparse.ArgumentParser(description="Read SINAP device status and hostname") +parser.add_argument("hostname", help="pass hostname (or ip) as first argument") +parser.add_argument("-p","--port", type=int, default=50132, help="Pass server port integer") +parser.add_argument("-P","--protocol",choices=['tcp', 'udp', 'udp-force-local'], default='tcp', help="pass protocol") +parser.add_argument("--header", default=True, action="store_true", help="select if header should be software appended") + +args = parser.parse_args() + +#Standard constructor use TCP socket and header True, with socket port 50132 +evr = EVO(args.hostname,port = args.port,protocol = args.protocol,header = args.header) +evr.ReadStatus() +evr.ReadVersion() +evr.close() \ No newline at end of file diff --git a/scripts/lib/sinap.py b/scripts/lib/sinap.py new file mode 100644 index 0000000..f254530 --- /dev/null +++ b/scripts/lib/sinap.py @@ -0,0 +1,158 @@ +import socket +import time + +class EVO(object): + def __init__(self, ip, port=50132,wait_time=0.001,protocol='tcp',header=True): + self.ip = ip + self.port = port + self.wait_time = wait_time + self.protocol = protocol + self.include_header = header + print ('EVO -> IP address: ', self.ip, '\tPort: ', self.port) + if self.protocol == 'udp-force-local': + self.socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + self.socket.bind(('', self.port)) + elif self.protocol == 'udp': + self.socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + elif self.protocol == 'tcp': + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.connect((self.ip, self.port)) + else: + print("Protocol not supported: using 'udp'") + self.socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + self.protocol = 'udp' + self.socket.settimeout(5) + + + + def Write(self,address, regA, regB, regC): + # Write + cmd = chr(0x40|address)+chr(regA[0])+chr(regA[1])+chr(regA[2])+chr(regA[3])+chr(regB[0])+chr(regB[1])+chr(regB[2])+chr(regB[3])+chr(regC[0])+chr(regC[1])+chr(regC[2])+chr(regC[3]) + if self.protocol == 'udp-force-local': + self.socket.sendto(bytes(cmd, 'latin-1'), (self.ip,self.port)) + elif self.protocol == 'udp': + self.socket.sendto(bytes(cmd, 'latin-1'), (self.ip,self.port)) + else: + self.socket.sendall(bytes(cmd, 'latin-1')) + time.sleep(self.wait_time) + + def Read(self,address): + # Read + cmd = chr(0x80|address)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0) + + if self.protocol == 'udp-force-local': + if self.include_header == False: + self.socket.sendto(bytes(cmd, 'latin-1'),(self.ip,self.port)) + else: + self.socket.sendto(bytes.fromhex('020A0A0A79000D')+bytes(cmd, 'latin-1'),(self.ip,self.port)) + data, addr = self.socket.recvfrom(20) # buffer size is 13 bytes or 20 bytes if header has been included + elif self.protocol == 'udp': + if self.include_header == False: + self.socket.sendto(bytes(cmd, 'latin-1'),(self.ip,self.port)) + else: + self.socket.sendto(bytes.fromhex('020A0A0A79000D')+bytes(cmd, 'latin-1'),(self.ip,self.port)) + data, addr = self.socket.recvfrom(30) # buffer size is 13 bytes or 20 bytes if header has been included + else: + if self.include_header == False: + self.socket.sendall(bytes(cmd, 'latin-1')) + else: + self.socket.sendall(bytes.fromhex('020A0A0A79000D')+bytes(cmd, 'latin-1')) + data = self.socket.recv(20) # buffer size is 13 bytes or 20 bytes if header has been included + expected_len=20 if self.include_header==True else 13 + while len(data) < expected_len: + data += self.socket.recv(20) + print("Data length: %d"%len(data)) + if len(data) == 20: #Remove header + data = data[7:] + print("Corrected Data length: %d"%len(data)) + regA = [((data[1])),((data[2])),((data[3])),((data[4]))] + regB = [((data[5])),((data[6])),((data[7])),((data[8]))] + regC = [((data[9])),((data[10])),((data[11])),((data[12]))] + + return regA, regB, regC + + def ReadStatus(self): + print("\n\n\r***********************************************************************") + print ('EVO -> IP address: ', self.ip, '\tPort: ', self.port) + regA, regB, regC = self.Read(63) # Configuration Register + # function selection + self.FUNSEL = (regC[3] & 0b11) + self.RFDIV = (regB[1] & 0b1111) + 1 + + if self.FUNSEL == 0: + self.mode = 'FOUT' + elif self.FUNSEL == 1: + self.mode = 'EVR' + elif self.FUNSEL == 2: + self.mode = 'EVG' + else: + self.mode = 'unknown' + + print ('EVO Module Function: %s'%self.mode) + print ('RF divider: ', self.RFDIV) + + def ReadVersion(self): + regA, regB, regC = self.Read(62) # Configuration Register + print("Commit hash version: %s"%bytes(regA+regB+regC).hex()) + + + def close(self): + self.socket.close() + + +class EVG(EVO): + def __init__(self, ip, port=50132,wait_time=0.001): + EVO.__init__(self,ip,port,wait_time) + self.enable(0,0) + self.set_rfdiv(4) + self.enable(1,1) + time.sleep(0.1) + + def ReadStatus(self): + EVO.ReadStatus(self) + if (self.mode == 'EVG'): # EVG + #======================= Control and Status Register + regA, regB, regC = self.Read(0) + self.EVGEN = regC[3] & 0b1 + self.SEQEN = regC[3] & 0b10 + self.SEQS = (regC[2] & 0b11000)>>3 + self.RFINS = regC[2] >> 5 + + #======================= AC line setting Register + regA, regB, regC = self.Read(40) + self.ACEN = regA[3] & 0b1 + self.ACDIV = (regC[0]<<24)+(regC[1]<<16)+(regC[2]<<8)+regC[3] + 1 + + #======================= MUX0 setting Register + self.MUXEN = [0,0,0,0,0,0,0,0] + self.MUXDIV = [0,0,0,0,0,0,0,0] + for i in range(8): + regA, regB, regC = self.Read(41+i) + self.MUXEN[i] = regA[3] & 0b1 + self.MUXDIV[i] = (regC[0]<<24)+(regC[1]<<16)+(regC[2]<<8)+regC[3] + 1 + + #======================= SEQRAM switch Register + regA, regB, regC = self.Read(50) + self.SEQCOUNT = ((regC[2]&0b111111)<<8)+regC[3] + + print ('EVG enable: ', bool(self.EVGEN)) + print ('RF input: ', bool(self.RFINS), '\tRF divider: ', self.RFDIV) + print ('AC line enable: ', bool(self.ACEN), '\tAC line divider: ', self.ACDIV) + print ('SEQRAM enable: ', bool(self.SEQEN), '\tSEQRAM Status: ', self.SEQS, '\tSEQRAM Count: ', self.SEQCOUNT) + for i in range(8): + print ('Clock output '+str(i)+' -> Enable: ', self.MUXEN[i], '\tDivider: ', self.MUXDIV[i]) + + def set_rfdiv(self,RFDIV): + self.RFDIV = RFDIV + add = 63 + regA = [0,0,0,0] + regB = [0,RFDIV-1,0,0] + regC = [0,0,0,18] + self.Write(63, regA, regB, regC) + + def enable(self,seqen, evgen): + regA = [0,0,0,0] + regB = [0,0,0,0] + regC = [0,0,0,2*seqen+evgen] + + self.Write(0, regA, regB, regC) \ No newline at end of file From ee23384950da730aff313ba25451317636cd704f Mon Sep 17 00:00:00 2001 From: Mauricio Donatti Date: Tue, 7 Nov 2023 16:32:24 -0300 Subject: [PATCH 3/6] scripts: move socket scripts to socket dir --- scripts/{ => socket}/EVE.py | 0 scripts/{ => socket}/EVG.py | 0 scripts/{ => socket}/EVR.py | 0 scripts/{ => socket}/Find_Modules.py | 0 scripts/{ => socket}/get_status_firmware.py | 0 scripts/{ => socket}/lib/sinap.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename scripts/{ => socket}/EVE.py (100%) rename scripts/{ => socket}/EVG.py (100%) rename scripts/{ => socket}/EVR.py (100%) rename scripts/{ => socket}/Find_Modules.py (100%) rename scripts/{ => socket}/get_status_firmware.py (100%) rename scripts/{ => socket}/lib/sinap.py (100%) diff --git a/scripts/EVE.py b/scripts/socket/EVE.py similarity index 100% rename from scripts/EVE.py rename to scripts/socket/EVE.py diff --git a/scripts/EVG.py b/scripts/socket/EVG.py similarity index 100% rename from scripts/EVG.py rename to scripts/socket/EVG.py diff --git a/scripts/EVR.py b/scripts/socket/EVR.py similarity index 100% rename from scripts/EVR.py rename to scripts/socket/EVR.py diff --git a/scripts/Find_Modules.py b/scripts/socket/Find_Modules.py similarity index 100% rename from scripts/Find_Modules.py rename to scripts/socket/Find_Modules.py diff --git a/scripts/get_status_firmware.py b/scripts/socket/get_status_firmware.py similarity index 100% rename from scripts/get_status_firmware.py rename to scripts/socket/get_status_firmware.py diff --git a/scripts/lib/sinap.py b/scripts/socket/lib/sinap.py similarity index 100% rename from scripts/lib/sinap.py rename to scripts/socket/lib/sinap.py From bcb4e105a2b397deeb2eb224c489eed3ef774864 Mon Sep 17 00:00:00 2001 From: Mauricio Donatti Date: Tue, 7 Nov 2023 16:33:35 -0300 Subject: [PATCH 4/6] scripts: move ioc old scripts to ioc dir --- scripts/{ => ioc}/EVRIOCTest.py | 0 scripts/{ => ioc}/IOCTest.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename scripts/{ => ioc}/EVRIOCTest.py (100%) rename scripts/{ => ioc}/IOCTest.py (100%) diff --git a/scripts/EVRIOCTest.py b/scripts/ioc/EVRIOCTest.py similarity index 100% rename from scripts/EVRIOCTest.py rename to scripts/ioc/EVRIOCTest.py diff --git a/scripts/IOCTest.py b/scripts/ioc/IOCTest.py similarity index 100% rename from scripts/IOCTest.py rename to scripts/ioc/IOCTest.py From 379fde5dfbde4d04dd3a0ad2d2a09cd7a1e4fbbd Mon Sep 17 00:00:00 2001 From: Mauricio Donatti Date: Tue, 7 Nov 2023 17:09:19 -0300 Subject: [PATCH 5/6] scripts: add script to check firmware version --- scripts/ioc/get_firmware_version.py | 38 +++++++++++++++++++++++++++++ scripts/ioc/sinap_list.py | 25 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100755 scripts/ioc/get_firmware_version.py create mode 100644 scripts/ioc/sinap_list.py diff --git a/scripts/ioc/get_firmware_version.py b/scripts/ioc/get_firmware_version.py new file mode 100755 index 0000000..52fa39c --- /dev/null +++ b/scripts/ioc/get_firmware_version.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +from epics import caget +import os + +#import sinap list from file +from sinap_list import devices + +#add PV gateway address if not set +ioc_servers = ['10.0.38.46:62000','10.0.38.59:62000'] + +if "EPICS_CA_ADDR_LIST" in os.environ.keys(): + for ioc_server in ioc_servers: + if ioc_server not in os.environ["EPICS_CA_ADDR_LIST"]: + print(f"Appending {ioc_server} to EPICS_CA_ADDR_LIST") + os.environ["EPICS_CA_ADDR_LIST"] = os.environ["EPICS_CA_ADDR_LIST"] + " " + ioc_server +else: + print("Creating EPICS_CA_ADDR_LIST") + os.environ["EPICS_CA_ADDR_LIST"] = ' '.join(ioc_servers) + +print("--------------------------------------------------------------") +print("Checking devices firmware version") +print("--------------------------------------------------------------") +n_devices = 0 +for category in devices.keys(): + print(f"Number of {category}: {len(devices[category])}") + n_devices = n_devices + len(devices[category]) +print("--------------------------------------------------------------") +print(f"Total devices: {n_devices}") +print("--------------------------------------------------------------") + +for category in devices.keys(): + print(f"{category} - {len(devices[category])} device{'s' if len(devices[category]) > 1 else ''}") + print("--------------------------------------------------------------") + for device in devices[category]: + fw_ver = caget(f"{device}:FwVersion-Cte.SVAL") + print(f"{device:30}{fw_ver}") + print("--------------------------------------------------------------") \ No newline at end of file diff --git a/scripts/ioc/sinap_list.py b/scripts/ioc/sinap_list.py new file mode 100644 index 0000000..b2f0bde --- /dev/null +++ b/scripts/ioc/sinap_list.py @@ -0,0 +1,25 @@ +#sinap devices list +devices = { + 'EVG':['AS-RaMO:TI-EVG'], + 'Fout':['RA-RaMO:TI-Fout', + 'CA-RaTim:TI-Fout-1', + 'CA-RaTim:TI-Fout-2', + 'CA-RaTim:TI-Fout-3', + 'CA-RaTim:TI-Fout-4', + 'CA-RaTim:TI-Fout-5'], + 'EVR':['LA-RFH01RACK2:TI-EVR', + 'IA-01RaInj05:TI-EVR', + 'LA-RaCtrl:TI-EVR', + 'PA-RaCtrl:TI-EVR-1', + 'PA-RaCtrl:TI-EVR-2', + 'IA-20RaDiag01:TI-EVR', + 'BA-IMBA:TI-EVR'], + 'EVE':['LA-BIH01RACK2:TI-EVE', + 'IA-16RaBbB:TI-EVE', + 'IA-18RaDiag04:TI-EVE', + 'IA-14RaDiag03:TI-EVE', + 'BA-MNCA:TI-EVE', + 'BA-CAXA:TI-EVE', + 'RA-RaBO01:TI-EVE', + 'RA-RaSIA01:TI-EVE'] +} \ No newline at end of file From efd8d1c01377f6b623bbbf01c90be5ffa5ad54f4 Mon Sep 17 00:00:00 2001 From: Mauricio Donatti Date: Fri, 10 Nov 2023 16:19:36 -0300 Subject: [PATCH 6/6] sinap_list.py: add room 10 EVR to sinap_list --- scripts/ioc/sinap_list.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ioc/sinap_list.py b/scripts/ioc/sinap_list.py index b2f0bde..c730dbe 100644 --- a/scripts/ioc/sinap_list.py +++ b/scripts/ioc/sinap_list.py @@ -13,6 +13,7 @@ 'PA-RaCtrl:TI-EVR-1', 'PA-RaCtrl:TI-EVR-2', 'IA-20RaDiag01:TI-EVR', + 'IA-10RaBPM:TI-EVR', 'BA-IMBA:TI-EVR'], 'EVE':['LA-BIH01RACK2:TI-EVE', 'IA-16RaBbB:TI-EVE',