-
Notifications
You must be signed in to change notification settings - Fork 0
/
camac_control.py
executable file
·331 lines (290 loc) · 9.81 KB
/
camac_control.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# encoding: utf-8
"""
camac_cmds.py
Created by Sam Cook on 2011-01-24.
Copyright (c) 2011. All rights reserved.
"""
from ecp_header import * # this imports packet_desc
from socket import *
from select import *
from struct import *
from time import sleep
# recvPackStr = ecp_header.headerPackStr + 'H'*3
# lens = {''}
class CAMACError(Exception):
pass
class CAMACreadfail(Exception):
pass
def status(sock):
"""
returns the status as received from the socket, sock.
options: verbose - returns full packet
packStr - alternate packing string (eg if header)
"""
data = ''
while not data:
data = sock.recv(4096)
if len(data) == 24:
# header only
res = dictify(ecp_header, data)
llcControl = res["llcControl"][1]
elif len(data) == 30:
# rcvd packed (header + nwords, data, qresp)
res = dictify(ecp_rcvd_packet, data)
llcControl = res["llcControl"][1]
else:
# most likley error but unpack it anyway
res = ()
while len(data) > 0:
byte, data = data[:1], data[1:]
res += unpack('B', byte)
llcControl = res[2]
ecp_header["llcControl"][1] = llcControl
return res
def status_check(data, location=""):
"""
Checks the status and qresp for the passed packed"""
if (data["status"][1] == 90) and (data["qresp"][1] == 0):
# warning only (no xresp)
return
elif data["status"][1] != 1:
raise CAMACError("Status failure code: %i %s" % (data["status"][1], location))
elif (data["qresp"][1] != 0x8000):
raise CAMACError("Qresp failure %i %s" % (data["qresp"][1], location))
def cccc(sock):
"""
send CAMAC clear to socket, sock
"""
msg = gettop(cmd = 'cmd_clear', mod = 0)
sock.send(msg)
return status(sock)
def cccz(sock):
"""
send CAMAC init to socket, sock
"""
msg = gettop(cmd = 'cmd_init', mod = 0)
sock.send(msg)
return status(sock)
def ccci(sock):
"""
send CAMAC inhibit to socket, sock
"""
msg = gettop(cmd = 'cmd_inhibit', mod=0)
sock.send(msg)
return status(sock)
def cssa(sock, n, f, a = None, data = None): # waitForLAM = False, timeout = 30):
"""
n = slot no,
f = camac function,
a is optional based on function and the subaddress of the module
d is optional based on function and the data to be passed
waitForLAM sends the command with the COR command "attach to LAM"
which will not be processed until a LAM has been seen on the module
returns the received packet as a list: n_words, dat and status
"""
toparg = {"cmd":'cmd_camac_op', "mod":1}
msg = gettop(**toparg) + naf(n, f, a, data)
sock.send(msg)
return status(sock)
def sendCOR(sock, cmd, mod):
# TODO use this to simplify cccc etc
msg = gettop(cmd = cmd, mod=mod)
sock.send(msg)
return status(sock)
def waitForLAM(sock, n, addr=None, maxpolls = 100):
"""
Polls the LAM at n then sleeps for 10us
"""
msg = gettop() + naf(n, f="clearLAM", a = 1)
sock.send (msg)
data = status(sock)
old_data = data
for i in range(maxpolls):
msg = gettop() + naf(n=n, cmd = 'cmd_test_lam', mod = n)
sock.send (msg)
data = status(sock)
# status_check(data)
if data["status"] != old_data["status"]:
print data
if ("qresp" in data) and (data["qresp"] != old_data["qresp"]):
print data
old_data = data
else:
raise timeout("Timeout waiting for interupt")
def rsync(sock, maxTries = 10):
"""resyncs the ecc + pc"""
LLC_responce = 0x64 # from 'our_ecc.h'
LLC_command = 0x60
rsync_cmd_1 = b'\x60\x60\x67'
rsync_cmd_2 = b'\x64\x64\xE7'
attempts = 0
cmd_2_sent = False
llccontrol = 0xF7 # more magic!
sock.send(rsync_cmd_1)
while True:
s = sock.recv(4098)
s = unpack("BBB",s[:3])[0]
if s == LLC_responce:
sock.send(rsync_cmd_2)
cmd_2_sent = True
elif (s == LLC_command and cmd_2_sent):
ecp_header["llcControl"][1] = llccontrol
return
elif attempts == maxTries:
raise timeout("timed running rsynch")
else:
attempts += 0
# dictionary format "command name":(command code, [subaddress needed?], [data needed?])
camacFunction = {
"readGrp1": (0, "subaddr"),
"readGrp2": (1, "subaddr"),
"readClrGrp1": (2, "subaddr"),
"readClrGrp2": (3, "subaddr"),
"testLAM": (8, ),
"clearGrp1": (9, ),
"clearLAM": (10, ),
"clearGrp2": (11, ),
"overWriteGrp1": (16, "subaddr", "data"),
"overWriteGrp2": (17, "subaddr", "data"),
"maskOverWriteGrp1": (18, "subaddr", "data"),
"maskOverWriteGrp2": (19, "subaddr", "data"),
"disable": (24, ),
"increment": (25, "subaddr"),
"enable": (26, ),
"testStatus": (27, ),
}
def naf(n, f, a = None, data = None ):
# data to write
"""
Converts n, a, f to a 2byte string that is suitable
to be sent to CAMAC in the format: 0fff ffnn nnna aaas
"""
# get the function info required (number and whether an address etc are needed)
funcCode = (f, ) if str(f).isdigit() else camacFunction[f]
if (("subaddr" in funcCode) and (a == None)):
raise CAMACError("function requires a subaddress")
elif (("data" in funcCode) and (data == None)):
raise CAMACError("function requires data")
a = a if a else 0
data = pack('H', data) if (data >= 0) else b''
# print 'n is', n, 'a is', a, 'f is', funcCode[0], '\n'
res = funcCode[0] <<10 | n <<5 | a << 1 | 0
res = pack('H', res)
return res + data
def sockset():
sock = socket(AF_INET, SOCK_DGRAM)
sock.settimeout(5)
sendAddr = ('192.168.0.2', 240) # (host, port) both defined in our_ecc
rcvAddr = ('', 59329)
sock.bind(rcvAddr) # where to receive data
sock.connect(sendAddr) # where to send from
return sock
def main_test(sock):
# this bit might work but it's hard to tell
print("starting, sending clear, init and inhibit,")
rsync(sock)
print("completed rsync")
cccc(sock)
print("\ncompleted c")
cccz(sock)
print("\ncompleted z")
ccci(sock)
print("\ncompleted i")
print cssa(sock, n=22, f='clearLAM', a=0, data=0)
# cssa(sock, n=22, f=26, a=1)
# cssa(sock, n=22, f=9, a=0)
# cssa(sock, n=22, f=11, a=0)
# count = 0
# while(True):
# t = cssa(sock, n=22, f=8, a=0)
# cssa(sock, n= 22, f='clearLAM')
# break
# cssa(sock = sock, n = 23, f = 16, a = 0, data=1)
# cssa(sock = sock, n = 23, f = 16, a = 0, data=0)
# sleep(1)
# if t["qresp"][1] != 0:
# # print "wow!"
# # print count
# # print t
# dat = cssa(sock, 21, "readGrp1", 8)
# cssa (sock, 21, "clearGrp1", 8)
# print dat["data"]
# else:
# count += 1
#
#
# msg = gettop(flags = 0x0300, ops = 5, cmd = "cmd_attach_lam", mod = 21)
# msg += naf(22, 0, 0) + naf(21,0,8) + naf(21, 0, 9)
# sock.send(msg)
# print status(sock)
# running = True
# inputs = [sock, ]
# print '='*40
# while running:
# inR, outR, erR = select(inputs, [], [])
#
# for i in inR:
# while len(i)> 0:
# print unpack('B',i)
# i = i[1:]
# print '='*40 + '\ns'
return
cssa(sock, n = 21, f = "clearGrp1", a = 0)
cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=1)
cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=0)
print "try and read"
old_q = 32768
n_run = 0
n_loops = 0
while True: # n_run < 5:
cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=1)
cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=0)
q = cssa(sock, n = 21, f = "testLAM")["qresp"][1]
if q != 0:
print "woot!"
else:
sleep(0.001)
# for i in range(4):
# d = cssa(sock, n = 21, f = "readGrp1", a = i)
# print d["data"]
#
# cssa(sock, n = 21, f = "clearGrp1", a=8)
# cssa(sock, n = 21, f = "clearLAM")
# print "="*10
# cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=1)
# cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=0)
# n_run += 1
# else:
# n_loops += 1
# print n_loops
# if n_loops == 50:
# cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=1)
# cssa(sock = sock, n = 23, f = "overWriteGrp1", a = 0, data=0)
# print "hello "
sock.close()
def adc_test():
sock = sockset()
print "rsync",
rsync(sock)
print "inhibi",
sendCOR(sock, "cmd_inhibit", mod=1)
print "F(25)",
cssa(sock, n= 21, f=25, a=0)
print "wait..",
sleep(0.002)
print "read ADC:"
for i in range(11):
dat = cssa(sock, n = 21, f="readClrGrp1", a=i)
if "qresp" in dat: print i, dat["qresp"][1], dat["data"][1]
sock.close()
print "done"
if __name__ == '__main__':
# filter for wire shark:
#(ip.src == 192.186.0.1 and ip.dst == 192.168.0.2) or (ip.src == 192.168.0.2 and ip.dst == 192.186.0.1)
# adc_test()
sock = sockset()
try:
main_test(sock)
finally:
sock.close()
print "bye bye"