Skip to content

Instantly share code, notes, and snippets.

@shima-529
Created April 9, 2021 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shima-529/10042e86455e0ed3c98fad4c9310f7f3 to your computer and use it in GitHub Desktop.
Save shima-529/10042e86455e0ed3c98fad4c9310f7f3 to your computer and use it in GitHub Desktop.
SCI Programmer for RA using python3. See: http://blueeyes.sakura.ne.jp/?p=3965
#!/usr/local/bin/python3
import sys
import time
import serial
port_name = sys.argv[1]
binary_name = sys.argv[2]
VERBOSE = False
class Color:
BLACK = '\033[30m'
RED = '\033[31m'
GREEN = '\033[32m'
YELLOW = '\033[33m'
BLUE = '\033[34m'
PURPLE = '\033[35m'
CYAN = '\033[36m'
WHITE = '\033[37m'
END = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
INVISIBLE = '\033[08m'
REVERCE = '\033[07m'
def send_cmd_packet(com, info): # {{{
ln = 1 + len(info)
lnh = ln >> 8
lnl = ln & 0xFF
cmd = [0x01] + [lnh] + [lnl] + [com] + info
sum_ = (~sum([lnh, lnl, com] + info) + 1) & 0xFF
cmd = bytearray(cmd + [sum_, 0x03])
ser.write(cmd)
# }}}
def send_data_packet(com, data): # {{{
ln = 1 + len(data)
lnh = ln >> 8
lnl = ln & 0xFF
cmd = [0x81] + [lnh] + [lnl] + [com] + data
sum_ = (~sum([lnh, lnl, com] + data) + 1) & 0xFF
cmd = bytearray(cmd + [sum_, 0x03])
ser.write(cmd)
# }}}
def split_word_into_list(word): # {{{
ret = []
for i in range(4):
ret += [word & 0xFF]
word >>= 8
ret.reverse()
return ret
# }}}
def recv_status(): # {{{
return ser.read(size=7)
# }}}
def status_is_ok(recv_data): # {{{
if len(recv_data) < 7:
raise Exception('Recv Data Length Error')
if recv_data[0] != 0x81:
return False
ln = (recv_data[1] << 8) | recv_data[2]
if recv_data[3] != 0x13:
return False
if recv_data[4 + ln + 1] != 0x03:
return False
return True
# }}}
def debug_printall(res):
if VERBOSE == False: return
for i in res:
print(hex(i), end=' ')
print('')
def main():
print(Color.BOLD + '\n=== Binary Loading ===' + Color.END)
with open(binary_name, 'rb') as f:
binary = list(f.read())
binary_size = len(binary)
padding_bytes = 0x2000 - binary_size % 0x2000
print('Binary Size: ' + str(binary_size))
print('Padding ' + str(padding_bytes) + ' bytes')
binary += [0xFF for _ in range(padding_bytes)]
binary_size += padding_bytes
print('==> Size Total: ' + str(binary_size) + ' Bytes')
print('Checking the designated binary...', end='')
if len(binary) >= 256 * 1024:
raise Exception('Binary Size Excess Error')
for i in range(0x408, 0x43C):
if binary[i] != 0xFF:
raise Exception('Security MPU Region Is Not All 0xFF')
print('OK')
global ser
with serial.Serial(port=port_name, baudrate=9600, timeout=0.1) as ser:
print(Color.BOLD + '\n=== SCI Connection ===' + Color.END)
print('Sending 2 pulses...')
ser.write([0x00, 0x00])
res = ord(ser.read())
if res == 0x00:
print('==>Response OK!')
else:
raise Exception('Response Error')
print('Sending Generic Code...')
send_cmd_packet(0x55, [])
res = ord(ser.read())
if res == 0xc3:
print('==>Response OK!')
else:
raise Exception('Response Error')
print('Changing baud rate...')
BAUD = 115200 * 8
send_cmd_packet(0x34, split_word_into_list(BAUD));
res = recv_status()
if res[3] == 0x34:
print('==>BaudRate changed to ' + str(BAUD) + '.')
ser.baudrate = BAUD
else:
print('==>BaudRate Change failed. Falling back to default 9600...')
debug_printall(res)
# TODO: Add Baud Rate Setting Cmd
print(Color.BOLD + '\n=== Main Execution ===' + Color.END)
print('Erasing the Flash pages required...')
for i in range(binary_size // 0x400):
print(str(i + 1) + '...')
ERASE_CMD = 0x12
send_cmd_packet(ERASE_CMD, split_word_into_list(0x00000000) + split_word_into_list(0x400 * (i + 1) - 1))
res = recv_status()
debug_printall(res)
print('\nWriting Binary...')
WRITE_CMD = 0x13
send_cmd_packet(WRITE_CMD, split_word_into_list(0x00000000) + split_word_into_list(binary_size - 1))
res = recv_status()
debug_printall(res)
for i in range(binary_size // 1024):
start_pos = 1024 * i
end_pos = 1024 * (i + 1)
send_data_packet(WRITE_CMD, binary[start_pos : end_pos])
res = recv_status()
print(str(i) + ':')
debug_printall(res)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment