diff --git a/mik32_eeprom.py b/mik32_eeprom.py index da6d68d..8c9f276 100644 --- a/mik32_eeprom.py +++ b/mik32_eeprom.py @@ -1,7 +1,7 @@ -from typing import List +from typing import Dict, List import time from tclrpc import OpenOcdTclRpc -from mik32_upload import Segment, MemorySection +from mik32_upload import Segment, MemorySection, bytes2words # -------------------------- # PM register offset @@ -152,12 +152,14 @@ def eeprom_write_page(openocd: OpenOcdTclRpc, address:int, data:List[int]): openocd.write_word(EEPROM_REGS_EECON, (1 << EEPROM_EX_S) | (1 << EEPROM_BWE_S) | (EEPROM_OP_PR << EEPROM_OP_S)) time.sleep(0.001) -def eeprom_check_data_apb(openocd: OpenOcdTclRpc, words: List[int]) -> int: - print("EEPROM check through APB...") - openocd.write_word(EEPROM_REGS_EEA, 0x00000000) +def eeprom_check_data_apb(openocd: OpenOcdTclRpc, words: List[int], offset: int, print_progress=True) -> int: + if print_progress: + print("EEPROM check through APB...") + openocd.write_word(EEPROM_REGS_EEA, offset) word_num = 0 progress = 0 - print("[", end="", flush=True) + if print_progress: + print("[", end="", flush=True) for word in words: value:int = openocd.read_word(EEPROM_REGS_EEDAT) if words[word_num] != value: @@ -165,35 +167,39 @@ def eeprom_check_data_apb(openocd: OpenOcdTclRpc, words: List[int]) -> int: return 1 word_num += 1 curr_progress = int((word_num * 50) / len(words)) - if curr_progress > progress: + if print_progress and (curr_progress > progress): print("#"*(curr_progress - progress), end="", flush=True) progress = curr_progress - print("]") - print("EEPROM check through APB done!") + if print_progress: + print("]") + print("EEPROM check through APB done!") return 0 -def eeprom_check_data_ahb_lite(openocd: OpenOcdTclRpc, words: List[int]) -> int: - print("EEPROM check through AHB-Lite...") - mem_array = openocd.read_memory(0x01000000, 32, len(words)) +def eeprom_check_data_ahb_lite(openocd: OpenOcdTclRpc, words: List[int], offset: int, print_progress=True) -> int: + if print_progress: + print("EEPROM check through AHB-Lite...") + mem_array = openocd.read_memory(0x01000000 + offset, 32, len(words)) if len(words) != len(mem_array): raise Exception("Wrong number of words in read_memory output!") progress = 0 - print("[", end="", flush=True) + if print_progress: + print("[", end="", flush=True) for word_num in range(len(words)): if words[word_num] != mem_array[word_num]: print(f"Unexpect value at {word_num} word, expect {words[word_num]:#0x}, \ get {mem_array[word_num]:#0x}") return 1 curr_progress = int((word_num * 50) / len(words)) - if curr_progress > progress: + if print_progress and (curr_progress > progress): print("#"*(curr_progress - progress), end="", flush=True) progress = curr_progress - print("]") - print("EEPROM check through APB done!") + if print_progress: + print("]") + print("EEPROM check through APB done!") return 0 -def write_words(words: List[int], openocd: OpenOcdTclRpc, write_by_word = False, read_through_apb = False, is_resume=True, ) -> int: +def write_words(words: List[int], openocd: OpenOcdTclRpc, write_by_word = False, read_through_apb = False, is_resume=True) -> int: """ Write words in MIK32 EEPROM through APB bus @@ -248,9 +254,9 @@ def write_words(words: List[int], openocd: OpenOcdTclRpc, write_by_word = False, eeprom_write_page(openocd, page_num*page_size*4, page) print("]") if read_through_apb: - result = eeprom_check_data_apb(openocd, words) + result = eeprom_check_data_apb(openocd, words, 0) else: - result = eeprom_check_data_ahb_lite(openocd, words) + result = eeprom_check_data_ahb_lite(openocd, words, 0) if is_resume: openocd.resume(0) @@ -258,3 +264,36 @@ def write_words(words: List[int], openocd: OpenOcdTclRpc, write_by_word = False, print("EEPROM write file done!") return result + +def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, read_through_apb = False, is_resume=True) -> int: + result = 0 + + openocd.halt() + eeprom_sysinit(openocd) + eeprom_global_erase(openocd) + # eeprom_global_erase_check(openocd) + openocd.write_word(EEPROM_REGS_NCYCRL, 1< Dict: exit() return memory_blocks - - -def bytes2words(arr: List[int]) -> List[int]: - bytes = [] - words = [] - for byte in arr: - bytes.append(byte) - if bytes.__len__() == 4: - words.append(bytes[0]+2**8*bytes[1]+2**16*bytes[2]+2**24*bytes[3]) - bytes = [] - if bytes.__len__() != 0: - print("WARNING: skipping not-word-aligned byte") - return words diff --git a/mik32_upload.py b/mik32_upload.py index a6fce1d..cb534dd 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -123,19 +123,28 @@ def read_file(filename: str) -> List[Segment]: return segments -def segments_to_pages(segments: List[Segment], page_size: int) -> List[Page]: +def segment_to_pages(segment: Segment, page_size: int, pages: Dict[int, List[int]]): + if segment.memory is None: + return + + internal_offset = segment.offset - segment.memory.offset + + for i, byte in enumerate(segment.data): + byte_offset = internal_offset + i + page_n = byte_offset // page_size + page_offset = page_n * page_size + + if (page_offset) not in pages.keys(): + pages[page_offset] = [0] * page_size + + pages[page_offset][byte_offset - page_offset] = byte + + +def segments_to_pages(segments: List[Segment], page_size: int) -> Dict[int, List[int]]: pages: Dict[int, List[int]] = {} for segment in segments: - if segment.memory is None: - continue - - internal_offset = segment.offset - segment.memory.offset - - for i, byte in enumerate(segment.data): - byte_offset = internal_offset + i - - pages[byte_offset % 256] + segment_to_pages(segment, page_size, pages) return pages @@ -172,29 +181,39 @@ def upload_file(filename: str, host: str = '127.0.0.1', port: int = OpenOcdTclRp raise Exception("ERROR: segment with offset %s and length %s overflows section %s" % ( hex(segment.offset), segment.data.__len__(), segment.memory.type.name)) - print(segments_to_pages(list(filter( - lambda segment: (segment.memory is not None) and (segment.memory.type == MemoryType.EEPROM), segments)), 128)) + proc: subprocess.Popen | None = None + if run_openocd: + cmd = shlex.split("%s -s %s -f interface/ftdi/m-link.cfg -f target/mcu32.cfg" % ( + DEFAULT_OPENOCD_EXEC_FILE_PATH, DEFAULT_OPENOCD_SCRIPTS_PATH), posix=False) + proc = subprocess.Popen( + cmd, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE) - # proc: subprocess.Popen | None = None - # if run_openocd: - # cmd = shlex.split("%s -s %s -f interface/ftdi/m-link.cfg -f target/mcu32.cfg" % ( - # DEFAULT_OPENOCD_EXEC_FILE_PATH, DEFAULT_OPENOCD_SCRIPTS_PATH), posix=False) - # proc = subprocess.Popen( - # cmd, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE) + with OpenOcdTclRpc() as openocd: + pages_eeprom = segments_to_pages(list(filter( + lambda segment: (segment.memory is not None) and (segment.memory.type == MemoryType.EEPROM), segments)), 128) + result = mik32_eeprom.write_pages(pages_eeprom, openocd, is_resume) + # elif segment_section.type == MemoryType.SPIFI: + # result = mik32_spifi.spifi_write_file(segment.data, openocd, is_resume) - # with OpenOcdTclRpc() as openocd: - # if segment_section.type == MemoryType.EEPROM: - # result = mik32_eeprom.write_words(bytes2words( - # segment.data), openocd, is_resume) - # elif segment_section.type == MemoryType.SPIFI: - # result = mik32_spifi.spifi_write_file(segment.data, openocd, is_resume) - - # if run_openocd and proc is not None: - # proc.kill() + if run_openocd and proc is not None: + proc.kill() return result +def bytes2words(arr: List[int]) -> List[int]: + bytes = [] + words = [] + for byte in arr: + bytes.append(byte) + if bytes.__len__() == 4: + words.append(bytes[0]+2**8*bytes[1]+2**16*bytes[2]+2**24*bytes[3]) + bytes = [] + if bytes.__len__() != 0: + print("WARNING: skipping not-word-aligned byte") + return words + + def createParser(): parser = argparse.ArgumentParser() parser.add_argument('filepath', nargs='?') @@ -204,6 +223,8 @@ def createParser(): '--openocd-host', dest='openocd_host', default='127.0.0.1') parser.add_argument('--openocd-port', dest='openocd_port', default=OpenOcdTclRpc.DEFAULT_PORT) + parser.add_argument('--keep-halt', dest='keep_halt', + action='store_true', default=False) # parser.add_argument('-b', '--boot-mode', default='undefined') return parser @@ -215,6 +236,6 @@ if __name__ == '__main__': if namespace.filepath: upload_file(namespace.filepath, namespace.openocd_host, - namespace.openocd_port, run_openocd=namespace.run_openocd) + namespace.openocd_port, is_resume=(not namespace.keep_halt), run_openocd=namespace.run_openocd) else: print("Nothing to upload")