2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2019 Vesa-Pekka Palmu <vpalmu@depili.fi>
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 3 of the License, or
9 ## (at your option) any later version.
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ## GNU General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
20 import sigrokdecode as srd
27 rxtx_channels = ('RX', 'TX')
29 # Don't forget to keep this in sync with 'cmds' is lists.py.
31 PAGE, GBV, GWV, GSV, GLV, GRPC, SBV, SWV, SSV, RPC, LINE, RECT, FRECT, \
32 PIXEL, GBVA, GWVA, SBVA, GBVR, GWVR, GSVR, GLVR, GRPCR, SBVR, SWVR, SSVR, \
33 RPCR, LINER, RECTR, FRECTR, PIXELR, GBVAR, GWVAR, SBVAR, ACK, NACK, SWVA, \
34 SWVAR, GCV, GCVR, SCV, SCVR, BIT, FIELD, WARN = range(L + 3)
36 def cmd_annotation_classes():
37 return tuple([tuple([cmd[0].lower(), cmd[1]]) for cmd in cmds.values()])
39 class Decoder(srd.Decoder):
43 longname = 'Amulet LCD ASCII'
44 desc = 'Amulet Technologies LCD controller ASCII protocol.'
49 annotations = cmd_annotation_classes() + (
52 ('warning', 'Warning'),
55 ('bits', 'Bits', (L + 0,)),
56 ('fields', 'Fields', (L + 1,)),
57 ('commands', 'Commands', tuple(range(len(cmds)))),
58 ('warnings', 'Warnings', (L + 2,)),
61 {'id': 'ms_chan', 'desc': 'Master -> slave channel',
62 'default': rxtx_channels[0], 'values': rxtx_channels},
63 {'id': 'sm_chan', 'desc': 'Slave -> master channel',
64 'default': rxtx_channels[1], 'values': rxtx_channels},
74 # Build dict mapping command keys to handler functions. Each
75 # command in 'cmds' (defined in lists.py) has a matching
76 # handler self.handle_<shortname>.
78 s = 'handle_%s' % cmds[cmd][0].lower().replace('/', '_')
79 return getattr(self, s)
80 self.cmd_handlers = dict((cmd, get_handler(cmd)) for cmd in cmds.keys())
83 self.out_ann = self.register(srd.OUTPUT_ANN)
86 # Simplification, most annotations span exactly one SPI byte/packet.
87 self.put(self.ss, self.es, self.out_ann, data)
90 self.put(self.ss_field, self.es_field, self.out_ann, data)
93 self.put(self.ss_cmd, self.es_cmd, self.out_ann, data)
95 def cmd_ann_list(self):
96 x, s = cmds[self.state][0], cmds[self.state][1]
97 return ['Command: %s (%s)' % (s, x), 'Command: %s' % s,
98 'Cmd: %s' % s, 'Cmd: %s' % x, x]
100 def emit_cmd_byte(self):
101 self.ss_cmd = self.ss
102 self.putx([Ann.FIELD, self.cmd_ann_list()])
104 def emit_addr_bytes(self, pdata):
105 if self.cmdstate == 2:
106 self.ss_field = self.ss
107 self.addr = chr(pdata)
108 self.putx([Ann.BIT, ['Address high nibble: %c' % (pdata),
109 'Addr high 0x%c' % (pdata), 'Addr h 0x%c' % (pdata)]])
110 elif self.cmdstate == 3:
111 self.es_field = self.es
112 self.addr += chr(pdata)
113 self.addr = int(self.addr, 16)
114 self.putx([Ann.BIT, ['Address low nibble: %c' % (pdata),
115 'Addr low 0x%c' % (pdata), 'Addr l 0x%c' % (pdata)]])
116 self.putf([Ann.FIELD, ['Address: 0x%02X' % self.addr,
117 'Addr: 0x%02X' % self.addr, '0x%02X' % self.addr]])
119 def emit_cmd_end(self, data):
120 self.es_cmd = self.es
124 def handle_read(self, data):
125 if self.cmdstate == 1:
128 elif self.cmdstate == 2:
129 self.emit_addr_bytes(pdata)
130 elif self.cmdstate == 3:
131 self.emit_addr_bytes(pdata)
134 def handle_set_common(self, pdata):
135 if self.cmdstate == 1:
137 self.emit_addr_bytes(pdata)
139 def emit_not_implemented(self, data):
140 self.es_cmd = self.es
141 self.putc([Ann.WARN, ['Command not decoded', 'Not decoded']])
142 self.emit_cmd_end(data)
144 def handle_string(self, pdata, ann_class):
145 # TODO: unicode / string modifiers...
146 self.handle_set_common(pdata)
147 if self.cmdstate == 4:
148 self.ss_field = self.ss
151 # Null terminated string ends.
152 self.es_field = self.es
153 self.putx([Ann.BIT, ['NULL']])
154 self.putf([Ann.FIELD, ['Value: %s' % (self.value),
155 'Val: %s' % (self.value), '%s' % (self.value)]])
156 self.emit_cmd_end([ann_class, self.cmd_ann_list()])
158 if self.cmdstate > 3:
159 self.value += chr(pdata)
160 self.putx([Ann.BIT, ['%c' % (pdata)]])
165 # Page change 0xA0, 0x02, index_high, index_low, checksum
166 def handle_page(self, pdata):
167 if self.cmdstate == 2:
169 self.ss_field = self.ss_cmd
170 self.es_field = self.es
171 self.putf([Ann.FIELD, self.cmd_ann_list()])
172 self.checksum = 0xA0 + 0x02
174 self.putx([Ann.WARN, ['Illegal second byte for page change',
177 elif self.cmdstate == 3:
178 self.ss_field = self.ss
179 self.checksum += pdata
181 elif self.cmdstate == 4:
182 self.checksum += pdata
184 self.es_field = self.es
185 if self.page[0] == self.page [1] == 0xFF:
187 self.putf(Ann.WARN, ['Soft reset', 'Reset'])
189 page = chr(self.page[0]) + chr(self.page[1])
190 self.putf(Ann.FIELD, ['Page index: 0x%s' % (page),
191 'Page: 0x%s' % (page), '0x%s' % (page)])
192 elif self.cmdstate == 5:
193 self.checksum += pdata
194 if (self.checksum & 0xFF) != 0:
195 self.putx([Ann.WARN, ['Checksum error', 'Error', 'ERR']])
197 self.putx([Ann.FIELD, ['Checksum OK', 'OK']])
198 self.emit_cmd_end(Ann.PAGE)
201 # Value reads: command byte, address high nibble, address low nibble
204 def handle_gbv(self, pdata):
205 self.handle_read(pdata)
206 self.emit_cmd_end([Ann.GBV, self.cmd_ann_list()])
209 def handle_gwv(self, pdata):
210 self.handle_read(pdata)
211 self.emit_cmd_end([Ann.GWV, self.cmd_ann_list()])
214 def handle_gsv(self, pdata):
215 self.handle_read(pdata)
216 self.emit_cmd_end([Ann.GSV, self.cmd_ann_list()])
219 def handle_glv(self, pdata):
220 self.handle_read(pdata)
221 self.emit_cmd_end([Ann.GLV, self.cmd_ann_list()])
224 def handle_grpc(self, pdata):
225 if self.cmdstate == 2:
226 self.ss_field = self.ss
227 self.flags = int(chr(pdata), 16) << 4
228 elif self.cmdstate == 3:
229 self.flags += int(chr(pdata), 16)
230 self.es_field = self.es
231 self.putf([Ann.FIELD, ['RPC flag: 0x%02X' % (self.flags)]])
232 self.emit_cmd_end([Ann.GRPC, self.cmd_ann_list()])
234 # Get byte value array
235 def handle_gbva(self, pdata):
236 self.handle_read(pdata)
237 self.emit_cmd_end([Ann.GBVA, self.cmd_ann_list()])
239 # Get word value array
240 def handle_gwva(self, pdata):
241 self.handle_read(pdata)
242 self.emit_cmd_end([Ann.GWVA, self.cmd_ann_list()])
245 def handle_gcv(self, pdata):
246 self.handle_read(pdata)
247 self.emit_cmd_end([Ann.GCV, self.cmd_ann_list()])
249 # Value setters: command byte, address high nibble, address low nibble, data bytes
251 # Set byte value data = high nibble, low nibble
252 def handle_sbv(self, pdata):
253 self.handle_set_common(pdata)
254 if self.cmdstate == 4:
255 self.ss_field = self.ss
256 self.value = chr(pdata)
257 elif self.cmdstate == 5:
258 self.value += chr(pdata)
259 self.es_field = self.es
260 self.putf([Ann.FIELD, ['Value: 0x%s' % self.value,
261 'Val: 0x%s' % self.value, '0x%s' % self.value]])
262 self.emit_cmd_end([Ann.SBV, self.cmd_ann_list()])
265 # Set word value, msb high, msb low, lsb high, lsb low
266 def handle_swv(self, pdata):
267 self.handle_set_common(pdata)
268 if self.cmdstate > 3:
269 nibble = self.cmdstate - 4
271 self.ss_field = self.ss
273 self.value += int(chr(pdata), 16) << 12 - (4 * nibble)
275 self.es_field = self.es
276 self.putf([Ann.FIELD, ['Value: 0x%04x' % self.value,
277 'Val: 0x%04x' % self.value, '0x%04x' % self.value]])
278 self.emit_cmd_end([Ann.SWV, self.cmd_ann_list()])
282 # Set string value, null terminated utf8 strings
283 def handle_ssv(self, pdata):
284 self.handle_string(pdata, Ann.SSV)
286 # Set byte value array
287 def handle_sbva(self, pdata):
288 nibble = (self.cmdstate - 3) % 2
289 if self.cmdstate == 2:
290 self.addr = int(chr(pdata), 16) << 4
291 self.ss_field = self.ss
292 self.putx([Ann.BIT, ['Address high nibble: %c' % (pdata),
293 'Addr high 0x%c' % (pdata), '0x%c' % (pdata)]])
294 elif self.cmdstate == 3:
295 self.addr += int(chr(pdata), 16)
296 self.es_field = self.ss
297 self.putx([Ann.BIT, ['Address low nibble: %c' % (pdata),
298 'Addr low 0x%c' % (pdata), '0x%c' % (pdata)]])
299 self.putf([Ann.FIELD, ['Address: 0x%02X' % self.addr,
300 'Addr: 0x%02X' % self.addr, '0x%02X' % self.addr]])
303 # Null terminated list
304 self.emit_cmd_end([Ann.SBVA, self.cmd_ann_list()])
306 self.value = int(chr(pdata), 16) << 4
308 self.value += int(chr(pdata), 16)
309 self.es_field = self.es
310 self.putf([Ann.FIELD, ['Value 0x%02X' % (self.value),
311 '0x%02X' % (self.value)]])
314 # Set word value array
315 def handle_swva(self, pdata):
316 nibble = (self.cmdstate - 3) % 4
317 if self.cmdstate == 2:
318 self.addr = int(chr(pdata), 16) << 4
319 self.ss_field = self.ss
320 self.putx([Ann.BIT, ['Address high nibble: %c' % (pdata),
321 'Addr high 0x%c' % (pdata), '0x%c' % (pdata)]])
322 elif self.cmdstate == 3:
323 self.addr += int(chr(pdata), 16)
324 self.es_field = self.ss
325 self.putx([Ann.BIT, ['Address low nibble: %c' % (pdata),
326 'Addr low 0x%c' % (pdata), '0x%c' % (pdata)]])
327 self.putf([Ann.FIELD, ['Address: 0x%02X' % self.addr,
328 'Addr: 0x%02X' % self.addr, '0x%02X' % self.addr]])
331 self.value += int(chr(pdata), 16) << 12 - (4 * nibble)
334 # Null terminated list
335 self.emit_cmd_end([Ann.SWVA, self.cmd_ann_list()])
337 self.ss_field = self.ss
339 self.es_field = self.es
340 self.putf([Ann.FIELD, ['Value 0x%04X' % (self.value),
341 '0x%04X' % (self.value)]])
345 def handle_scv(self, pdata):
346 if self.cmdstate == 8:
347 self.emit_not_implemented([Ann.SCV, self.cmd_ann_list()])
351 def handle_rpc(self, pdata):
352 self.handle_read(pdata)
353 self.emit_cmd_end([Ann.RPC, self.cmd_ann_list()])
357 # Decode pair of (x,y) 16bit coordinates
358 def decode_coords(self, pdata):
359 if self.cmdstate == 1:
364 if self.cmdstate < 18:
366 nibble = (self.cmdstate - 1) % 4
367 i = (self.cmdstate - 1) / 4
368 self.coords[i] += int(chr(pdata), 16) << 12 - (4 * nibble)
370 self.ss_field = self.ss
372 self.es_field = self.es
373 self.putf([Ann.FIELD, ['Coordinate 0x%04X' % (self.coords[i])],
374 ['0x%04X' % (self.coords[i])]])
376 # TODO: There are actually two protocol revisions for drawing.
377 # Both use 4 bytes for 16bit x and y pairs for start and end.
378 # The older follows this by a pattern selector and then line weight.
379 # Newer version has 6 bytes for 8bit RGB color...
382 def handle_line(self, pdata):
384 if self.cmdstate == 18:
385 self.es_cmd = self.es
386 self.putc([Ann.LINE, self.cmd_ann_list()])
387 self.putc([Ann.WARN, ['Line pattern / Color not implemented']])
392 def handle_rect(self, pdata):
394 if self.cmdstate == 18:
395 self.es_cmd = self.es
396 self.putc([Ann.RECT, self.cmd_ann_list()])
397 self.putc([Ann.WARN, ['Line pattern / Color not implemented']])
401 # Draw filled rectangle
402 def handle_frect(self, pdata):
404 if self.cmdstate == 18:
405 self.es_cmd = self.es
406 self.putc([Ann.FRECT, self.cmd_ann_list()])
407 self.putc([Ann.WARN, ['Fill pattern / Color not implemented']])
412 def handle_pixel(self, pdata):
413 self.es_cmd = self.es
414 self.putc([Ann.WARN, ['Draw pixel documentation is missing.', 'Undocumented']])
418 def handle_gbvr(self, pdata):
419 self.emit_add_bytes(pdata)
420 if self.cmdstate == 4:
421 self.ss_field = self.ss
422 self.value = int(chr(pdata), 16) << 4
423 self.putx([Ann.BIT, ['High nibble 0x%s' % (pdata), '0x%s' % (pdata)]])
424 elif self.cmdstate == 5:
425 self.value += int(chr(pdata), 16)
426 self.putx([Ann.BIT, ['Low nibble 0x%s' % (pdata), '0x%s' % (pdata)]])
427 self.es_field = self.es
428 self.putf([Ann.FIELD, ['Value: 0x%02X' % (self.value),
429 '0x%02X' % (self.value)]])
430 self.emit_cmd_end([Ann.GBVR, self.cmd_ann_list()])
433 def handle_gwvr(self, pdata):
434 self.emit_add_bytes(pdata)
435 if self.cmdstate > 3:
436 nibble = self.cmdstate - 3
439 self.ss_field = self.ss
440 self.value += int(chr(pdata), 16) << 12 - (4 * nibble)
441 self.putx([Ann.BIT, ['0x%s' % (pdata)]])
443 self.putf([Ann.FIELD, ['Value: 0x%04x' % (self.value),
444 '0x%04X' % (self.value)]])
445 self.es_cmd = self.ss
446 self.emit_cmd_end([Ann.GWVR, self.cmd_ann_list()])
449 def handle_gsvr(self, pdata):
450 self.handle_string(pdata, Ann.GSVR)
452 def handle_glvr(self, pdata):
453 self.handle_string(pdata, Ann.GLVR)
455 def handle_grpcr(self, pdata):
456 self.handle_addr(pdata)
457 if self.cmdstate > 3:
458 nibble = (self.cmdstate - 3) % 2
461 self.emit_cmd_end([Ann.GRPCR, self.cmd_ann_list()])
463 self.value = int(chr(pdata), 16) << 4
464 self.ss_field = self.ss
465 self.putx([Ann.BIT, ['0x%s' % (pdata)]])
467 self.value += int(chr(pdata), 16)
468 self.es_field = self.es
469 self.putx([Ann.BIT, ['0x%s' % (pdata)]])
470 self.putf([Ann.FIELD, ['0x%02X' % (self.value)]])
473 def handle_sbvr(self, pdata):
474 self.handle_set_common(pdata)
475 if self.cmdstate == 4:
476 self.ss_field = self.ss
477 self.value = chr(pdata)
478 elif self.cmdstate == 5:
479 self.value += chr(pdata)
480 self.es_field = self.es
481 self.putf([Ann.FIELD, ['Value: 0x%s' % self.value,
482 'Val: 0x%s' % self.value, '0x%s' % self.value]])
483 self.emit_cmd_end([Ann.SBVR, self.cmd_ann_list()])
486 def handle_swvr(self, pdata):
487 self.handle_set_common(pdata)
488 if self.cmdstate == 4:
489 self.ss_field = self.ss
490 self.value = (pdata - 0x30) << 4
491 elif self.cmdstate == 5:
492 self.value += (pdata - 0x30)
493 self.value = self.value << 8
494 elif self.cmdstate == 6:
495 self.value += (pdata - 0x30) << 4
496 elif self.cmdstate == 7:
497 self.value += (pdata - 0x30)
498 self.es_field = self.es
499 self.putf([Ann.FIELD, ['Value: 0x%04x' % self.value,
500 'Val: 0x%04x' % self.value, '0x%04x' % self.value]])
501 self.emit_cmd_end([Ann.SWVR, self.cmd_ann_list()])
505 def handle_ssvr(self, pdata):
506 self.handle_string(pdata, Ann.SSVR)
508 def handle_rpcr(self, pdata):
509 self.handle_read(pdata)
510 self.emit_cmd_end([Ann.RPCR, self.cmd_ann_list()])
512 def handle_liner(self, pdata):
514 if self.cmdstate == 18:
515 self.es_cmd = self.es
516 self.putc([Ann.LINER, self.cmd_ann_list()])
517 self.putc([Ann.WARN, ['Line pattern / Color not implemented']])
521 def handle_rectr(self, pdata):
523 if self.cmdstate == 18:
524 self.es_cmd = self.es
525 self.putc([Ann.RECTR, self.cmd_ann_list()])
526 self.putc([Ann.WARN, ['Line pattern / Color not implemented']])
530 def handle_frectr(self, pdata):
532 if self.cmdstate == 18:
533 self.es_cmd = self.es
534 self.putc([Ann.FRECTR, self.cmd_ann_list()])
535 self.putc([Ann.WARN, ['Line pattern / Color not implemented']])
539 def handle_pixelr(self, pdata):
540 self.es_cmd = self.es
541 self.putc([Ann.WARN,['Draw pixel documentation is missing.', 'Undocumented']])
544 def handle_gbvar(self, pdata):
545 nibble = (self.cmdstate - 3) % 2
546 if self.cmdstate == 2:
547 self.addr = int(chr(pdata), 16) << 4
548 self.ss_field = self.ss
549 self.putx([Ann.BIT, ['Address high nibble: %c' % (pdata),
550 'Addr high 0x%c' % (pdata), '0x%c' % (pdata)]])
551 elif self.cmdstate == 3:
552 self.addr += int(chr(pdata), 16)
553 self.es_field = self.ss
554 self.putx([Ann.BIT, ['Address low nibble: %c' % (pdata),
555 'Addr low 0x%c' % (pdata), '0x%c' % (pdata)]])
556 self.putf([Ann.FIELD, ['Address: 0x%02X' % self.addr,
557 'Addr: 0x%02X' % self.addr, '0x%02X' % self.addr]])
560 # Null terminated list
561 self.emit_cmd_end([Ann.GBVAR, self.cmd_ann_list()])
563 self.value = int(chr(pdata), 16) << 4
565 self.value += int(chr(pdata), 16)
566 self.es_field = self.es
567 self.putf([Ann.FIELD, ['Value 0x%02X' % (self.value),
568 '0x%02X' % (self.value)]])
571 def handle_gwvar(self, pdata):
572 nibble = (self.cmdstate - 3) % 4
573 if self.cmdstate == 2:
574 self.addr = int(chr(pdata), 16) << 4
575 self.ss_field = self.ss
576 self.putx([Ann.BIT, ['Address high nibble: %c' % (pdata),
577 'Addr high 0x%c' % (pdata), '0x%c' % (pdata)]])
578 elif self.cmdstate == 3:
579 self.addr += int(chr(pdata), 16)
580 self.es_field = self.ss
581 self.putx([Ann.BIT, ['Address low nibble: %c' % (pdata),
582 'Addr low 0x%c' % (pdata), '0x%c' % (pdata)]])
583 self.putf([Ann.FIELD, ['Address: 0x%02X' % self.addr,
584 'Addr: 0x%02X' % self.addr, '0x%02X' % self.addr]])
587 self.value += int(chr(pdata), 16) << 12 - (4 * nibble)
590 # Null terminated list
591 self.emit_cmd_end([Ann.GWVAR, self.cmd_ann_list()])
593 self.ss_field = self.ss
595 self.es_field = self.es
596 self.putf([Ann.FIELD, ['Value 0x%04X' % (self.value),
597 '0x%04X' % (self.value)]])
600 # Get byte variable array reply
601 def handle_sbvar(self, pdata):
602 nibble = (self.cmdstate - 3) % 2
603 if self.cmdstate == 2:
604 self.addr = int(chr(pdata), 16) << 4
605 self.ss_field = self.ss
606 self.putx([Ann.BIT, ['Address high nibble: %c' % (pdata),
607 'Addr high 0x%c' % (pdata), '0x%c' % (pdata)]])
608 elif self.cmdstate == 3:
609 self.addr += int(chr(pdata), 16)
610 self.es_field = self.ss
611 self.putx([Ann.BIT, ['Address low nibble: %c' % (pdata),
612 'Addr low 0x%c' % (pdata), '0x%c' % (pdata)]])
613 self.putf([Ann.FIELD, ['Address: 0x%02X' % self.addr,
614 'Addr: 0x%02X' % self.addr, '0x%02X' % self.addr]])
617 # Null terminated list
618 self.emit_cmd_end([Ann.SBVAR, self.cmd_ann_list()])
620 self.value = int(chr(pdata), 16) << 4
622 self.value += int(chr(pdata), 16)
623 self.es_field = self.es
624 self.putf([Ann.FIELD, ['Value 0x%02X' % (self.value),
625 '0x%02X' % (self.value)]])
628 # Set word variable array reply
629 def handle_swvar(self, pdata):
630 nibble = (self.cmdstate - 3) % 4
631 if self.cmdstate == 2:
632 self.addr = int(chr(pdata), 16) << 4
633 self.ss_field = self.ss
634 self.putx([Ann.BIT, ['Address high nibble: %c' % (pdata),
635 'Addr high 0x%c' % (pdata), '0x%c' % (pdata)]])
636 elif self.cmdstate == 3:
637 self.addr += int(chr(pdata), 16)
638 self.es_field = self.ss
639 self.putx([Ann.BIT, ['Address low nibble: %c' % (pdata),
640 'Addr low 0x%c' % (pdata), '0x%c' % (pdata)]])
641 self.putf([Ann.FIELD, ['Address: 0x%02X' % self.addr,
642 'Addr: 0x%02X' % self.addr, '0x%02X' % self.addr]])
645 self.value += int(chr(pdata), 16) << 12 - (4 * nibble)
648 # Null terminated list
649 self.emit_cmd_end([Ann.SWVAR, self.cmd_ann_list()])
651 self.ss_field = self.ss
653 self.es_field = self.es
654 self.putf([Ann.FIELD, ['Value 0x%04X' % (self.value),
655 '0x%04X' % (self.value)]])
658 def handle_gcvr(self, pdata):
659 if self.cmdstate == 8:
660 self.emit_not_implemented([Ann.SCV, self.cmd_ann_list()])
663 def handle_scvr(self, pdata):
664 if self.cmdstate == 8:
665 self.emit_not_implemented([Ann.SCV, self.cmd_ann_list()])
670 def handle_ack(self, pdata):
671 self.putx([Ann.ACK, self.cmd_ann_list()])
674 def handle_nack(self, pdata):
675 self.putx([Ann.NACK, self.cmd_ann_list()])
678 def decode(self, ss, es, data):
679 ptype, rxtx, pdata = data
681 self.ss, self.es = ss, es
688 abort_current = (0xD0 <= pdata[0] <= 0xF7) and \
689 (not (self.state in cmds_with_high_bytes)) and \
692 self.putx([Ann.WARN, ['Command aborted by invalid byte', 'Abort']])
693 self.state = pdata[0]
696 if (self.state is None):
697 self.state = pdata[0]
700 self.cmd_handlers[self.state](pdata[0])
702 self.putx([Ann.WARN, ['Unknown command: 0x%02x' % pdata[0]]])