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
22 from common
.srdhelper
import SrdIntEnum
29 Ann
= SrdIntEnum
.from_list('Ann',
30 [c
[0] for c
in cmds
.values()] + ['BIT', 'FIELD', 'WARN'])
32 def cmd_annotation_classes():
33 return tuple([tuple([cmd
[0].lower(), cmd
[1]]) for cmd
in cmds
.values()])
35 class Decoder(srd
.Decoder
):
39 longname
= 'Amulet LCD ASCII'
40 desc
= 'Amulet Technologies LCD controller ASCII protocol.'
45 annotations
= cmd_annotation_classes() + (
48 ('warning', 'Warning'),
51 ('bits', 'Bits', (L
+ 0,)),
52 ('fields', 'Fields', (L
+ 1,)),
53 ('commands', 'Commands', tuple(range(L
))),
54 ('warnings', 'Warnings', (L
+ 2,)),
57 {'id': 'ms_chan', 'desc': 'Master -> slave channel',
58 'default': 'RX', 'values': ('RX', 'TX')},
59 {'id': 'sm_chan', 'desc': 'Slave -> master channel',
60 'default': 'TX', 'values': ('RX', 'TX')},
70 # Build dict mapping command keys to handler functions. Each
71 # command in 'cmds' (defined in lists.py) has a matching
72 # handler self.handle_<shortname>.
74 s
= 'handle_%s' % cmds
[cmd
][0].lower().replace('/', '_')
75 return getattr(self
, s
)
76 self
.cmd_handlers
= dict((cmd
, get_handler(cmd
)) for cmd
in cmds
.keys())
79 self
.out_ann
= self
.register(srd
.OUTPUT_ANN
)
82 # Simplification, most annotations span exactly one SPI byte/packet.
83 self
.put(self
.ss
, self
.es
, self
.out_ann
, data
)
86 self
.put(self
.ss_field
, self
.es_field
, self
.out_ann
, data
)
89 self
.put(self
.ss_cmd
, self
.es_cmd
, self
.out_ann
, data
)
91 def cmd_ann_list(self
):
92 x
, s
= cmds
[self
.state
][0], cmds
[self
.state
][1]
93 return ['Command: %s (%s)' % (s
, x
), 'Command: %s' % s
,
94 'Cmd: %s' % s
, 'Cmd: %s' % x
, x
]
96 def emit_cmd_byte(self
):
98 self
.putx([Ann
.FIELD
, self
.cmd_ann_list()])
100 def emit_addr_bytes(self
, pdata
):
101 if self
.cmdstate
== 2:
102 self
.ss_field
= self
.ss
103 self
.addr
= chr(pdata
)
104 self
.putx([Ann
.BIT
, ['Address high nibble: %c' % pdata
,
105 'Addr high 0x%c' % pdata
, 'Addr h 0x%c' % pdata
]])
106 elif self
.cmdstate
== 3:
107 self
.es_field
= self
.es
108 self
.addr
+= chr(pdata
)
109 self
.addr
= int(self
.addr
, 16)
110 self
.putx([Ann
.BIT
, ['Address low nibble: %c' % pdata
,
111 'Addr low 0x%c' % pdata
, 'Addr l 0x%c' % pdata
]])
112 self
.putf([Ann
.FIELD
, ['Address: 0x%02X' % self
.addr
,
113 'Addr: 0x%02X' % self
.addr
, '0x%02X' % self
.addr
]])
115 def emit_cmd_end(self
, data
):
116 self
.es_cmd
= self
.es
120 def handle_read(self
, data
):
121 if self
.cmdstate
== 1:
124 elif self
.cmdstate
== 2:
125 self
.emit_addr_bytes(pdata
)
126 elif self
.cmdstate
== 3:
127 self
.emit_addr_bytes(pdata
)
130 def handle_set_common(self
, pdata
):
131 if self
.cmdstate
== 1:
133 self
.emit_addr_bytes(pdata
)
135 def emit_not_implemented(self
, data
):
136 self
.es_cmd
= self
.es
137 self
.putc([Ann
.WARN
, ['Command not decoded', 'Not decoded']])
138 self
.emit_cmd_end(data
)
140 def handle_string(self
, pdata
, ann_class
):
141 # TODO: unicode / string modifiers...
142 self
.handle_set_common(pdata
)
143 if self
.cmdstate
== 4:
144 self
.ss_field
= self
.ss
147 # Null terminated string ends.
148 self
.es_field
= self
.es
149 self
.putx([Ann
.BIT
, ['NULL']])
150 self
.putf([Ann
.FIELD
, ['Value: %s' % self
.value
,
151 'Val: %s' % self
.value
, '%s' % self
.value
]])
152 self
.emit_cmd_end([ann_class
, self
.cmd_ann_list()])
154 if self
.cmdstate
> 3:
155 self
.value
+= chr(pdata
)
156 self
.putx([Ann
.BIT
, ['%c' % pdata
]])
161 # Page change 0xA0, 0x02, index_high, index_low, checksum
162 def handle_page(self
, pdata
):
163 if self
.cmdstate
== 2:
165 self
.ss_field
= self
.ss_cmd
166 self
.es_field
= self
.es
167 self
.putf([Ann
.FIELD
, self
.cmd_ann_list()])
168 self
.checksum
= 0xA0 + 0x02
170 self
.putx([Ann
.WARN
, ['Illegal second byte for page change',
173 elif self
.cmdstate
== 3:
174 self
.ss_field
= self
.ss
175 self
.checksum
+= pdata
177 elif self
.cmdstate
== 4:
178 self
.checksum
+= pdata
180 self
.es_field
= self
.es
181 if self
.page
[0] == self
.page
[1] == 0xFF:
183 self
.putf(Ann
.WARN
, ['Soft reset', 'Reset'])
185 page
= chr(self
.page
[0]) + chr(self
.page
[1])
186 self
.putf(Ann
.FIELD
, ['Page index: 0x%s' % page
,
187 'Page: 0x%s' % page
, '0x%s' % page
])
188 elif self
.cmdstate
== 5:
189 self
.checksum
+= pdata
190 if (self
.checksum
& 0xFF) != 0:
191 self
.putx([Ann
.WARN
, ['Checksum error', 'Error', 'ERR']])
193 self
.putx([Ann
.FIELD
, ['Checksum OK', 'OK']])
194 self
.emit_cmd_end(Ann
.PAGE
)
197 # Value reads: command byte, address high nibble, address low nibble
200 def handle_gbv(self
, pdata
):
201 self
.handle_read(pdata
)
202 self
.emit_cmd_end([Ann
.GBV
, self
.cmd_ann_list()])
205 def handle_gwv(self
, pdata
):
206 self
.handle_read(pdata
)
207 self
.emit_cmd_end([Ann
.GWV
, self
.cmd_ann_list()])
210 def handle_gsv(self
, pdata
):
211 self
.handle_read(pdata
)
212 self
.emit_cmd_end([Ann
.GSV
, self
.cmd_ann_list()])
215 def handle_glv(self
, pdata
):
216 self
.handle_read(pdata
)
217 self
.emit_cmd_end([Ann
.GLV
, self
.cmd_ann_list()])
220 def handle_grpc(self
, pdata
):
221 if self
.cmdstate
== 2:
222 self
.ss_field
= self
.ss
223 self
.flags
= int(chr(pdata
), 16) << 4
224 elif self
.cmdstate
== 3:
225 self
.flags
+= int(chr(pdata
), 16)
226 self
.es_field
= self
.es
227 self
.putf([Ann
.FIELD
, ['RPC flag: 0x%02X' % self
.flags
]])
228 self
.emit_cmd_end([Ann
.GRPC
, self
.cmd_ann_list()])
230 # Get byte value array
231 def handle_gbva(self
, pdata
):
232 self
.handle_read(pdata
)
233 self
.emit_cmd_end([Ann
.GBVA
, self
.cmd_ann_list()])
235 # Get word value array
236 def handle_gwva(self
, pdata
):
237 self
.handle_read(pdata
)
238 self
.emit_cmd_end([Ann
.GWVA
, self
.cmd_ann_list()])
241 def handle_gcv(self
, pdata
):
242 self
.handle_read(pdata
)
243 self
.emit_cmd_end([Ann
.GCV
, self
.cmd_ann_list()])
245 # Value setters: command byte, address high nibble, address low nibble, data bytes
247 # Set byte value data = high nibble, low nibble
248 def handle_sbv(self
, pdata
):
249 self
.handle_set_common(pdata
)
250 if self
.cmdstate
== 4:
251 self
.ss_field
= self
.ss
252 self
.value
= chr(pdata
)
253 elif self
.cmdstate
== 5:
254 self
.value
+= chr(pdata
)
255 self
.es_field
= self
.es
256 self
.putf([Ann
.FIELD
, ['Value: 0x%s' % self
.value
,
257 'Val: 0x%s' % self
.value
, '0x%s' % self
.value
]])
258 self
.emit_cmd_end([Ann
.SBV
, self
.cmd_ann_list()])
261 # Set word value, msb high, msb low, lsb high, lsb low
262 def handle_swv(self
, pdata
):
263 self
.handle_set_common(pdata
)
264 if self
.cmdstate
> 3:
265 nibble
= self
.cmdstate
- 4
267 self
.ss_field
= self
.ss
269 self
.value
+= int(chr(pdata
), 16) << 12 - (4 * nibble
)
271 self
.es_field
= self
.es
272 self
.putf([Ann
.FIELD
, ['Value: 0x%04x' % self
.value
,
273 'Val: 0x%04x' % self
.value
, '0x%04x' % self
.value
]])
274 self
.emit_cmd_end([Ann
.SWV
, self
.cmd_ann_list()])
278 # Set string value, null terminated utf8 strings
279 def handle_ssv(self
, pdata
):
280 self
.handle_string(pdata
, Ann
.SSV
)
282 # Set byte value array
283 def handle_sbva(self
, pdata
):
284 nibble
= (self
.cmdstate
- 3) % 2
285 if self
.cmdstate
== 2:
286 self
.addr
= int(chr(pdata
), 16) << 4
287 self
.ss_field
= self
.ss
288 self
.putx([Ann
.BIT
, ['Address high nibble: %c' % pdata
,
289 'Addr high 0x%c' % pdata
, '0x%c' % pdata
]])
290 elif self
.cmdstate
== 3:
291 self
.addr
+= int(chr(pdata
), 16)
292 self
.es_field
= self
.ss
293 self
.putx([Ann
.BIT
, ['Address low nibble: %c' % pdata
,
294 'Addr low 0x%c' % pdata
, '0x%c' % pdata
]])
295 self
.putf([Ann
.FIELD
, ['Address: 0x%02X' % self
.addr
,
296 'Addr: 0x%02X' % self
.addr
, '0x%02X' % self
.addr
]])
299 # Null terminated list
300 self
.emit_cmd_end([Ann
.SBVA
, self
.cmd_ann_list()])
302 self
.value
= int(chr(pdata
), 16) << 4
304 self
.value
+= int(chr(pdata
), 16)
305 self
.es_field
= self
.es
306 self
.putf([Ann
.FIELD
, ['Value 0x%02X' % self
.value
,
307 '0x%02X' % self
.value
]])
310 # Set word value array
311 def handle_swva(self
, pdata
):
312 nibble
= (self
.cmdstate
- 3) % 4
313 if self
.cmdstate
== 2:
314 self
.addr
= int(chr(pdata
), 16) << 4
315 self
.ss_field
= self
.ss
316 self
.putx([Ann
.BIT
, ['Address high nibble: %c' % pdata
,
317 'Addr high 0x%c' % pdata
, '0x%c' % pdata
]])
318 elif self
.cmdstate
== 3:
319 self
.addr
+= int(chr(pdata
), 16)
320 self
.es_field
= self
.ss
321 self
.putx([Ann
.BIT
, ['Address low nibble: %c' % pdata
,
322 'Addr low 0x%c' % pdata
, '0x%c' % pdata
]])
323 self
.putf([Ann
.FIELD
, ['Address: 0x%02X' % self
.addr
,
324 'Addr: 0x%02X' % self
.addr
, '0x%02X' % self
.addr
]])
327 self
.value
+= int(chr(pdata
), 16) << 12 - (4 * nibble
)
330 # Null terminated list
331 self
.emit_cmd_end([Ann
.SWVA
, self
.cmd_ann_list()])
333 self
.ss_field
= self
.ss
335 self
.es_field
= self
.es
336 self
.putf([Ann
.FIELD
, ['Value 0x%04X' % self
.value
,
337 '0x%04X' % self
.value
]])
341 def handle_scv(self
, pdata
):
342 if self
.cmdstate
== 8:
343 self
.emit_not_implemented([Ann
.SCV
, self
.cmd_ann_list()])
347 def handle_rpc(self
, pdata
):
348 self
.handle_read(pdata
)
349 self
.emit_cmd_end([Ann
.RPC
, self
.cmd_ann_list()])
353 # Decode pair of (x,y) 16bit coordinates
354 def decode_coords(self
, pdata
):
355 if self
.cmdstate
== 1:
360 if self
.cmdstate
< 18:
362 nibble
= (self
.cmdstate
- 1) % 4
363 i
= (self
.cmdstate
- 1) / 4
364 self
.coords
[i
] += int(chr(pdata
), 16) << 12 - (4 * nibble
)
366 self
.ss_field
= self
.ss
368 self
.es_field
= self
.es
369 self
.putf([Ann
.FIELD
, ['Coordinate 0x%04X' % self
.coords
[i
]],
370 ['0x%04X' % self
.coords
[i
]]])
372 # TODO: There are actually two protocol revisions for drawing.
373 # Both use 4 bytes for 16bit x and y pairs for start and end.
374 # The older follows this by a pattern selector and then line weight.
375 # Newer version has 6 bytes for 8bit RGB color...
378 def handle_line(self
, pdata
):
380 if self
.cmdstate
== 18:
381 self
.es_cmd
= self
.es
382 self
.putc([Ann
.LINE
, self
.cmd_ann_list()])
383 self
.putc([Ann
.WARN
, ['Line pattern / Color not implemented']])
388 def handle_rect(self
, pdata
):
390 if self
.cmdstate
== 18:
391 self
.es_cmd
= self
.es
392 self
.putc([Ann
.RECT
, self
.cmd_ann_list()])
393 self
.putc([Ann
.WARN
, ['Line pattern / Color not implemented']])
397 # Draw filled rectangle
398 def handle_frect(self
, pdata
):
400 if self
.cmdstate
== 18:
401 self
.es_cmd
= self
.es
402 self
.putc([Ann
.FRECT
, self
.cmd_ann_list()])
403 self
.putc([Ann
.WARN
, ['Fill pattern / Color not implemented']])
408 def handle_pixel(self
, pdata
):
409 self
.es_cmd
= self
.es
410 self
.putc([Ann
.WARN
, ['Draw pixel documentation is missing.', 'Undocumented']])
414 def handle_gbvr(self
, pdata
):
415 self
.emit_add_bytes(pdata
)
416 if self
.cmdstate
== 4:
417 self
.ss_field
= self
.ss
418 self
.value
= int(chr(pdata
), 16) << 4
419 self
.putx([Ann
.BIT
, ['High nibble 0x%s' % pdata
, '0x%s' % pdata
]])
420 elif self
.cmdstate
== 5:
421 self
.value
+= int(chr(pdata
), 16)
422 self
.putx([Ann
.BIT
, ['Low nibble 0x%s' % pdata
, '0x%s' % pdata
]])
423 self
.es_field
= self
.es
424 self
.putf([Ann
.FIELD
, ['Value: 0x%02X' % self
.value
,
425 '0x%02X' % self
.value
]])
426 self
.emit_cmd_end([Ann
.GBVR
, self
.cmd_ann_list()])
429 def handle_gwvr(self
, pdata
):
430 self
.emit_add_bytes(pdata
)
431 if self
.cmdstate
> 3:
432 nibble
= self
.cmdstate
- 3
435 self
.ss_field
= self
.ss
436 self
.value
+= int(chr(pdata
), 16) << 12 - (4 * nibble
)
437 self
.putx([Ann
.BIT
, ['0x%s' % pdata
]])
439 self
.putf([Ann
.FIELD
, ['Value: 0x%04x' % self
.value
,
440 '0x%04X' % self
.value
]])
441 self
.es_cmd
= self
.ss
442 self
.emit_cmd_end([Ann
.GWVR
, self
.cmd_ann_list()])
445 def handle_gsvr(self
, pdata
):
446 self
.handle_string(pdata
, Ann
.GSVR
)
448 def handle_glvr(self
, pdata
):
449 self
.handle_string(pdata
, Ann
.GLVR
)
451 def handle_grpcr(self
, pdata
):
452 self
.handle_addr(pdata
)
453 if self
.cmdstate
> 3:
454 nibble
= (self
.cmdstate
- 3) % 2
457 self
.emit_cmd_end([Ann
.GRPCR
, self
.cmd_ann_list()])
459 self
.value
= int(chr(pdata
), 16) << 4
460 self
.ss_field
= self
.ss
461 self
.putx([Ann
.BIT
, ['0x%s' % pdata
]])
463 self
.value
+= int(chr(pdata
), 16)
464 self
.es_field
= self
.es
465 self
.putx([Ann
.BIT
, ['0x%s' % pdata
]])
466 self
.putf([Ann
.FIELD
, ['0x%02X' % self
.value
]])
469 def handle_sbvr(self
, pdata
):
470 self
.handle_set_common(pdata
)
471 if self
.cmdstate
== 4:
472 self
.ss_field
= self
.ss
473 self
.value
= chr(pdata
)
474 elif self
.cmdstate
== 5:
475 self
.value
+= chr(pdata
)
476 self
.es_field
= self
.es
477 self
.putf([Ann
.FIELD
, ['Value: 0x%s' % self
.value
,
478 'Val: 0x%s' % self
.value
, '0x%s' % self
.value
]])
479 self
.emit_cmd_end([Ann
.SBVR
, self
.cmd_ann_list()])
482 def handle_swvr(self
, pdata
):
483 self
.handle_set_common(pdata
)
484 if self
.cmdstate
== 4:
485 self
.ss_field
= self
.ss
486 self
.value
= (pdata
- 0x30) << 4
487 elif self
.cmdstate
== 5:
488 self
.value
+= (pdata
- 0x30)
489 self
.value
= self
.value
<< 8
490 elif self
.cmdstate
== 6:
491 self
.value
+= (pdata
- 0x30) << 4
492 elif self
.cmdstate
== 7:
493 self
.value
+= (pdata
- 0x30)
494 self
.es_field
= self
.es
495 self
.putf([Ann
.FIELD
, ['Value: 0x%04x' % self
.value
,
496 'Val: 0x%04x' % self
.value
, '0x%04x' % self
.value
]])
497 self
.emit_cmd_end([Ann
.SWVR
, self
.cmd_ann_list()])
501 def handle_ssvr(self
, pdata
):
502 self
.handle_string(pdata
, Ann
.SSVR
)
504 def handle_rpcr(self
, pdata
):
505 self
.handle_read(pdata
)
506 self
.emit_cmd_end([Ann
.RPCR
, self
.cmd_ann_list()])
508 def handle_liner(self
, pdata
):
510 if self
.cmdstate
== 18:
511 self
.es_cmd
= self
.es
512 self
.putc([Ann
.LINER
, self
.cmd_ann_list()])
513 self
.putc([Ann
.WARN
, ['Line pattern / Color not implemented']])
517 def handle_rectr(self
, pdata
):
519 if self
.cmdstate
== 18:
520 self
.es_cmd
= self
.es
521 self
.putc([Ann
.RECTR
, self
.cmd_ann_list()])
522 self
.putc([Ann
.WARN
, ['Line pattern / Color not implemented']])
526 def handle_frectr(self
, pdata
):
528 if self
.cmdstate
== 18:
529 self
.es_cmd
= self
.es
530 self
.putc([Ann
.FRECTR
, self
.cmd_ann_list()])
531 self
.putc([Ann
.WARN
, ['Line pattern / Color not implemented']])
535 def handle_pixelr(self
, pdata
):
536 self
.es_cmd
= self
.es
537 self
.putc([Ann
.WARN
,['Draw pixel documentation is missing.', 'Undocumented']])
540 def handle_gbvar(self
, pdata
):
541 nibble
= (self
.cmdstate
- 3) % 2
542 if self
.cmdstate
== 2:
543 self
.addr
= int(chr(pdata
), 16) << 4
544 self
.ss_field
= self
.ss
545 self
.putx([Ann
.BIT
, ['Address high nibble: %c' % pdata
,
546 'Addr high 0x%c' % pdata
, '0x%c' % pdata
]])
547 elif self
.cmdstate
== 3:
548 self
.addr
+= int(chr(pdata
), 16)
549 self
.es_field
= self
.ss
550 self
.putx([Ann
.BIT
, ['Address low nibble: %c' % pdata
,
551 'Addr low 0x%c' % pdata
, '0x%c' % pdata
]])
552 self
.putf([Ann
.FIELD
, ['Address: 0x%02X' % self
.addr
,
553 'Addr: 0x%02X' % self
.addr
, '0x%02X' % self
.addr
]])
556 # Null terminated list
557 self
.emit_cmd_end([Ann
.GBVAR
, self
.cmd_ann_list()])
559 self
.value
= int(chr(pdata
), 16) << 4
561 self
.value
+= int(chr(pdata
), 16)
562 self
.es_field
= self
.es
563 self
.putf([Ann
.FIELD
, ['Value 0x%02X' % self
.value
,
564 '0x%02X' % self
.value
]])
567 def handle_gwvar(self
, pdata
):
568 nibble
= (self
.cmdstate
- 3) % 4
569 if self
.cmdstate
== 2:
570 self
.addr
= int(chr(pdata
), 16) << 4
571 self
.ss_field
= self
.ss
572 self
.putx([Ann
.BIT
, ['Address high nibble: %c' % pdata
,
573 'Addr high 0x%c' % pdata
, '0x%c' % pdata
]])
574 elif self
.cmdstate
== 3:
575 self
.addr
+= int(chr(pdata
), 16)
576 self
.es_field
= self
.ss
577 self
.putx([Ann
.BIT
, ['Address low nibble: %c' % pdata
,
578 'Addr low 0x%c' % pdata
, '0x%c' % pdata
]])
579 self
.putf([Ann
.FIELD
, ['Address: 0x%02X' % self
.addr
,
580 'Addr: 0x%02X' % self
.addr
, '0x%02X' % self
.addr
]])
583 self
.value
+= int(chr(pdata
), 16) << 12 - (4 * nibble
)
586 # Null terminated list
587 self
.emit_cmd_end([Ann
.GWVAR
, self
.cmd_ann_list()])
589 self
.ss_field
= self
.ss
591 self
.es_field
= self
.es
592 self
.putf([Ann
.FIELD
, ['Value 0x%04X' % self
.value
,
593 '0x%04X' % self
.value
]])
596 # Get byte variable array reply
597 def handle_sbvar(self
, pdata
):
598 nibble
= (self
.cmdstate
- 3) % 2
599 if self
.cmdstate
== 2:
600 self
.addr
= int(chr(pdata
), 16) << 4
601 self
.ss_field
= self
.ss
602 self
.putx([Ann
.BIT
, ['Address high nibble: %c' % pdata
,
603 'Addr high 0x%c' % pdata
, '0x%c' % pdata
]])
604 elif self
.cmdstate
== 3:
605 self
.addr
+= int(chr(pdata
), 16)
606 self
.es_field
= self
.ss
607 self
.putx([Ann
.BIT
, ['Address low nibble: %c' % pdata
,
608 'Addr low 0x%c' % pdata
, '0x%c' % pdata
]])
609 self
.putf([Ann
.FIELD
, ['Address: 0x%02X' % self
.addr
,
610 'Addr: 0x%02X' % self
.addr
, '0x%02X' % self
.addr
]])
613 # Null terminated list
614 self
.emit_cmd_end([Ann
.SBVAR
, self
.cmd_ann_list()])
616 self
.value
= int(chr(pdata
), 16) << 4
618 self
.value
+= int(chr(pdata
), 16)
619 self
.es_field
= self
.es
620 self
.putf([Ann
.FIELD
, ['Value 0x%02X' % self
.value
,
621 '0x%02X' % self
.value
]])
624 # Set word variable array reply
625 def handle_swvar(self
, pdata
):
626 nibble
= (self
.cmdstate
- 3) % 4
627 if self
.cmdstate
== 2:
628 self
.addr
= int(chr(pdata
), 16) << 4
629 self
.ss_field
= self
.ss
630 self
.putx([Ann
.BIT
, ['Address high nibble: %c' % pdata
,
631 'Addr high 0x%c' % pdata
, '0x%c' % pdata
]])
632 elif self
.cmdstate
== 3:
633 self
.addr
+= int(chr(pdata
), 16)
634 self
.es_field
= self
.ss
635 self
.putx([Ann
.BIT
, ['Address low nibble: %c' % pdata
,
636 'Addr low 0x%c' % pdata
, '0x%c' % pdata
]])
637 self
.putf([Ann
.FIELD
, ['Address: 0x%02X' % self
.addr
,
638 'Addr: 0x%02X' % self
.addr
, '0x%02X' % self
.addr
]])
641 self
.value
+= int(chr(pdata
), 16) << 12 - (4 * nibble
)
644 # Null terminated list
645 self
.emit_cmd_end([Ann
.SWVAR
, self
.cmd_ann_list()])
647 self
.ss_field
= self
.ss
649 self
.es_field
= self
.es
650 self
.putf([Ann
.FIELD
, ['Value 0x%04X' % self
.value
,
651 '0x%04X' % self
.value
]])
654 def handle_gcvr(self
, pdata
):
655 if self
.cmdstate
== 8:
656 self
.emit_not_implemented([Ann
.SCV
, self
.cmd_ann_list()])
659 def handle_scvr(self
, pdata
):
660 if self
.cmdstate
== 8:
661 self
.emit_not_implemented([Ann
.SCV
, self
.cmd_ann_list()])
666 def handle_ack(self
, pdata
):
667 self
.putx([Ann
.ACK
, self
.cmd_ann_list()])
670 def handle_nack(self
, pdata
):
671 self
.putx([Ann
.NACK
, self
.cmd_ann_list()])
674 def decode(self
, ss
, es
, data
):
675 ptype
, rxtx
, pdata
= data
677 self
.ss
, self
.es
= ss
, es
684 abort_current
= (0xD0 <= pdata
[0] <= 0xF7) and \
685 (not (self
.state
in cmds_with_high_bytes
)) and \
688 self
.putx([Ann
.WARN
, ['Command aborted by invalid byte', 'Abort']])
689 self
.state
= pdata
[0]
692 if self
.state
is None:
693 self
.state
= pdata
[0]
696 self
.cmd_handlers
[self
.state
](pdata
[0])
698 self
.putx([Ann
.WARN
, ['Unknown command: 0x%02x' % pdata
[0]]])