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

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)