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()