from RAConnect import *
from RAPacker import *
-SECTOR_SIZE = 2048
+VENDOR_ID = 0x045B
+PRODUCT_ID = 0x0261
+
+commands = {
+ "write": lambda dev, args: write_img(dev, args.file_name, args.start_address, args.size, args.verify),
+ "read": lambda dev, args: read_img(dev, args.file_name, args.start_address, args.size),
+ "erase": lambda dev, args: erase_chip(dev, args.start_address, args.size),
+ "info": lambda dev, args: (get_dev_info(dev), dev.set_chip_layout(get_area_info(dev, output=True)))
+}
def int_to_hex_list(num):
hex_string = hex(num)[2:].upper() # convert to hex string
except ValueError:
raise argparse.ArgumentTypeError(f"'{string}' is not a valid hexadecimal value.")
-def set_size_boundaries(start_addr, size):
- if start_addr % SECTOR_SIZE:
- raise ValueError(f"start addr not aligned on sector size {SECTOR_SIZE}")
+def set_size_boundaries(dev, start_addr, size):
+
+ sector_size = dev.chip_layout[dev.sel_area]['ALIGN'] # currently only area 0 supported
- if size < SECTOR_SIZE:
+ if start_addr % sector_size:
+ raise ValueError(f"start addr not aligned on sector size {sector_size}")
+
+ if size < sector_size:
print("Warning: you are trying to write something that is less than one sector size: padding with zeroes")
- blocks = (size + SECTOR_SIZE - 1) // SECTOR_SIZE
- end_addr = blocks * SECTOR_SIZE + start_addr - 1
+ blocks = (size + sector_size - 1) // sector_size
+ end_addr = blocks * sector_size + start_addr - 1
if (end_addr <= start_addr):
raise ValueError(f"End address smaller or equal than start_address")
- if (end_addr > 0x3FFFF):
+ if (end_addr > dev.chip_layout[dev.sel_area]['EAD']):
raise ValueError(f"Binary file is bigger than available ROM space")
return (start_addr, end_addr)
-def inquire_connection(dev):
- packed = pack_pkt(INQ_CMD, "")
- dev.send_data(packed)
- info = dev.recv_data(7)
- if info == bytearray(b'\x00') or info == bytearray(b''):
- return False
- msg = unpack_pkt(info)
- #print("Connection already established")
- return True
-
-def get_area_info(dev):
+def get_area_info(dev, output=False):
+ cfg = {}
for i in [0,1,2]:
packed = pack_pkt(ARE_CMD, [str(i)])
dev.send_data(packed)
msg = unpack_pkt(info)
fmt = '>BIIII'
KOA, SAD, EAD, EAU, WAU = struct.unpack(fmt, bytes(int(x, 16) for x in msg))
- print(f'Area {KOA}: {hex(SAD)}:{hex(EAD)} (erase {hex(EAU)} - write {hex(WAU)})')
+ cfg[i] = {"SAD": SAD, "EAD": EAD, "ALIGN": EAU}
+ if output:
+ print(f'Area {KOA}: {hex(SAD)}:{hex(EAD)} (erase {hex(EAU)} - write {hex(WAU)})')
+
+ return cfg
def get_dev_info(dev):
packed = pack_pkt(SIG_CMD, "")
elif TYP == 0x03:
print('Chip: RA MCU + RA6 Series')
else:
- rint('Unknown MCU type')
+ print('Unknown MCU type')
print(f'Serial interface speed: {SCI} Hz')
print(f'Recommend max UART baud rate: {RMB} bps')
print(f'User area in Code flash [{NOA & 0x1}|{NOA & 0x02 >> 1}]')
def erase_chip(dev, start_addr, size):
if size == None:
- size = 0x3FFFF - start_addr # erase all
+ size = dev.chip_layout[dev.sel_area]['EAD'] - start_addr # erase all
- (start_addr, end_addr) = set_size_boundaries(start_addr, size)
+ (start_addr, end_addr) = set_size_boundaries(dev, start_addr, size)
print(f'Erasing {hex(start_addr)}:{hex(end_addr)}')
# setup initial communication
if size == None:
size = 0x3FFFF - start_addr # read maximum possible
- (start_addr, end_addr) = set_size_boundaries(start_addr, size)
- print(hex(start_addr), hex(end_addr))
+ (start_addr, end_addr) = set_size_boundaries(dev, start_addr, size)
# setup initial communication
SAD = int_to_hex_list(start_addr)
if size > file_size:
raise ValueError("Write size > file size")
- (start_addr, end_addr) = set_size_boundaries(start_addr, size)
- print(start_addr, end_addr)
+ (start_addr, end_addr) = set_size_boundaries(dev, start_addr, size)
chunk_size = 1024 # max is 1024 according to protocol
ret = dev.recv_data(7)
unpack_pkt(ret)
+ totalread = 0
with open(img, 'rb') as f:
- with tqdm(total=file_size, desc="Writing progress") as pbar:
+ with tqdm(total=size, desc="Writing progress") as pbar:
chunk = f.read(chunk_size)
pbar.update(len(chunk))
- while chunk:
+ while chunk and totalread < size:
if len(chunk) != chunk_size:
padding_length = chunk_size - len(chunk)
chunk += b'\0' * padding_length
reply = dev.recv_data(reply_len)
msg = unpack_pkt(reply)
chunk = f.read(chunk_size)
+ totalread += chunk_size
pbar.update(len(chunk))
subparsers = parser.add_subparsers(dest="command", title="Commands")
- # Subparser for the write command
write_parser = subparsers.add_parser("write", help="Write data to flash")
write_parser.add_argument("--start_address", type=hex_type, default='0x0000', help="Start address")
write_parser.add_argument("--size", type=hex_type, default=None, help="Size in bytes")
write_parser.add_argument("--verify", action="store_true", help="Verify after writing")
write_parser.add_argument("file_name", type=str, help="File name")
- # Subparser for the read command
read_parser = subparsers.add_parser("read", help="Read data from flash")
read_parser.add_argument("--start_address", type=hex_type, default='0x0000', help="Start address")
read_parser.add_argument("--size", type=hex_type, default=None, help="Size in bytes")
erase_parser.add_argument("--start_address", default='0x0000', type=hex_type, help="Start address")
erase_parser.add_argument("--size", type=hex_type, help="Size")
- # Subparser for the info command
subparsers.add_parser("info", help="Show flasher information")
args = parser.parse_args()
-
- if args.command == "write":
- dev = RAConnect(vendor_id=0x045B, product_id=0x0261)
- status_con = inquire_connection(dev)
- if not status_con:
- dev.confirm_connection()
- #print(args.start_address, args.size)
- write_img(dev, args.file_name, args.start_address, args.size, args.verify)
- elif args.command == "read":
- dev = RAConnect(vendor_id=0x045B, product_id=0x0261)
- status_con = inquire_connection(dev)
- if not status_con:
- dev.confirm_connection()
- read_img(dev, args.file_name, args.start_address, args.size)
- elif args.command == "erase":
- dev = RAConnect(vendor_id=0x045B, product_id=0x0261)
- status_con = inquire_connection(dev)
- if not status_con:
- dev.confirm_connection()
- erase_chip(dev, args.start_address, args.size)
- elif args.command == "info":
- dev = RAConnect(vendor_id=0x045B, product_id=0x0261)
- status_con = inquire_connection(dev)
- if not status_con:
- dev.confirm_connection()
- get_dev_info(dev)
- get_area_info(dev)
+
+ if args.command in commands:
+ dev = RAConnect(VENDOR_ID, PRODUCT_ID)
+ area_cfg = get_area_info(dev)
+ dev.set_chip_layout(area_cfg)
+ commands[args.command](dev, args)
else:
parser.print_help()
if __name__ == "__main__":
main()
-