m10_freq.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #!/bin/python3
  2. import argparse
  3. import sys
  4. import os
  5. # Create a parser
  6. parser = argparse.ArgumentParser(description='Patch a M10 firmware for specific frequenc.\nThis is for M10 based on MSP430F233.')
  7. parser.add_argument('--verbose', action='store_true', help='Print the details', default=False)
  8. # Lecture du binaire
  9. subparsers = parser.add_subparsers()
  10. p_readbin = subparsers.add_parser("readbin", help='Read the binary file')
  11. p_readbin.add_argument('--input', type=str, help='Input file')
  12. p_readbin.set_defaults(func="readbin")
  13. # Ecriture du binaire
  14. p_writebin = subparsers.add_parser("writebin", help='Write the binary file')
  15. p_writebin.set_defaults(func="writebin")
  16. p_writebin.add_argument('--input', type=str, help='Input file')
  17. p_writebin.add_argument('--output', type=str, help='Output file')
  18. p_writebin.add_argument('--frequency', type=int, help='Frequency in Hz')
  19. args = parser.parse_args()
  20. if not hasattr(args, 'func'):
  21. print('error: arguments are required\n'
  22. 'use --help for more information',
  23. file=sys.stderr)
  24. sys.exit(os.EX_USAGE)
  25. if args.func == "writebin" and args.verbose:
  26. print("Writing the binary file")
  27. print("File : " + args.input)
  28. print("Output : " + args.output)
  29. print("Frequency : " + str(args.frequency))
  30. def hex_to_freq(hex_value):
  31. inverted_hex_value = hex(int(hex_value[4:6] + hex_value[2:4] + hex_value[0:2], 16))
  32. shifted_bin_value = bin(int(inverted_hex_value, 16) >> 2)
  33. if args.verbose:
  34. print("Binary value : \t\t" + bin(int(inverted_hex_value, 16)))
  35. print("Binary value shifted : \t" + str(shifted_bin_value))
  36. return int(shifted_bin_value, 2) / 512
  37. # function to convert frequence to hex
  38. # Coded on 20 bits in binary format.
  39. def freq_to_hex(freq_base):
  40. freq=freq_base/1000
  41. if args.verbose:
  42. print("Frequency: " + str(freq) + "Hz")
  43. print("freq * 512 = " + str(freq*512))
  44. print("arrondu freq * 512 = " + str(int(freq*512)))
  45. print("binary : " + str(bin(int(freq*512))))
  46. print("binare + 01 : " + str(bin(int(freq*512)) + "01"))
  47. print("binary str : " + str(bin(int(freq*512)) + "01").replace("0b",""))
  48. value = str(hex(int(str(bin(int(freq*512)) + "01").replace("0b",""),2)))[2:]
  49. print("hex value calculated : 0x" + value)
  50. # invert the value
  51. # draft and dirty value flip-flop
  52. value1="0" + value[0:1]
  53. value2=value[1:3]
  54. value3=value[3:5]
  55. if args.verbose:
  56. print("value : " + value)
  57. print ("value1 : " + value1 + " value2 : " + value2 + " value3 : " + value3)
  58. print("hex value inverted : 0x" + value3 + value2 + value1)
  59. return value3 + value2 + value1
  60. def write_output_line(line):
  61. # write the output line
  62. with open(args.output, 'a') as f_out:
  63. f_out.write(line)
  64. f_out.close()
  65. def fix_checksum(line):
  66. print("Fixing the checksum")
  67. # calculate the checksum
  68. checksum = 0
  69. print("Checksum : \n" + line)
  70. byte1 = hex(int(line[1:3], 16))
  71. byte2 = hex(int(line[3:5], 16))
  72. byte3 = hex(int(line[5:7], 16))
  73. byte4 = hex(int(line[7:9], 16))
  74. byte5 = hex(int(line[9:11], 16))
  75. byte6 = hex(int(line[11:13], 16))
  76. byte7 = hex(int(line[13:15], 16))
  77. byte8 = hex(int(line[15:17], 16))
  78. byte9 = hex(int(line[17:19], 16))
  79. byte10 = hex(int(line[19:21], 16))
  80. byte11 = hex(int(line[21:23], 16))
  81. byte12 = hex(int(line[23:25], 16))
  82. byte13 = hex(int(line[25:27], 16))
  83. byte14 = hex(int(line[27:29], 16))
  84. byte15 = hex(int(line[29:31], 16))
  85. byte16 = hex(int(line[31:33], 16))
  86. byte17 = hex(int(line[33:35], 16))
  87. byte18 = hex(int(line[35:37], 16))
  88. byte19 = hex(int(line[37:39], 16))
  89. byte20 = hex(int(line[39:41], 16))
  90. # checksum intel hex format
  91. checksum = 0x100 - (int(byte1, 16) + int(byte2, 16) + int(byte3, 16) + int(byte4, 16) + int(byte5, 16) + int(byte6, 16) + int(byte7, 16) + int(byte8, 16) + int(byte9, 16) + int(byte10, 16) + int(byte11, 16) + int(byte12, 16) + int(byte13, 16) + int(byte14, 16) + int(byte15, 16) + int(byte16, 16) + int(byte17, 16) + int(byte18, 16) + int(byte19, 16) + int(byte20, 16)) % 0x100
  92. print("Checksum : " + str(hex(checksum)))
  93. return checksum
  94. # check if the input file exists
  95. try:
  96. with open(args.input, 'rb') as f:
  97. pass
  98. except FileNotFoundError:
  99. print(f'Error: {args.input} does not exist')
  100. exit(1)
  101. if args.func == "readbin":
  102. print("")
  103. print("Reading the frequency value for M10...")
  104. # print each line of the input file
  105. with open(args.input, 'rb') as f:
  106. for line in f:
  107. if ":10101000" in line.decode('utf-8'):
  108. if args.verbose:
  109. print("Found the frequency sequence in Hex Intel format : " + line.decode('utf-8')[9:15])
  110. print("Frequency read : " + str(hex_to_freq(line.decode('utf-8')[9:15])))
  111. exit(0)
  112. if args.func == "writebin":
  113. if os.path.exists(args.output):
  114. os.remove(args.output)
  115. with open(args.output, 'wb') as f_new:
  116. f_new.close()
  117. print("Calculating the frequency "+ str(args.frequency) +"Hz value for M10...")
  118. # print each line of the input file
  119. with open(args.input, 'rb') as f_in:
  120. for line in f_in:
  121. if ":10101000" in line.decode('utf-8'):
  122. if args.verbose:
  123. print("Found the frequency line like this : " + str(line))
  124. print("Frequency sequence in Hex Intel format : " + line.decode('utf-8')[9:15])
  125. print("Actual frequency value : " + str(hex_to_freq(line.decode('utf-8')[9:15])) + "Hz")
  126. new_freq = freq_to_hex(args.frequency)
  127. print("New frequency value : " + str(args.frequency) + "Hz")
  128. # replace the frequency value
  129. new_line = line.decode('utf-8').replace(line.decode('utf-8')[9:15], new_freq).upper()
  130. print("New line : " + new_line)
  131. #replace two last bytes with the checksum
  132. new_line = new_line[0:41] + str(hex(fix_checksum(new_line)))[2:].upper() + "\n"
  133. print("New line with checksum : " + new_line)
  134. write_output_line(new_line)
  135. else:
  136. write_output_line(line.decode('utf-8'))
  137. f_in.close()