RAFlasher.py: initial get_dev_info
[renesas-ra-flasher] / src / RAFlasher.py
1 import os
2 import math
3 import argparse
4 from RAConnect import *
5 from RAPacker import *
6
7 SECTOR_SIZE = 2048
8
9 def get_dev_info(dev):
10
11     packed = pack_pkt(SIG_CMD, "")
12     dev.send_data(packed)
13     #info_ret = dev.recv_data(17)
14     info = b'\x81\x00\x0D\x3A\x01\x31\x2d\x00\x00\x1e\x84\x80\x04\x02\x0a\x08' # test
15     fmt = '>IIIBBH'
16     _HEADER, SCI, RMB, NOA, TYP, BFV = struct.unpack(fmt, info)
17     print(f'Ver{BFV >> 8}.{BFV & 0xFF}')
18
19 def verify_img(dev, img, start_addr, end_addr):
20     raise Exception("Not implemented")
21
22 def write_img(dev, img, start_addr, end_addr, verify=False):
23
24     if os.path.exists(img):
25         file_size = os.path.getsize(img)
26     else:
27         raise Exception(f'file {img} does not exist')
28
29     # calculate / check start and end address 
30     if start_addr == None or end_addr == None:
31         if start_addr == None:
32             start_addr = 0
33         # align start addr
34         if start_addr % SECTOR_SIZE:
35             raise ValueError(f"start addr not aligned on sector size {SECTOR_SIZE}")
36         blocks = (file_size + SECTOR_SIZE - 1) // SECTOR_SIZE
37         end_addr = blocks * SECTOR_SIZE + start_addr
38         print(end_addr)
39     
40     chunk_size = 64 # max is 1024
41     if (start_addr > 0xFF800): # for RA4 series
42         raise ValueError("start address value error")
43     if (end_addr <= start_addr or end_addr > 0xFF800):
44         raise ValueError("end address value error")
45
46     # @TODO setup initial communication
47
48     with open(img, 'rb') as f:
49         chunk = f.read(chunk_size)
50         while chunk:
51             packed = pack_pkt(WRI_CMD, chunk)
52             print(f'Sending {len(chunk)} bytes')
53             dev.send_data(packed)
54             reply_len = 7
55             reply = dev.recv_data(reply_len)
56             #reply = b'\x81\x00\x02\x00\x00\xFE\x03' # test reply
57             if not reply == False:
58                 msg = unpack_pkt(reply)
59                 print(msg)
60             chunk = f.read(chunk_size)
61
62 def main():
63     parser = argparse.ArgumentParser(description="RA Flasher Tool")
64
65     subparsers = parser.add_subparsers(dest="command", title="Commands")
66
67     # Subparser for the write command
68     write_parser = subparsers.add_parser("write", help="Write data to flash")
69     write_parser.add_argument("--start_address", type=int, default=0x0000, help="Start address")
70     write_parser.add_argument("--end_address", type=int, help="End address")
71     write_parser.add_argument("--verify", action="store_true", help="Verify after writing")
72     write_parser.add_argument("file_name", type=str, help="File name")
73
74     # Subparser for the read command
75     read_parser = subparsers.add_parser("read", help="Read data from flash")
76     read_parser.add_argument("--start_address", type=int, default=0x000, help="Start address")
77     read_parser.add_argument("--size", type=int, default=1024, help="Size in bytes")
78     read_parser.add_argument("file_name", type=str, help="File name")
79
80     # Subparser for the info command
81     subparsers.add_parser("info", help="Show flasher information")
82
83     args = parser.parse_args()
84
85     if args.command == "write":
86         dev = RAConnect(vendor_id=0x1a86, product_id=0x7523)
87         print(args)
88         write_img(dev, args.file_name, args.start_address, args.end_address, args.verify)
89     elif args.command == "read":
90         print('read command')
91     elif args.command == "info":
92         dev = RAConnect(vendor_id=0x1a86, product_id=0x7523)
93         get_dev_info(dev)
94     else:
95         parser.print_help()
96
97 if __name__ == "__main__":
98     main()
99