jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / contrib / xsvf_tools / svf2xsvf.py
1 #!/usr/bin/python3.0
2 # SPDX-License-Identifier: GPL-2.0-or-later
3
4 # Copyright 2008, SoftPLC Corporation http://softplc.com
5 # Dick Hollenbeck dick@softplc.com
6
7 # A python program to convert an SVF file to an XSVF file. There is an
8 # option to include comments containing the source file line number from the origin
9 # SVF file before each outputted XSVF statement.
10 #
11 # We deviate from the XSVF spec in that we introduce a new command called
12 # XWAITSTATE which directly flows from the SVF RUNTEST command. Unfortunately
13 # XRUNSTATE was ill conceived and is not used here. We also add support for the
14 # three Lattice extensions to SVF: LCOUNT, LDELAY, and LSDR. The xsvf file
15 # generated from this program is suitable for use with the xsvf player in
16 # OpenOCD with my modifications to xsvf.c.
17 #
18 # This program is written for python 3.0, and it is not easy to change this
19 # back to 2.x. You may find it easier to use python 3.x even if that means
20 # building it.
21
22
23 import re
24 import sys
25 import struct
26
27
28 # There are both ---<Lexer>--- and ---<Parser>--- sections to this program
29
30
31 if len( sys.argv ) < 3:
32 print("usage %s <svf_filename> <xsvf_filename>" % sys.argv[0])
33 exit(1)
34
35
36 inputFilename = sys.argv[1]
37 outputFilename = sys.argv[2]
38
39 doCOMMENTs = True # Save XCOMMENTs in the output xsvf file
40 #doCOMMENTs = False # Save XCOMMENTs in the output xsvf file
41
42 # pick your file encoding
43 file_encoding = 'ISO-8859-1'
44 #file_encoding = 'utf-8'
45
46
47 xrepeat = 0 # argument to XREPEAT, gives retry count for masked compares
48
49
50 #-----< Lexer >---------------------------------------------------------------
51
52 StateBin = (RESET,IDLE,
53 DRSELECT,DRCAPTURE,DRSHIFT,DREXIT1,DRPAUSE,DREXIT2,DRUPDATE,
54 IRSELECT,IRCAPTURE,IRSHIFT,IREXIT1,IRPAUSE,IREXIT2,IRUPDATE) = range(16)
55
56 # Any integer index into this tuple will be equal to its corresponding StateBin value
57 StateTxt = ("RESET","IDLE",
58 "DRSELECT","DRCAPTURE","DRSHIFT","DREXIT1","DRPAUSE","DREXIT2","DRUPDATE",
59 "IRSELECT","IRCAPTURE","IRSHIFT","IREXIT1","IRPAUSE","IREXIT2","IRUPDATE")
60
61
62 (XCOMPLETE,XTDOMASK,XSIR,XSDR,XRUNTEST,hole0,hole1,XREPEAT,XSDRSIZE,XSDRTDO,
63 XSETSDRMASKS,XSDRINC,XSDRB,XSDRC,XSDRE,XSDRTDOB,XSDRTDOC,
64 XSDRTDOE,XSTATE,XENDIR,XENDDR,XSIR2,XCOMMENT,XWAIT,XWAITSTATE,
65 LCOUNT,LDELAY,LSDR,XTRST) = range(29)
66
67 #Note: LCOUNT, LDELAY, and LSDR are Lattice extensions to SVF and provide a way to loop back
68 # and check a completion status, essentially waiting on a part until it signals that it is done.
69 # For example below: loop 25 times, each time through the loop do a LDELAY (same as a true RUNTEST)
70 # and exit loop when LSDR compares match.
71 """
72 LCOUNT 25;
73 ! Step to DRPAUSE give 5 clocks and wait for 1.00e+000 SEC.
74 LDELAY DRPAUSE 5 TCK 1.00E-003 SEC;
75 ! Test for the completed status. Match means pass.
76 ! Loop back to LDELAY line if not match and loop count less than 25.
77 LSDR 1 TDI (0)
78 TDO (1);
79 """
80
81 #XTRST is an opcode Xilinx seemed to have missed and it comes from the SVF TRST statement.
82
83 LineNumber = 1
84
85 def s_ident(scanner, token): return ("ident", token.upper(), LineNumber)
86
87 def s_hex(scanner, token):
88 global LineNumber
89 LineNumber = LineNumber + token.count('\n')
90 token = ''.join(token.split())
91 return ("hex", token[1:-1], LineNumber)
92
93 def s_int(scanner, token): return ("int", int(token), LineNumber)
94 def s_float(scanner, token): return ("float", float(token), LineNumber)
95 #def s_comment(scanner, token): return ("comment", token, LineNumber)
96 def s_semicolon(scanner, token): return ("semi", token, LineNumber)
97
98 def s_nl(scanner,token):
99 global LineNumber
100 LineNumber = LineNumber + 1
101 #print( 'LineNumber=', LineNumber, file=sys.stderr )
102 return None
103
104 #2.00E-002
105
106 scanner = re.Scanner([
107 (r"[a-zA-Z]\w*", s_ident),
108 # (r"[-+]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?", s_float),
109 (r"[-+]?[0-9]+(([.][0-9eE+-]*)|([eE]+[-+]?[0-9]+))", s_float),
110 (r"\d+", s_int),
111 (r"\(([0-9a-fA-F]|\s)*\)", s_hex),
112 (r"(!|//).*$", None),
113 (r";", s_semicolon),
114 (r"\n",s_nl),
115 (r"\s*", None),
116 ],
117 re.MULTILINE
118 )
119
120 # open the file using the given encoding
121 file = open( sys.argv[1], encoding=file_encoding )
122
123 # read all svf file input into string "input"
124 input = file.read()
125
126 file.close()
127
128 # Lexer:
129 # create a list of tuples containing (tokenType, tokenValue, LineNumber)
130 tokens = scanner.scan( input )[0]
131
132 input = None # allow gc to reclaim memory holding file
133
134 #for tokenType, tokenValue, ln in tokens: print( "line %d: %s" % (ln, tokenType), tokenValue )
135
136
137 #-----<parser>-----------------------------------------------------------------
138
139 tokVal = tokType = tokLn = None
140
141 tup = iter( tokens )
142
143 def nextTok():
144 """
145 Function to read the next token from tup into tokType, tokVal, tokLn (linenumber)
146 which are globals.
147 """
148 global tokType, tokVal, tokLn, tup
149 tokType, tokVal, tokLn = tup.__next__()
150
151
152 class ParseError(Exception):
153 """A class to hold a parsing error message"""
154 def __init__(self, linenumber, token, message):
155 self.linenumber = linenumber
156 self.token = token
157 self.message = message
158 def __str__(self):
159 global inputFilename
160 return "Error in file \'%s\' at line %d near token %s\n %s" % (
161 inputFilename, self.linenumber, repr(self.token), self.message)
162
163
164 class MASKSET(object):
165 """
166 Class MASKSET holds a set of bit vectors, all of which are related, will all
167 have the same length, and are associated with one of the seven shiftOps:
168 HIR, HDR, TIR, TDR, SIR, SDR, LSDR. One of these holds a mask, smask, tdi, tdo, and a
169 size.
170 """
171 def __init__(self, name):
172 self.empty()
173 self.name = name
174
175 def empty(self):
176 self.mask = bytearray()
177 self.smask = bytearray()
178 self.tdi = bytearray()
179 self.tdo = bytearray()
180 self.size = 0
181
182 def syncLengths( self, sawTDI, sawTDO, sawMASK, sawSMASK, newSize ):
183 """
184 Set all the lengths equal in the event some of the masks were
185 not seen as part of the last change set.
186 """
187 if self.size == newSize:
188 return
189
190 if newSize == 0:
191 self.empty()
192 return
193
194 # If an SIR was given without a MASK(), then use a mask of all zeros.
195 # this is not consistent with the SVF spec, but it makes sense because
196 # it would be odd to be testing an instruction register read out of a
197 # tap without giving a mask for it. Also, lattice seems to agree and is
198 # generating SVF files that comply with this philosophy.
199 if self.name == 'SIR' and not sawMASK:
200 self.mask = bytearray( newSize )
201
202 if newSize != len(self.mask):
203 self.mask = bytearray( newSize )
204 if self.name == 'SDR': # leave mask for HIR,HDR,TIR,TDR,SIR zeros
205 for i in range( newSize ):
206 self.mask[i] = 1
207
208 if newSize != len(self.tdo):
209 self.tdo = bytearray( newSize )
210
211 if newSize != len(self.tdi):
212 self.tdi = bytearray( newSize )
213
214 if newSize != len(self.smask):
215 self.smask = bytearray( newSize )
216
217 self.size = newSize
218 #-----</MASKSET>-----
219
220
221 def makeBitArray( hexString, bitCount ):
222 """
223 Converts a packed sequence of hex ascii characters into a bytearray where
224 each element in the array holds exactly one bit. Only "bitCount" bits are
225 scanned and these must be the least significant bits in the hex number. That
226 is, it is legal to have some unused bits in the must significant hex nibble
227 of the input "hexString". The string is scanned starting from the backend,
228 then just before returning we reverse the array. This way the append()
229 method can be used, which I assume is faster than an insert.
230 """
231 global tokLn
232 a = bytearray()
233 length = bitCount
234 hexString = list(hexString)
235 hexString.reverse()
236 #print(hexString)
237 for c in hexString:
238 if length <= 0:
239 break;
240 c = int(c, 16)
241 for mask in [1,2,4,8]:
242 if length <= 0:
243 break;
244 length = length - 1
245 a.append( (c & mask) != 0 )
246 if length > 0:
247 raise ParseError( tokLn, hexString, "Insufficient hex characters for given length of %d" % bitCount )
248 a.reverse()
249 #print(a)
250 return a
251
252
253 def makeXSVFbytes( bitarray ):
254 """
255 Make a bytearray which is contains the XSVF bits which will be written
256 directly to disk. The number of bytes needed is calculated from the size
257 of the argument bitarray.
258 """
259 bitCount = len(bitarray)
260 byteCount = (bitCount+7)//8
261 ba = bytearray( byteCount )
262 firstBit = (bitCount % 8) - 1
263 if firstBit == -1:
264 firstBit = 7
265 bitNdx = 0
266 for byteNdx in range(byteCount):
267 mask = 1<<firstBit
268 byte = 0
269 while mask:
270 if bitarray[bitNdx]:
271 byte |= mask;
272 mask = mask >> 1
273 bitNdx = bitNdx + 1
274 ba[byteNdx] = byte
275 firstBit = 7
276 return ba
277
278
279 def writeComment( outputFile, shiftOp_linenum, shiftOp ):
280 """
281 Write an XCOMMENT record to outputFile
282 """
283 comment = "%s @%d\0" % (shiftOp, shiftOp_linenum) # \0 is terminating nul
284 ba = bytearray(1)
285 ba[0] = XCOMMENT
286 ba += comment.encode()
287 outputFile.write( ba )
288
289
290 def combineBitVectors( trailer, meat, header ):
291 """
292 Combine the 3 bit vectors comprizing a transmission. Since the least
293 significant bits are sent first, the header is put onto the list last so
294 they are sent first from that least significant position.
295 """
296 ret = bytearray()
297 ret.extend( trailer )
298 ret.extend( meat )
299 ret.extend( header )
300 return ret
301
302
303 def writeRUNTEST( outputFile, run_state, end_state, run_count, min_time, tokenTxt ):
304 """
305 Write the output for the SVF RUNTEST command.
306 run_count - the number of clocks
307 min_time - the number of seconds
308 tokenTxt - either RUNTEST or LDELAY
309 """
310 # convert from secs to usecs
311 min_time = int( min_time * 1000000)
312
313 # the SVF RUNTEST command does NOT map to the XSVF XRUNTEST command. Check the SVF spec, then
314 # read the XSVF command. They are not the same. Use an XSVF XWAITSTATE to
315 # implement the required behavior of the SVF RUNTEST command.
316 if doCOMMENTs:
317 writeComment( output, tokLn, tokenTxt )
318
319 if tokenTxt == 'RUNTEST':
320 obuf = bytearray(11)
321 obuf[0] = XWAITSTATE
322 obuf[1] = run_state
323 obuf[2] = end_state
324 struct.pack_into(">i", obuf, 3, run_count ) # big endian 4 byte int to obuf
325 struct.pack_into(">i", obuf, 7, min_time ) # big endian 4 byte int to obuf
326 outputFile.write( obuf )
327 else: # == 'LDELAY'
328 obuf = bytearray(10)
329 obuf[0] = LDELAY
330 obuf[1] = run_state
331 # LDELAY has no end_state
332 struct.pack_into(">i", obuf, 2, run_count ) # big endian 4 byte int to obuf
333 struct.pack_into(">i", obuf, 6, min_time ) # big endian 4 byte int to obuf
334 outputFile.write( obuf )
335
336
337 output = open( outputFilename, mode='wb' )
338
339 hir = MASKSET('HIR')
340 hdr = MASKSET('HDR')
341 tir = MASKSET('TIR')
342 tdr = MASKSET('TDR')
343 sir = MASKSET('SIR')
344 sdr = MASKSET('SDR')
345
346
347 expecting_eof = True
348
349
350 # one of the commands that take the shiftParts after the length, the parse
351 # template for all of these commands is identical
352 shiftOps = ('SDR', 'SIR', 'LSDR', 'HDR', 'HIR', 'TDR', 'TIR')
353
354 # the order must correspond to shiftOps, this holds the MASKSETS. 'LSDR' shares sdr with 'SDR'
355 shiftSets = (sdr, sir, sdr, hdr, hir, tdr, tir )
356
357 # what to expect as parameters to a shiftOp, i.e. after a SDR length or SIR length
358 shiftParts = ('TDI', 'TDO', 'MASK', 'SMASK')
359
360 # the set of legal states which can trail the RUNTEST command
361 run_state_allowed = ('IRPAUSE', 'DRPAUSE', 'RESET', 'IDLE')
362
363 enddr_state_allowed = ('DRPAUSE', 'IDLE')
364 endir_state_allowed = ('IRPAUSE', 'IDLE')
365
366 trst_mode_allowed = ('ON', 'OFF', 'Z', 'ABSENT')
367
368 enddr_state = IDLE
369 endir_state = IDLE
370
371 frequency = 1.00e+006 # HZ;
372
373 # change detection for xsdrsize and xtdomask
374 xsdrsize = -1 # the last one sent, send only on change
375 xtdomask = bytearray() # the last one sent, send only on change
376
377
378 # we use a number of single byte writes for the XSVF command below
379 cmdbuf = bytearray(1)
380
381
382 # Save the XREPEAT setting into the file as first thing.
383 obuf = bytearray(2)
384 obuf[0] = XREPEAT
385 obuf[1] = xrepeat
386 output.write( obuf )
387
388
389 try:
390 while 1:
391 expecting_eof = True
392 nextTok()
393 expecting_eof = False
394 # print( tokType, tokVal, tokLn )
395
396 if tokVal in shiftOps:
397 shiftOp_linenum = tokLn
398 shiftOp = tokVal
399
400 set = shiftSets[shiftOps.index(shiftOp)]
401
402 # set flags false, if we see one later, set that one true later
403 sawTDI = sawTDO = sawMASK = sawSMASK = False
404
405 nextTok()
406 if tokType != 'int':
407 raise ParseError( tokLn, tokVal, "Expecting 'int' giving %s length, got '%s'" % (shiftOp, tokType) )
408 length = tokVal
409
410 nextTok()
411
412 while tokVal != ';':
413 if tokVal not in shiftParts:
414 raise ParseError( tokLn, tokVal, "Expecting TDI, TDO, MASK, SMASK, or ';'")
415 shiftPart = tokVal
416
417 nextTok()
418
419 if tokType != 'hex':
420 raise ParseError( tokLn, tokVal, "Expecting hex bits" )
421 bits = makeBitArray( tokVal, length )
422
423 if shiftPart == 'TDI':
424 sawTDI = True
425 set.tdi = bits
426
427 elif shiftPart == 'TDO':
428 sawTDO = True
429 set.tdo = bits
430
431 elif shiftPart == 'MASK':
432 sawMASK = True
433 set.mask = bits
434
435 elif shiftPart == 'SMASK':
436 sawSMASK = True
437 set.smask = bits
438
439 nextTok()
440
441 set.syncLengths( sawTDI, sawTDO, sawMASK, sawSMASK, length )
442
443 # process all the gathered parameters and generate outputs here
444 if shiftOp == 'SIR':
445 if doCOMMENTs:
446 writeComment( output, shiftOp_linenum, 'SIR' )
447
448 tdi = combineBitVectors( tir.tdi, sir.tdi, hir.tdi )
449 if len(tdi) > 255:
450 obuf = bytearray(3)
451 obuf[0] = XSIR2
452 struct.pack_into( ">h", obuf, 1, len(tdi) )
453 else:
454 obuf = bytearray(2)
455 obuf[0] = XSIR
456 obuf[1] = len(tdi)
457 output.write( obuf )
458 obuf = makeXSVFbytes( tdi )
459 output.write( obuf )
460
461 elif shiftOp == 'SDR':
462 if doCOMMENTs:
463 writeComment( output, shiftOp_linenum, shiftOp )
464
465 if not sawTDO:
466 # pass a zero filled bit vector for the sdr.mask
467 mask = combineBitVectors( tdr.mask, bytearray(sdr.size), hdr.mask )
468 tdi = combineBitVectors( tdr.tdi, sdr.tdi, hdr.tdi )
469
470 if xsdrsize != len(tdi):
471 xsdrsize = len(tdi)
472 cmdbuf[0] = XSDRSIZE
473 output.write( cmdbuf )
474 obuf = bytearray(4)
475 struct.pack_into( ">i", obuf, 0, xsdrsize ) # big endian 4 byte int to obuf
476 output.write( obuf )
477
478 if xtdomask != mask:
479 xtdomask = mask
480 cmdbuf[0] = XTDOMASK
481 output.write( cmdbuf )
482 obuf = makeXSVFbytes( mask )
483 output.write( obuf )
484
485 cmdbuf[0] = XSDR
486 output.write( cmdbuf )
487 obuf = makeXSVFbytes( tdi )
488 output.write( obuf )
489
490 else:
491 mask = combineBitVectors( tdr.mask, sdr.mask, hdr.mask )
492 tdi = combineBitVectors( tdr.tdi, sdr.tdi, hdr.tdi )
493 tdo = combineBitVectors( tdr.tdo, sdr.tdo, hdr.tdo )
494
495 if xsdrsize != len(tdi):
496 xsdrsize = len(tdi)
497 cmdbuf[0] = XSDRSIZE
498 output.write( cmdbuf )
499 obuf = bytearray(4)
500 struct.pack_into(">i", obuf, 0, xsdrsize ) # big endian 4 byte int to obuf
501 output.write( obuf )
502
503 if xtdomask != mask:
504 xtdomask = mask
505 cmdbuf[0] = XTDOMASK
506 output.write( cmdbuf )
507 obuf = makeXSVFbytes( mask )
508 output.write( obuf )
509
510 cmdbuf[0] = XSDRTDO
511 output.write( cmdbuf )
512 obuf = makeXSVFbytes( tdi )
513 output.write( obuf )
514 obuf = makeXSVFbytes( tdo )
515 output.write( obuf )
516 #print( "len(tdo)=", len(tdo), "len(tdr.tdo)=", len(tdr.tdo), "len(sdr.tdo)=", len(sdr.tdo), "len(hdr.tdo)=", len(hdr.tdo) )
517
518 elif shiftOp == 'LSDR':
519 if doCOMMENTs:
520 writeComment( output, shiftOp_linenum, shiftOp )
521
522 mask = combineBitVectors( tdr.mask, sdr.mask, hdr.mask )
523 tdi = combineBitVectors( tdr.tdi, sdr.tdi, hdr.tdi )
524 tdo = combineBitVectors( tdr.tdo, sdr.tdo, hdr.tdo )
525
526 if xsdrsize != len(tdi):
527 xsdrsize = len(tdi)
528 cmdbuf[0] = XSDRSIZE
529 output.write( cmdbuf )
530 obuf = bytearray(4)
531 struct.pack_into(">i", obuf, 0, xsdrsize ) # big endian 4 byte int to obuf
532 output.write( obuf )
533
534 if xtdomask != mask:
535 xtdomask = mask
536 cmdbuf[0] = XTDOMASK
537 output.write( cmdbuf )
538 obuf = makeXSVFbytes( mask )
539 output.write( obuf )
540
541 cmdbuf[0] = LSDR
542 output.write( cmdbuf )
543 obuf = makeXSVFbytes( tdi )
544 output.write( obuf )
545 obuf = makeXSVFbytes( tdo )
546 output.write( obuf )
547 #print( "len(tdo)=", len(tdo), "len(tdr.tdo)=", len(tdr.tdo), "len(sdr.tdo)=", len(sdr.tdo), "len(hdr.tdo)=", len(hdr.tdo) )
548
549 elif tokVal == 'RUNTEST' or tokVal == 'LDELAY':
550 # e.g. from lattice tools:
551 # "RUNTEST IDLE 5 TCK 1.00E-003 SEC;"
552 saveTok = tokVal
553 nextTok()
554 min_time = 0
555 run_count = 0
556 max_time = 600 # ten minutes
557 if tokVal in run_state_allowed:
558 run_state = StateTxt.index(tokVal)
559 end_state = run_state # bottom of page 17 of SVF spec
560 nextTok()
561 if tokType != 'int' and tokType != 'float':
562 raise ParseError( tokLn, tokVal, "Expecting 'int' or 'float' after RUNTEST [run_state]")
563 timeval = tokVal;
564 nextTok()
565 if tokVal != 'TCK' and tokVal != 'SEC' and tokVal != 'SCK':
566 raise ParseError( tokLn, tokVal, "Expecting 'TCK' or 'SEC' or 'SCK' after RUNTEST [run_state] (run_count|min_time)")
567 if tokVal == 'TCK' or tokVal == 'SCK':
568 run_count = int( timeval )
569 else:
570 min_time = timeval
571 nextTok()
572 if tokType == 'int' or tokType == 'float':
573 min_time = tokVal
574 nextTok()
575 if tokVal != 'SEC':
576 raise ParseError( tokLn, tokVal, "Expecting 'SEC' after RUNTEST [run_state] run_count min_time")
577 nextTok()
578 if tokVal == 'MAXIMUM':
579 nextTok()
580 if tokType != 'int' and tokType != 'float':
581 raise ParseError( tokLn, tokVal, "Expecting 'max_time' after RUNTEST [run_state] min_time SEC MAXIMUM")
582 max_time = tokVal
583 nextTok()
584 if tokVal != 'SEC':
585 raise ParseError( tokLn, tokVal, "Expecting 'max_time' after RUNTEST [run_state] min_time SEC MAXIMUM max_time")
586 nextTok()
587 if tokVal == 'ENDSTATE':
588 nextTok()
589 if tokVal not in run_state_allowed:
590 raise ParseError( tokLn, tokVal, "Expecting 'run_state' after RUNTEST .... ENDSTATE")
591 end_state = StateTxt.index(tokVal)
592 nextTok()
593 if tokVal != ';':
594 raise ParseError( tokLn, tokVal, "Expecting ';' after RUNTEST ....")
595 # print( "run_count=", run_count, "min_time=", min_time,
596 # "max_time=", max_time, "run_state=", State[run_state], "end_state=", State[end_state] )
597 writeRUNTEST( output, run_state, end_state, run_count, min_time, saveTok )
598
599 elif tokVal == 'LCOUNT':
600 nextTok()
601 if tokType != 'int':
602 raise ParseError( tokLn, tokVal, "Expecting integer 'count' after LCOUNT")
603 loopCount = tokVal
604 nextTok()
605 if tokVal != ';':
606 raise ParseError( tokLn, tokVal, "Expecting ';' after LCOUNT count")
607 if doCOMMENTs:
608 writeComment( output, tokLn, 'LCOUNT' )
609 obuf = bytearray(5)
610 obuf[0] = LCOUNT
611 struct.pack_into(">i", obuf, 1, loopCount ) # big endian 4 byte int to obuf
612 output.write( obuf )
613
614 elif tokVal == 'ENDDR':
615 nextTok()
616 if tokVal not in enddr_state_allowed:
617 raise ParseError( tokLn, tokVal, "Expecting 'stable_state' after ENDDR. (one of: DRPAUSE, IDLE)")
618 enddr_state = StateTxt.index(tokVal)
619 nextTok()
620 if tokVal != ';':
621 raise ParseError( tokLn, tokVal, "Expecting ';' after ENDDR stable_state")
622 if doCOMMENTs:
623 writeComment( output, tokLn, 'ENDDR' )
624 obuf = bytearray(2)
625 obuf[0] = XENDDR
626 # Page 10 of the March 1999 SVF spec shows that RESET is also allowed here.
627 # Yet the XSVF spec has no provision for that, and uses a non-standard, i.e.
628 # boolean argument to XENDDR which only handles two of the 3 intended states.
629 obuf[1] = 1 if enddr_state == DRPAUSE else 0
630 output.write( obuf )
631
632 elif tokVal == 'ENDIR':
633 nextTok()
634 if tokVal not in endir_state_allowed:
635 raise ParseError( tokLn, tokVal, "Expecting 'stable_state' after ENDIR. (one of: IRPAUSE, IDLE)")
636 endir_state = StateTxt.index(tokVal)
637 nextTok()
638 if tokVal != ';':
639 raise ParseError( tokLn, tokVal, "Expecting ';' after ENDIR stable_state")
640 if doCOMMENTs:
641 writeComment( output, tokLn, 'ENDIR' )
642 obuf = bytearray(2)
643 obuf[0] = XENDIR
644 # Page 10 of the March 1999 SVF spec shows that RESET is also allowed here.
645 # Yet the XSVF spec has no provision for that, and uses a non-standard, i.e.
646 # boolean argument to XENDDR which only handles two of the 3 intended states.
647 obuf[1] = 1 if endir_state == IRPAUSE else 0
648 output.write( obuf )
649
650 elif tokVal == 'STATE':
651 nextTok()
652 ln = tokLn
653 while tokVal != ';':
654 if tokVal not in StateTxt:
655 raise ParseError( tokLn, tokVal, "Expecting 'stable_state' after STATE")
656 stable_state = StateTxt.index( tokVal )
657
658 if doCOMMENTs and ln != -1:
659 writeComment( output, ln, 'STATE' )
660 ln = -1 # save comment only once
661
662 obuf = bytearray(2)
663 obuf[0] = XSTATE
664 obuf[1] = stable_state
665 output.write( obuf )
666 nextTok()
667
668 elif tokVal == 'FREQUENCY':
669 nextTok()
670 if tokVal != ';':
671 if tokType != 'int' and tokType != 'float':
672 raise ParseError( tokLn, tokVal, "Expecting 'cycles HZ' after FREQUENCY")
673 frequency = tokVal
674 nextTok()
675 if tokVal != 'HZ':
676 raise ParseError( tokLn, tokVal, "Expecting 'HZ' after FREQUENCY cycles")
677 nextTok()
678 if tokVal != ';':
679 raise ParseError( tokLn, tokVal, "Expecting ';' after FREQUENCY cycles HZ")
680
681 elif tokVal == 'TRST':
682 nextTok()
683 if tokVal not in trst_mode_allowed:
684 raise ParseError( tokLn, tokVal, "Expecting 'ON|OFF|Z|ABSENT' after TRST")
685 trst_mode = tokVal
686 nextTok()
687 if tokVal != ';':
688 raise ParseError( tokLn, tokVal, "Expecting ';' after TRST trst_mode")
689 if doCOMMENTs:
690 writeComment( output, tokLn, 'TRST %s' % trst_mode )
691 obuf = bytearray( 2 )
692 obuf[0] = XTRST
693 obuf[1] = trst_mode_allowed.index( trst_mode ) # use the index as the binary argument to XTRST opcode
694 output.write( obuf )
695
696 else:
697 raise ParseError( tokLn, tokVal, "Unknown token '%s'" % tokVal)
698
699 except StopIteration:
700 if not expecting_eof:
701 print( "Unexpected End of File at line ", tokLn )
702
703 except ParseError as pe:
704 print( "\n", pe )
705
706 finally:
707 # print( "closing file" )
708 cmdbuf[0] = XCOMPLETE
709 output.write( cmdbuf )
710 output.close()

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)