+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
+ hex_string = hex_string.zfill(8) # pad for 8 char's long
+ hex_list = [f'0x{hex_string[c:c+2]}' for c in range(0, 8, 2)]
+ return hex_list
+
+def hex_type(string):
+ try:
+ value = int(string, 16)
+ return value
+ except ValueError:
+ raise argparse.ArgumentTypeError(f"'{string}' is not a valid hexadecimal value.")
+
+def set_size_boundaries(dev, start_addr, size):
+
+ sector_size = dev.chip_layout[dev.sel_area]['ALIGN'] # currently only area 0 supported
+
+ 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
+
+ if (end_addr <= start_addr):
+ raise ValueError(f"End address smaller or equal than start_address")
+
+ 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 get_area_info(dev, output=False):
+ cfg = {}
+ for i in [0,1,2]:
+ packed = pack_pkt(ARE_CMD, [str(i)])
+ dev.send_data(packed)
+ info = dev.recv_data(23)
+ msg = unpack_pkt(info)
+ fmt = '>BIIII'
+ KOA, SAD, EAD, EAU, WAU = struct.unpack(fmt, bytes(int(x, 16) for x in msg))
+ 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