acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

DebugDecoder.py (3912B)

      1 import re, sys, argparse
      2 from pathlib import Path
      3 from argparse import RawTextHelpFormatter
      4 
      5 
      6 '''
      7 TODO list:
      8   1. Parse macro values (the names of bits in all registers in header file)
      9   2. Failed SPI write handling
     10   3. SX126x/SX128x handling
     11 '''
     12 
     13 
     14 def get_macro_name(value, macros):
     15     for macro in macros:
     16         if macro[1] == value:
     17             return macro[0]
     18     return 'UNKNOWN_VALUE'
     19 
     20 
     21 def get_macro_value(value):
     22     return '                         0x{0:02X}\n'.format(int(value, 16))
     23 
     24 
     25 parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
     26     RadioLib debug output decoder script. Turns RadioLib Serial dumps into readable text.
     27 
     28     Step-by-step guid on how to use the decoder:
     29     1. Uncomment lines 312 (#define RADIOLIB_DEBUG) and 313 (#define RADIOLIB_VERBOSE) in RadioLib/src/BuildOpt.h
     30     2. Recompile and upload the failing Arduino sketch
     31     3. Open Arduino IDE Serial Monitor and enable timestamps
     32     4. Copy the Serial output and save it into a .txt file
     33     5. Run this script
     34 
     35     Output will be saved in the file specified by --out and printed to the terminal
     36 ''')
     37 parser.add_argument('file', metavar='file', type=str, help='Text file of the debug output')
     38 parser.add_argument('--out', metavar='out', default='./out.txt', type=str, help='Where to save the decoded file (defaults to ./out.txt)')
     39 args = parser.parse_args()
     40 
     41 # open the log file
     42 log = open(args.file, 'r').readlines()
     43 
     44 # find modules that are in use
     45 used_modules = []
     46 pattern_module = re.compile('(([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?.[0-9]{3} -> )?M\t')
     47 for entry in log:
     48     m = pattern_module.search(entry)
     49     if m != None:
     50         used_modules.append(entry[m.end():].rstrip())
     51 
     52 # get paths to all relevant header files
     53 header_files = []
     54 for path in Path('../../src').rglob('*.h'):
     55     for module in used_modules:
     56         if module in path.name:
     57             header_files.append(path)
     58 
     59 # extract names of address macros from the header files
     60 macro_addresses = []
     61 pattern_define = re.compile('#define \w* +\w*(\n| +\/\/){1}')
     62 for path in header_files:
     63     file = open(path, 'r').readlines()
     64     for line in file:
     65         m = pattern_define.search(line)
     66         if m != None:
     67             s = re.split(' +', m.group().rstrip())
     68             if (s.__len__() > 1) and ('_REG' in s[1]):
     69                 macro_addresses.append([s[1], int(s[2], 0)])
     70 
     71 '''
     72 # extract names of value macros for each adddress macro
     73 macro_values = []
     74 for path in header_files:
     75     file = open(path, 'r').readlines()
     76     for line in file:
     77         for module in used_modules:
     78             pattern_addr_macro = re.compile('\/\/ SI443X_REG_\w+'.format(module.capitalize()))
     79 '''
     80 
     81 # parse every line in the log file
     82 out = []
     83 pattern_debug = re.compile('(([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?.[0-9]{3} -> )?[RWM]\t.+')
     84 for entry in log:
     85     m = pattern_debug.search(entry)
     86     if m != None:
     87         s = re.split('( |\t)+', entry.rstrip())
     88         cmd_len = int((s.__len__() - 7)/2)
     89         new_entry = s[0] + s[1] + s[2] + s[3]
     90         if s[4] == 'W':
     91             macro_address = int(s[6], 16)
     92             new_entry += 'write {0:>2} 0x{1:02X} {2}\n'.format(cmd_len, macro_address, get_macro_name(macro_address, macro_addresses))
     93             for i in range(cmd_len):
     94                 new_entry += get_macro_value(s[8 + 2*i]);
     95         elif s[4] == 'R':
     96             macro_address = int(s[6], 16)
     97             new_entry += 'read  {0:>2} 0x{1:02X} {2}\n'.format(cmd_len, macro_address, get_macro_name(macro_address, macro_addresses))
     98             for i in range(cmd_len):
     99                 new_entry += get_macro_value(s[8 + 2*i]);
    100         elif s[4] == 'M':
    101             new_entry += 'module {}\n'.format(s[6])
    102         out.append(new_entry)
    103     else:
    104         out.append(entry)
    105 
    106 # write the output file
    107 out_file = open(args.out, 'w')
    108 for line in out:
    109     print(line, end='')
    110     out_file.write(line)
    111 out_file.close()