1515# Differences between full PDS and compressed PDS are:
1616# 1. Comments are stripped
1717# 2. Symbolic names are replaced with their values
18- # 3. Hexadecimal and binary numbers are replaced by their decimal values
18+ # 3. All numbers (decimal, hexadecimal and binary) are replaced by their
19+ # hexadecimal values (without '0x' prefix)
1920# 4. New lines and spaces are stripped
2021#
2122# In two words, output of this script is more or less same as:
3132# Avoid syntax error with python 2.x
3233from __future__ import print_function
3334
34- # If you modifiy this file, please don't forget to increment version number.
35- __version__ = "1.1 "
35+ # If you modify this file, please don't forget to increment version number.
36+ __version__ = "1.4 "
3637
3738import io
3839import os
3940import sys
4041import re
42+ import struct
4143import textwrap
4244import argparse
4345
4446class DebugInfo ():
45- def __init__ (self , path = "" , line = 0 ):
47+ def __init__ (self , path = "" , line = 0 ):
4648 self .path = path
4749 self .line = line
4850
@@ -261,8 +263,8 @@ def check_syntax():
261263 '}' : [ ',' , ']' , '}' , 'E' ],
262264 ']' : [ ',' , ']' , '}' , 'E' ],
263265 }
264- brace_stack = [ ];
265- cur_state = AnnotOut (g_result [- 1 ].loc , 'S' );
266+ brace_stack = [ ]
267+ cur_state = AnnotOut (g_result [- 1 ].loc , 'S' )
266268
267269 for annot_tok in token_iter ():
268270 tok = annot_tok .val
@@ -276,20 +278,20 @@ def check_syntax():
276278 pr_info (annot_tok .loc , "error: parsing error" )
277279 return False
278280 else :
279- cur_state = annot_tok
280- if tok in [ '{' , '[' ]:
281- brace_stack .append (tok )
282- if tok == '}' :
283- if brace_stack .pop () != '{' :
284- pr_info (annot_tok .loc , "error: unexpected '}'" );
285- return False
286- if tok == ']' :
287- if brace_stack .pop () != '[' :
288- pr_info (annot_tok .loc , "error: unexpected ']'" );
289- return False
290- if tok == 'E' and len ( brace_stack ) > 0 :
291- pr_info (annot_tok .loc , "error: unbalanced %s" % brace_stack .pop ());
292- return False
281+ cur_state = annot_tok
282+ if tok in [ '{' , '[' ]:
283+ brace_stack .append (tok )
284+ if tok in [ '}' ] :
285+ if brace_stack .pop () != '{' :
286+ pr_info (annot_tok .loc , "error: unexpected '}'" );
287+ return False
288+ if tok in [ ']' ] :
289+ if brace_stack .pop () != '[' :
290+ pr_info (annot_tok .loc , "error: unexpected ']'" );
291+ return False
292+ if tok in [ 'E' ] and brace_stack :
293+ pr_info (annot_tok .loc , "error: unbalanced %s" % brace_stack .pop ());
294+ return False
293295 return True
294296
295297def check_sizes (pds_str ):
@@ -300,9 +302,9 @@ def check_sizes(pds_str):
300302 for c in pds_str :
301303 if c in ",:}]" :
302304 num_token += 1
303- if c == '{' or c == '[' :
305+ if c in [ '{' , '[' ] :
304306 brace_level += 1
305- if c == '}' or c == ']' :
307+ if c in [ '}' , ']' ] :
306308 brace_level -= 1
307309 if brace_level == 1 :
308310 if num_token >= 256 :
@@ -356,33 +358,100 @@ def formatc(f_out, pds):
356358 stack = 0
357359 buf = ""
358360 out = ""
361+ for c in pds :
362+ buf += c
363+ if c in [ '{' , '[' ]:
364+ stack += 1
365+ if c in [ '}' , ']' ]:
366+ stack -= 1
367+ if c in [ '}' , ']' ] and stack == 1 :
368+ out += ' "{%s}",\n ' % buf [1 :];
369+ buf = ""
370+ f_out .write (textwrap .dedent (tmpl_c ) % out );
371+
372+ tmpl_rust = """\
373+ /* AUTOMATICALLY GENERATED -- DO NOT EDIT BY HAND */
374+ /*
375+ * Copyright 2018, Silicon Laboratories Inc. All rights reserved.
376+ *
377+ * Licensed under the Apache License, Version 2.0 (the "License");
378+ * you may not use this file except in compliance with the License.
379+ * You may obtain a copy of the License at
380+ *
381+ * http://www.apache.org/licenses/LICENSE-2.0
382+ *
383+ * Unless required by applicable law or agreed to in writing, software
384+ * distributed under the License is distributed on an "AS IS" BASIS,
385+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
386+ * See the License for the specific language governing permissions and
387+ * limitations under the License.
388+ *
389+ */
390+
391+ /// PDS (platform data set) is SiLab's solution to configuring the wifi chip.
392+ /// Options such as GPIO, PA power, number of antennae are configured with PDS.
393+ /// The data set here is "compiled" using a script (pds_compress) that
394+ /// can be found in SiliconLabs github repository:
395+ /// https://github.com/SiliconLabs/wfx-linux-tools/blob/master/pds_compress
396+ ///
397+ /// The output is meant to be redirected into a .rs file in the same crate as your
398+ /// hal driver, and pulled in with the appropriate mod/use statements.
399+
400+ pub const PDS_DATA: [&[u8]; %d] = [
401+ %s];
402+ """
403+
404+ def formatrust (f_out , pds ):
405+ stack = 0
406+ lines = 0
407+ buf = ""
408+ out = ""
359409 for c in pds :
360410 buf += c
361411 if c == '{' or c == '[' :
362412 stack += 1
363413 if c == '}' or c == ']' :
364414 stack -= 1
365415 if (c == '}' or c == ']' ) and stack == 1 :
366- out += ' "{%s}",\n ' % buf [1 :];
416+ lines += 1
417+ out += ' b"{%s}\\ 0", \n ' % buf [1 :];
367418 buf = ""
368- f_out .write (textwrap .dedent (tmpl_c ) % out );
419+ f_out .write (textwrap .dedent (tmpl_rust ) % ( lines , out ) );
369420
370421def formattiny (f_out , pds ):
371422 stack = 0
372423 for c in pds :
373- if c == '}' or c == ']' :
424+ if c in [ '}' , ']' ] :
374425 stack -= 1
375426 f_out .write ("\n " + " " * stack );
376427 f_out .write (c );
377- if c == ':' :
428+ if c in [ ':' ] :
378429 f_out .write (" " );
379- if c == '{' or c == '[' :
430+ if c in [ '{' , '[' ] :
380431 stack += 1
381432 f_out .write ("\n " + " " * stack );
382- if c == ',' :
433+ if c in [ ',' ] :
383434 f_out .write ("\n " + " " * stack );
384435 f_out .write ("\n " );
385436
437+ def formattlv (f_out , pds ):
438+ stack = 0
439+ buf = ''
440+ for c in pds :
441+ if c in [ '{' , '[' ]:
442+ stack += 1
443+ if c in [ '}' , ']' ]:
444+ stack -= 1
445+ if c in [ ',' ] and stack == 1 :
446+ buf = '{'
447+ elif c in [ '}' , ']' ] and stack == 1 :
448+ buf += c
449+ buf += '}'
450+ f_out .write (struct .pack ('<HH' , 0x4450 , len (buf ) + 4 ).decode ('charmap' ));
451+ f_out .write (buf );
452+ elif stack > 0 :
453+ buf += c
454+
386455def parse_cmdline (args = sys .argv [1 :]):
387456 parser = argparse .ArgumentParser (usage = "%(prog)s [options] INPUT [OUTPUT]" ,
388457 description = "Generate a compressed version of PDS from a full PDS" )
@@ -398,16 +467,20 @@ def parse_cmdline(args=sys.argv[1:]):
398467 help = "predefine DEF with value VAL" )
399468 parser .add_argument ("-f" , "--force" , action = "store_true" , dest = "force" ,
400469 help = "try to produce (probably broken) output even if errors are detected" )
401- parser .add_argument ("--out" , dest = "out_format" , default = "pds" , choices = ['pds' , 'tinypds' , 'c' , 'json' ],
402- help = "specify output format. Accepted values: pds (compressed PDS), tinypds (indented PDS), c (C file), json. Default: pds" )
470+ parser .add_argument ("--out" , dest = "out_format" , default = "pds" , choices = ['tlv' , ' pds' , 'tinypds' , 'c' , 'json' ],
471+ help = "specify output format. Accepted values: pds (compressed PDS), tlv (compressed PDS in TLV structs), tinypds (indented PDS), c (C file), json. Default: pds" )
403472 parser .add_argument ("-j" , action = "store_const" , const = "json" , dest = "out_format" ,
404473 help = "shortcut for --out=json" )
405474 parser .add_argument ("-c" , action = "store_const" , const = "c" , dest = "out_format" ,
406475 help = "shortcut for --out=c" )
407476 parser .add_argument ("-p" , action = "store_const" , const = "pds" , dest = "out_format" ,
408477 help = "shortcut for --out=pds" )
478+ parser .add_argument ("-l" , action = "store_const" , const = "tlv" , dest = "out_format" ,
479+ help = "shortcut for --out=tlv" )
409480 parser .add_argument ("-t" , action = "store_const" , const = "tinypds" , dest = "out_format" ,
410481 help = "shortcut for --out=tinypds" )
482+ parser .add_argument ("-r" , action = "store_const" , const = "rust" , dest = "out_format" ,
483+ help = "shortcut for --out=rust" )
411484 return parser .parse_args (args )
412485
413486def main (options ):
@@ -447,16 +520,23 @@ def main(options):
447520 formattiny (options .output , re .sub (r'([-A-Za-z0-9]+)' , r'"\1"' , str_result ))
448521 elif options .out_format == "c" :
449522 formatc (options .output , str_result )
523+ elif options .out_format == "rust" :
524+ formatrust (options .output , str_result )
450525 elif options .out_format == "tinypds" :
451526 formattiny (options .output , str_result )
527+ elif options .out_format == "tlv" :
528+ # We may apply this encoding to all the other outputs. However, the TLV
529+ # is the only one which generates binary data.
530+ options .output .reconfigure (encoding = 'charmap' , newline = '' )
531+ formattlv (options .output , str_result )
452532 elif options .out_format == "pds" :
453533 options .output .write (str_result )
454534 else :
455535 raise Exception ('bad out_format value' )
456536 return g_ret_value
457537
458538# This function is only an help for third-party tools that import pds_compress
459- # as a python module (also note it is necessary to add .py extension to this in
539+ # as a python module (also note it is necessary to add .py extention to this in
460540# order to import it).
461541def compress_string (str_in , extra_options = "" ):
462542 global g_defs , g_result , g_ret_value
0 commit comments