13
13
logger = logging .getLogger (__name__ )
14
14
15
15
16
+ _mode_enc = {
17
+ "exp" : 0 ,
18
+ "1" : 1 ,
19
+ "0" : 2 ,
20
+ "in" : 3
21
+ }
22
+
23
+
16
24
class _TTLWidget (QtGui .QFrame ):
17
- def __init__ (self , force_out , name ):
25
+ def __init__ (self , send_to_device , channel , force_out , name ):
26
+ self .send_to_device = send_to_device
27
+ self .channel = channel
18
28
self .force_out = force_out
19
29
20
30
QtGui .QFrame .__init__ (self )
@@ -29,29 +39,72 @@ def __init__(self, force_out, name):
29
39
grid .addWidget (label , 1 , 1 )
30
40
31
41
self ._direction = QtGui .QLabel ()
32
- self ._value = QtGui .QLabel ()
33
42
self ._direction .setAlignment (QtCore .Qt .AlignCenter )
34
- self ._value .setAlignment (QtCore .Qt .AlignCenter )
35
- self .set_value (0 , False , False )
36
43
grid .addWidget (self ._direction , 2 , 1 )
44
+ self ._value = QtGui .QLabel ()
45
+ self ._value .setAlignment (QtCore .Qt .AlignCenter )
37
46
grid .addWidget (self ._value , 3 , 1 , 6 , 1 )
38
47
48
+ self ._value .setContextMenuPolicy (QtCore .Qt .ActionsContextMenu )
49
+ menu = QtGui .QActionGroup (self ._value )
50
+ menu .setExclusive (True )
51
+ self ._expctl_action = QtGui .QAction ("Experiment controlled" , self ._value )
52
+ self ._expctl_action .setCheckable (True )
53
+ menu .addAction (self ._expctl_action )
54
+ self ._value .addAction (self ._expctl_action )
55
+ self ._expctl_action .triggered .connect (lambda : self .set_force ("exp" ))
56
+ self ._force1_action = QtGui .QAction ("Force 1" , self ._value )
57
+ self ._force1_action .setCheckable (True )
58
+ menu .addAction (self ._force1_action )
59
+ self ._value .addAction (self ._force1_action )
60
+ self ._force1_action .triggered .connect (lambda : self .set_force ("1" ))
61
+ self ._force0_action = QtGui .QAction ("Force 0" , self ._value )
62
+ self ._force0_action .setCheckable (True )
63
+ menu .addAction (self ._force0_action )
64
+ self ._value .addAction (self ._force0_action )
65
+ self ._force0_action .triggered .connect (lambda : self .set_force ("0" ))
66
+ self ._forcein_action = QtGui .QAction ("Force input" , self ._value )
67
+ self ._forcein_action .setCheckable (True )
68
+ self ._forcein_action .setEnabled (not force_out )
69
+ menu .addAction (self ._forcein_action )
70
+ self ._value .addAction (self ._forcein_action )
71
+ self ._forcein_action .triggered .connect (lambda : self .set_force ("in" ))
72
+
73
+ self .set_value (0 , False , False )
74
+
75
+ def set_force (self , mode ):
76
+ data = struct .pack ("bbb" ,
77
+ 2 , # MONINJ_REQ_TTLSET
78
+ self .channel , _mode_enc [mode ])
79
+ self .send_to_device (data )
80
+
39
81
def set_value (self , value , oe , override ):
40
- value = "1" if value else "0"
82
+ value_s = "1" if value else "0"
41
83
if override :
42
- value = "<b>" + value + "</b>"
84
+ value_s = "<b>" + value_s + "</b>"
43
85
color = " color=\" red\" "
44
86
else :
45
87
color = ""
46
88
self ._value .setText ("<font size=\" 9\" {}>{}</font>" .format (
47
- color , value ))
89
+ color , value_s ))
48
90
oe = oe or self .force_out
49
91
direction = "OUT" if oe else "IN"
50
92
self ._direction .setText ("<font size=\" 1\" >" + direction + "</font>" )
93
+ if override :
94
+ if oe :
95
+ if value :
96
+ self ._force1_action .setChecked (True )
97
+ else :
98
+ self ._force0_action .setChecked (True )
99
+ else :
100
+ self ._forcein_action .setChecked (True )
101
+ else :
102
+ self ._expctl_action .setChecked (True )
51
103
52
104
53
105
class _DeviceManager :
54
- def __init__ (self , init ):
106
+ def __init__ (self , send_to_device , init ):
107
+ self .send_to_device = send_to_device
55
108
self .ddb = dict ()
56
109
self .ttl_cb = lambda : None
57
110
self .ttl_widgets = dict ()
@@ -68,7 +121,8 @@ def __setitem__(self, k, v):
68
121
if v ["type" ] == "local" and v ["module" ] == "artiq.coredevice.ttl" :
69
122
channel = v ["arguments" ]["channel" ]
70
123
force_out = v ["class" ] == "TTLOut"
71
- self .ttl_widgets [channel ] = _TTLWidget (force_out , k )
124
+ self .ttl_widgets [channel ] = _TTLWidget (
125
+ self .send_to_device , channel , force_out , k )
72
126
self .ttl_cb ()
73
127
except KeyError :
74
128
pass
@@ -92,7 +146,7 @@ def get_core_addr(self):
92
146
class MonInjTTLDock (dockarea .Dock , TaskObject ):
93
147
def __init__ (self ):
94
148
dockarea .Dock .__init__ (self , "TTL" , size = (1500 , 500 ))
95
- self .dm = _DeviceManager (dict ())
149
+ self .dm = _DeviceManager (self . send_to_device , dict ())
96
150
self .transport = None
97
151
98
152
self .grid = QtGui .QGridLayout ()
@@ -118,42 +172,45 @@ def connection_made(self, transport):
118
172
self .transport = transport
119
173
120
174
def datagram_received (self , data , addr ):
121
- ttl_levels , ttl_oes = struct .unpack (">QQ " , data )
175
+ ttl_levels , ttl_oes , ttl_overrides = struct .unpack (">QQQ " , data )
122
176
for channel , w in self .dm .ttl_widgets .items ():
123
177
w .set_value (ttl_levels & (1 << channel ),
124
178
ttl_oes & (1 << channel ),
125
- False )
179
+ ttl_overrides & ( 1 << channel ) )
126
180
127
181
def error_received (self , exc ):
128
182
logger .warning ("datagram endpoint error" )
129
183
130
184
def connection_lost (self , exc ):
131
185
self .transport = None
132
186
187
+ def send_to_device (self , data ):
188
+ ca = self .dm .get_core_addr ()
189
+ if ca is None :
190
+ logger .warning ("could not find core device address" )
191
+ elif self .transport is None :
192
+ logger .warning ("datagram endpoint not available" )
193
+ else :
194
+ self .transport .sendto (data , (ca , 3250 ))
195
+
133
196
@asyncio .coroutine
134
197
def _do (self ):
135
198
while True :
136
199
yield from asyncio .sleep (0.2 )
137
- ca = self .dm .get_core_addr ()
138
- if ca is None :
139
- logger .warning ("could not find core device address" )
140
- elif self .transport is None :
141
- logger .warning ("datagram endpoint not available" )
142
- else :
143
- # MONINJ_REQ_MONITOR
144
- self .transport .sendto (b"\x01 " , (ca , 3250 ))
200
+ # MONINJ_REQ_MONITOR
201
+ self .send_to_device (b"\x01 " )
145
202
146
203
def layout_ttl_widgets (self ):
147
204
w = self .grid .itemAt (0 )
148
205
while w is not None :
149
206
self .grid .removeItem (w )
150
207
w = self .grid .itemAt (0 )
151
208
for i , (_ , w ) in enumerate (sorted (self .dm .ttl_widgets .items (),
152
- key = itemgetter (0 ))):
209
+ key = itemgetter (0 ))):
153
210
self .grid .addWidget (w , i // 4 , i % 4 )
154
211
155
212
def init_devices (self , d ):
156
- self .dm = _DeviceManager (d )
213
+ self .dm = _DeviceManager (self . send_to_device , d )
157
214
self .dm .ttl_cb = self .layout_ttl_widgets
158
215
self .layout_ttl_widgets ()
159
216
return self .dm
0 commit comments