2 # -*- coding: utf-8 -*-
4 # IMPORTS ######################################################################
7 if sys.version_info.major != 3:
9 "ERROR: Please run this script using Python 3.\n"
17 'ERROR: serial module for Python 3 is unavailable.\n'
18 'On Debian based systems run "apt-get install python3-serial"\n'
23 from os.path import abspath, dirname, join
25 WHERE_AM_I = abspath(dirname(__file__))
29 # SERIAL #######################################################################
31 def send_data(port, data, sim=False):
34 'SPIMST0:4({:X},{:X})\n'.format((data>>8)&0xFF, (data)&0xFF),
40 ser = serial.Serial(port,
42 bytesize = serial.EIGHTBITS,
43 parity = serial.PARITY_NONE,
44 stopbits = serial.STOPBITS_ONE,
48 result = ser.read(1000)
50 result = ser.read(1000)
58 vports = sorted(glob.glob('/dev/ttyACM*'))
59 vports += sorted(glob.glob('/dev/ttyUSB*'))
61 # This doesn't return all the ports on /dev/ttyS*, as it is expected to
62 # return the must probable ports on where the device might be connected.
64 ports = sorted(glob.glob('/dev/ttyS*'))
65 if len(ports) > limit:
72 # COMMAND LINE #################################################################
79 parser = argparse.ArgumentParser(description='Send data to LMC1 device.')
81 parser.add_argument('-o', '--output', metavar='0xXXXX' ,
82 default='0x0000' , required=True,
83 help='16 bits value to send, bit by bit mapped to board outputs')
85 parser.add_argument('-p', '--port' , metavar='/dev/ttyXXX',
86 default=get_ports()[0], required=True,
87 help='tty port to communicate with the board')
89 parser.add_argument('-s', '--sim' ,
91 help='simulate command, do not write to output port')
93 args = vars(parser.parse_args())
97 data = int(args['output'], 0)
100 'WARNING: output data is negative, '
106 'WARNING: output data is larger than 16 bits, '
107 'extra bits will be ignored.\n'
110 sys.stderr.write('ERROR: output data is not an integer literal.\n')
114 # Note check done because existance of port, write rights,
115 # etc, are handled as exceptions.
121 cmd, result = send_data(port, data, sim)
122 sys.stdout.write('Command: {}'.format(cmd))
123 sys.stdout.write('Result : ')
125 sys.stdout.write('(none, using simulation)\n')
127 sys.stdout.write('{}\n'.format(result))
130 except serial.SerialException as e:
131 sys.stderr.write('ERROR: {}.\n'.format(str(e)))
136 # GUI ##########################################################################
142 from gi.repository import Gtk, Pango
146 'ERROR: Gtk3 bindings module for Python 3 is unavailable.\n'
147 'On Debian based systems run "apt-get install python3-gi"\n'
158 self.builder = Gtk.Builder()
159 self.glade_file = join(WHERE_AM_I, 'gui.glade')
160 self.builder.add_from_file(self.glade_file)
161 go = self.builder.get_object
164 self.window = go('window')
166 self.port_list = go('port_list')
167 self.port = go('port')
168 self.send = go('send')
171 for i in range(1, 17):
172 self.outputs.append(go('out_{}'.format(i)))
174 self.opt_autosend = go('opt_autosend')
175 self.opt_sim = go('opt_sim')
177 self.log_view = go('log_view')
178 self.log_buff = go('log_buff')
181 self.builder.connect_signals(self)
183 # Configure interface
184 self.populate_ports_cb(None, None)
185 self.port_list.set_active(0)
187 self.opt_autosend.set_active(True)
189 self.log_view.modify_font(Pango.FontDescription('DejaVu Sans Mono 9'))
191 self.window.connect('delete-event', lambda x,y: Gtk.main_quit())
193 # Everything is ready
198 self.log_buff.insert_at_cursor(data)
199 cursor = self.log_buff.get_insert()
200 self.log_view.scroll_to_mark(cursor, 0.0, False, 0.0, 0.0)
202 def populate_ports_cb(self, widget, data=None):
203 self.port_list.get_model().clear()
204 for p in get_ports():
205 self.port_list.append_text(p)
207 def autosend_changed_cb(self, widget, data=None):
208 self.send.set_sensitive(not widget.get_active())
210 def autosend_cb(self, widget, data=None):
211 if(self.opt_autosend.get_active()):
212 self.send_cb(widget, data)
214 def send_cb(self, widget, data=None):
216 port = self.port.get_text()
218 error = Gtk.MessageDialog(self.window,
219 Gtk.DialogFlags.DESTROY_WITH_PARENT,
220 Gtk.MessageType.ERROR,
221 Gtk.ButtonsType.CLOSE,
222 'Please specify a communication port.'
229 for i in range(0, 16):
230 if(not self.outputs[i].get_active()):
233 sim = self.opt_sim.get_active()
236 self.log(('Port: {}\n'
239 '\tHexadecimal: {}\n'
240 '\tDecimal : {}\n\n').format(
241 port, bin(data), hex(data), data
246 cmd, result = send_data(port, data, sim)
247 self.log('Command: {}\n'.format(cmd))
248 self.log('Result : ')
250 self.log('(none, using simulation)\n')
252 self.log('{}\n'.format(result))
254 except serial.SerialException as e:
255 self.log('ERROR: {}.\n'.format(str(e)))
260 if __name__ == '__main__':
262 if(len(sys.argv) > 1):