From f576a4f4785fa75059945b89038cd564cf9a721f Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Mon, 29 May 2023 16:00:22 +0300 Subject: [PATCH 1/9] WIP test platformio support --- .piopm | 1 + mik32_upload.py | 59 ++++++++++++++++++++++++++++++++++++------------- package.json | 15 +++++++++++++ tclrpc.py | 40 +++++++++++++++++++++++---------- 4 files changed, 88 insertions(+), 27 deletions(-) create mode 100644 .piopm create mode 100644 package.json diff --git a/.piopm b/.piopm new file mode 100644 index 0000000..3deea79 --- /dev/null +++ b/.piopm @@ -0,0 +1 @@ +{"type": "tool", "name": "tool-mik32-uploader", "version": "0.1.0", "spec": {"owner": "platformio", "id": 1235, "name": "tool-mik32-uploader", "requirements": null, "uri": null}} \ No newline at end of file diff --git a/mik32_upload.py b/mik32_upload.py index c2baf7a..7b5fc93 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -61,7 +61,7 @@ mik32v0_sections: List[MemorySection] = [ @dataclass class Segment: offset: int - memory: MemorySection | None + memory: MemorySection or None data: List[int] @@ -74,7 +74,7 @@ def belongs_memory_section(memory_section: MemorySection, offset: int) -> bool: return True -def find_memory_section(offset: int) -> MemorySection | None: +def find_memory_section(offset: int) -> MemorySection or None: for section in mik32v0_sections: if belongs_memory_section(section, offset): return section @@ -126,7 +126,7 @@ def read_file(filename: str) -> List[Segment]: 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): @@ -136,7 +136,7 @@ def segment_to_pages(segment: Segment, page_size: int, pages: Dict[int, List[int if (page_offset) not in pages.keys(): pages[page_offset] = [0] * page_size - + pages[page_offset][byte_offset - page_offset] = byte @@ -145,11 +145,21 @@ def segments_to_pages(segments: List[Segment], page_size: int) -> Dict[int, List for segment in segments: segment_to_pages(segment, page_size, pages) - + return pages -def upload_file(filename: str, host: str = '127.0.0.1', port: int = OpenOcdTclRpc.DEFAULT_PORT, is_resume=True, run_openocd=False, use_quad_spi=False) -> int: +def upload_file( + filename: str, + openocd_path: str, + scripts_path: str, + adapter_speed: str, + host: str = '127.0.0.1', + port: int = OpenOcdTclRpc.DEFAULT_PORT, + is_resume=True, + run_openocd=False, + use_quad_spi=False +) -> int: """ Write ihex or binary file into MIK32 EEPROM or external flash memory @@ -165,6 +175,7 @@ def upload_file(filename: str, host: str = '127.0.0.1', port: int = OpenOcdTclRp result = 0 + print(filename) if not os.path.exists(filename): print("ERROR: File %s does not exist" % filename) exit(1) @@ -181,12 +192,13 @@ 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)) - proc: subprocess.Popen | None = None + proc: subprocess.Popen or 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) + cmd = shlex.split("%s -s %s -f interface/ftdi/m-link.cfg -f target/mik32.cfg" % ( + openocd_path, scripts_path), posix=False) + print(cmd) proc = subprocess.Popen( - cmd, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE) + cmd) with OpenOcdTclRpc() as openocd: pages_eeprom = segments_to_pages(list(filter( @@ -195,12 +207,14 @@ def upload_file(filename: str, host: str = '127.0.0.1', port: int = OpenOcdTclRp lambda segment: (segment.memory is not None) and (segment.memory.type == MemoryType.SPIFI), segments)), 256) segments_ram = list(filter( lambda segment: (segment.memory is not None) and (segment.memory.type == MemoryType.RAM), segments)) - + if (pages_eeprom.__len__() > 0): - result |= mik32_eeprom.write_pages(pages_eeprom, openocd, is_resume) + result |= mik32_eeprom.write_pages( + pages_eeprom, openocd, is_resume) if (pages_spifi.__len__() > 0): # print(pages_spifi) - result |= mik32_spifi.write_pages(pages_spifi, openocd, is_resume, use_quad_spi) + result |= mik32_spifi.write_pages( + pages_spifi, openocd, is_resume, use_quad_spi) if (segments_ram.__len__() > 0): mik32_ram.write_segments(segments_ram, openocd, is_resume) result |= 0 @@ -214,6 +228,12 @@ def upload_file(filename: str, host: str = '127.0.0.1', port: int = OpenOcdTclRp def createParser(): parser = argparse.ArgumentParser() parser.add_argument('filepath', nargs='?') + parser.add_argument('--openocd-path', dest='openocd_path', + default=DEFAULT_OPENOCD_EXEC_FILE_PATH) + parser.add_argument('--scripts-path', dest='scripts_path', + default=DEFAULT_OPENOCD_SCRIPTS_PATH) + parser.add_argument('--adapter-speed', dest='adapter_speed', + default=500) parser.add_argument('--run-openocd', dest='run_openocd', action='store_true', default=False) parser.add_argument('--use-quad-spi', dest='use_quad_spi', @@ -234,7 +254,16 @@ if __name__ == '__main__': namespace = parser.parse_args() if namespace.filepath: - upload_file(namespace.filepath, namespace.openocd_host, - namespace.openocd_port, is_resume=(not namespace.keep_halt), run_openocd=namespace.run_openocd, use_quad_spi=namespace.use_quad_spi) + upload_file( + namespace.filepath, + namespace.openocd_path, + namespace.scripts_path, + namespace.adapter_speed, + host=namespace.openocd_host, + port=namespace.openocd_port, + is_resume=(not namespace.keep_halt), + run_openocd=namespace.run_openocd, + use_quad_spi=namespace.use_quad_spi, + ) else: print("Nothing to upload") diff --git a/package.json b/package.json new file mode 100644 index 0000000..1760bd4 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "tool-mik32-uploader", + "version": "0.1.0", + "description": "mik32-uploader", + "keywords": [ + "tools", + "uploader", + "mik32" + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/MikronMIK32/mik32-uploader" + } +} diff --git a/tclrpc.py b/tclrpc.py index 6b58d82..095e8fd 100644 --- a/tclrpc.py +++ b/tclrpc.py @@ -128,8 +128,20 @@ class OpenOcdTclRpc: return self.run(f"capture \"write_memory {address:#0x} {width} {{{data_string}}}\"") def write_word(self, address:int, word:int): - return self.write_memory(address, 32, [word]) + return self.run(f"capture \"mww {address:#0x} {word}\"") + # def read_memory(self, address:int, width:int, count:int): + # """This function provides an efficient way to read the target memory from a Tcl script. + # A Tcl list containing the requested memory elements is returned by this function. + + # address ... target memory address + + # width ... memory access bit size, can be 8, 16, 32 or 64 + + # count ... number of elements to read """ + # data = self.run(f"capture \"read_memory {address:#0x} {width} {count}\"").split(" ") + # return list(map(lambda word: int(word, base=16), data)) + def read_memory(self, address:int, width:int, count:int): """This function provides an efficient way to read the target memory from a Tcl script. A Tcl list containing the requested memory elements is returned by this function. @@ -139,19 +151,23 @@ class OpenOcdTclRpc: width ... memory access bit size, can be 8, 16, 32 or 64 count ... number of elements to read """ - data = self.run(f"capture \"read_memory {address:#0x} {width} {count}\"").split(" ") + data = self.run(f"capture \"mem2array {width} {address:#0x} {count}\"").split(" ") return list(map(lambda word: int(word, base=16), data)) + # def read_word(self, address:int): + # """This function provides an efficient way to read the target memory from a Tcl script. + # A Tcl list containing the requested memory elements is returned by this function. + + # address ... target memory address + + # width ... memory access bit size, can be 8, 16, 32 or 64 + + # count ... number of elements to read """ + # data = self.run(f"capture \"read_memory {address:#0x} 32 1\"").split(" ") + # return int(data[0], base=16) + def read_word(self, address:int): - """This function provides an efficient way to read the target memory from a Tcl script. - A Tcl list containing the requested memory elements is returned by this function. - - address ... target memory address - - width ... memory access bit size, can be 8, 16, 32 or 64 - - count ... number of elements to read """ - data = self.run(f"capture \"read_memory {address:#0x} 32 1\"").split(" ") - return int(data[0], base=16) + data = self.run(f"capture \"mdw {address:#0x}\"").split(" ") + return int(data[1], base=16) From 23666d49fa7b26a76f4dff11c1d2cdd31584270d Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Mon, 29 May 2023 16:15:28 +0300 Subject: [PATCH 2/9] update ocd 0.12 --- tclrpc.py | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/tclrpc.py b/tclrpc.py index 095e8fd..6b58d82 100644 --- a/tclrpc.py +++ b/tclrpc.py @@ -128,20 +128,8 @@ class OpenOcdTclRpc: return self.run(f"capture \"write_memory {address:#0x} {width} {{{data_string}}}\"") def write_word(self, address:int, word:int): - return self.run(f"capture \"mww {address:#0x} {word}\"") + return self.write_memory(address, 32, [word]) - # def read_memory(self, address:int, width:int, count:int): - # """This function provides an efficient way to read the target memory from a Tcl script. - # A Tcl list containing the requested memory elements is returned by this function. - - # address ... target memory address - - # width ... memory access bit size, can be 8, 16, 32 or 64 - - # count ... number of elements to read """ - # data = self.run(f"capture \"read_memory {address:#0x} {width} {count}\"").split(" ") - # return list(map(lambda word: int(word, base=16), data)) - def read_memory(self, address:int, width:int, count:int): """This function provides an efficient way to read the target memory from a Tcl script. A Tcl list containing the requested memory elements is returned by this function. @@ -151,23 +139,19 @@ class OpenOcdTclRpc: width ... memory access bit size, can be 8, 16, 32 or 64 count ... number of elements to read """ - data = self.run(f"capture \"mem2array {width} {address:#0x} {count}\"").split(" ") + data = self.run(f"capture \"read_memory {address:#0x} {width} {count}\"").split(" ") return list(map(lambda word: int(word, base=16), data)) - # def read_word(self, address:int): - # """This function provides an efficient way to read the target memory from a Tcl script. - # A Tcl list containing the requested memory elements is returned by this function. - - # address ... target memory address - - # width ... memory access bit size, can be 8, 16, 32 or 64 - - # count ... number of elements to read """ - # data = self.run(f"capture \"read_memory {address:#0x} 32 1\"").split(" ") - # return int(data[0], base=16) - def read_word(self, address:int): - data = self.run(f"capture \"mdw {address:#0x}\"").split(" ") - return int(data[1], base=16) + """This function provides an efficient way to read the target memory from a Tcl script. + A Tcl list containing the requested memory elements is returned by this function. + + address ... target memory address + + width ... memory access bit size, can be 8, 16, 32 or 64 + + count ... number of elements to read """ + data = self.run(f"capture \"read_memory {address:#0x} 32 1\"").split(" ") + return int(data[0], base=16) From 46c72768e0d0db339a41f0a4383cc9621601b3de Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Mon, 29 May 2023 16:58:36 +0300 Subject: [PATCH 3/9] debug output wip --- mik32_spifi.py | 3 ++- mik32_upload.py | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mik32_spifi.py b/mik32_spifi.py index 96a7a66..fb7660d 100644 --- a/mik32_spifi.py +++ b/mik32_spifi.py @@ -319,7 +319,8 @@ def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_d for i in range(byte_count): data8 = openocd.read_memory(SPIFI_CONFIG_DATA32, 8, 1)[0] read_data.append(data8) - # print(f"DATA[{i+address}] = {read_data[i]:#0x}") + if is_verbose: + print(f"DATA[{i+address}] = {read_data[i]:#0x}") for i in range(byte_count): if read_data[i] != bin_data[i]: diff --git a/mik32_upload.py b/mik32_upload.py index 7b5fc93..a46a761 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -26,6 +26,7 @@ DEFAULT_OPENOCD_SCRIPTS_PATH = os.path.join( supported_formats = [".hex"] +is_verbose = False def test_connection(): output = "" @@ -244,6 +245,8 @@ def createParser(): default=OpenOcdTclRpc.DEFAULT_PORT) parser.add_argument('--keep-halt', dest='keep_halt', action='store_true', default=False) + parser.add_argument('--verbose', dest='is_verbose', + action='store_true', default=False) # parser.add_argument('-b', '--boot-mode', default='undefined') return parser @@ -252,6 +255,7 @@ def createParser(): if __name__ == '__main__': parser = createParser() namespace = parser.parse_args() + is_verbose = namespace.is_verbose if namespace.filepath: upload_file( From 9c184971ca0188df6ecaddf7ec313da6243e365a Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Mon, 29 May 2023 17:34:29 +0300 Subject: [PATCH 4/9] wip --- config.py | 1 + mik32_spifi.py | 7 ++++--- mik32_upload.py | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 config.py diff --git a/config.py b/config.py new file mode 100644 index 0000000..031e011 --- /dev/null +++ b/config.py @@ -0,0 +1 @@ +is_verbose = False \ No newline at end of file diff --git a/mik32_spifi.py b/mik32_spifi.py index fb7660d..c3911d6 100644 --- a/mik32_spifi.py +++ b/mik32_spifi.py @@ -3,6 +3,7 @@ from typing import Dict, List import time from tclrpc import TclException from tclrpc import OpenOcdTclRpc +import config # -------------------------- # PM register offset @@ -319,13 +320,13 @@ def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_d for i in range(byte_count): data8 = openocd.read_memory(SPIFI_CONFIG_DATA32, 8, 1)[0] read_data.append(data8) - if is_verbose: + if config.is_verbose: print(f"DATA[{i+address}] = {read_data[i]:#0x}") for i in range(byte_count): if read_data[i] != bin_data[i]: - print(f"DATA[{i+address}] = {read_data[i]:#0x} - ошибка") - return 1 + print(f"DATA[{(i+address):#0x}] = {read_data[i]:#0x}, expected {bin_data[i]:#0x}") + # return 1 return 0 diff --git a/mik32_upload.py b/mik32_upload.py index a46a761..7c485c1 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -9,6 +9,7 @@ import mik32_eeprom import mik32_spifi import mik32_ram from mik32_parsers import * +import config # class bcolors(Enum): @@ -245,7 +246,7 @@ def createParser(): default=OpenOcdTclRpc.DEFAULT_PORT) parser.add_argument('--keep-halt', dest='keep_halt', action='store_true', default=False) - parser.add_argument('--verbose', dest='is_verbose', + parser.add_argument('-v', '--verbose', dest='is_verbose', action='store_true', default=False) # parser.add_argument('-b', '--boot-mode', default='undefined') @@ -255,7 +256,7 @@ def createParser(): if __name__ == '__main__': parser = createParser() namespace = parser.parse_args() - is_verbose = namespace.is_verbose + config.is_verbose = namespace.is_verbose if namespace.filepath: upload_file( From 9f9c6f2a3cc2919451f8f2e5bca00ed18b2c7931 Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Tue, 30 May 2023 11:46:28 +0300 Subject: [PATCH 5/9] add more console info and checking erase --- mik32_spifi.py | 33 +++++++++++++++++++++++++++++++-- mik32_upload.py | 2 +- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/mik32_spifi.py b/mik32_spifi.py index c3911d6..cca07f2 100644 --- a/mik32_spifi.py +++ b/mik32_spifi.py @@ -307,6 +307,32 @@ def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int): spifi_wait_intrq_timeout(openocd, "Timeout executing chip erase command") +def spifi_check_erase(openocd: OpenOcdTclRpc, address: int, byte_count: int): + print(f"Checking erase from {address:#0x} to {(byte_count-1):#0x}") + + read_data: List[int] = [] + openocd.write_word(SPIFI_CONFIG_ADDR, address) + + spifi_intrq_clear(openocd) + openocd.write_word(SPIFI_CONFIG_CMD, (READ_DATA_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | + (SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR << SPIFI_CONFIG_CMD_FRAMEFORM_S) | + (SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL << SPIFI_CONFIG_CMD_FIELDFORM_S) | + (byte_count << SPIFI_CONFIG_CMD_DATALEN_S)) + # spifi_wait_intrq_timeout(openocd, "Timeout executing read data command") + for i in range(byte_count): + data8 = openocd.read_memory(SPIFI_CONFIG_DATA32, 8, 1)[0] + read_data.append(data8) + if config.is_verbose: + print(f"DATA[{i+address}] = {read_data[i]:#0x}") + + for i in range(byte_count): + if read_data[i] != 0: + print(f"DATA[{(i+address):#0x}] = {read_data[i]:#0x}, expected {0:#0x}") + return 1 + + return 0 + + def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_data: List[int]) -> int: read_data: List[int] = [] openocd.write_word(SPIFI_CONFIG_ADDR, address) @@ -326,7 +352,7 @@ def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_d for i in range(byte_count): if read_data[i] != bin_data[i]: print(f"DATA[{(i+address):#0x}] = {read_data[i]:#0x}, expected {bin_data[i]:#0x}") - # return 1 + return 1 return 0 @@ -335,6 +361,7 @@ def spifi_page_program(openocd: OpenOcdTclRpc, ByteAddress: int, data: List[int] if byte_count > 256: raise Exception("Byte count more than 256") + print("Writing page %s..." % hex(ByteAddress)) # spifi_intrq_clear(openocd) openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) @@ -366,11 +393,13 @@ def spifi_erase(openocd, erase_type: EraseType = EraseType.CHIP_ERASE, sectors: spifi_write_enable(openocd) spifi_chip_erase(openocd) spifi_wait_busy(openocd) + spifi_check_erase(openocd, 0, 65536) elif erase_type == EraseType.SECTOR_ERASE: for sector in sectors: spifi_write_enable(openocd) spifi_sector_erase(openocd, sector) spifi_wait_busy(openocd) + spifi_check_erase(openocd, 0, 4096) def spifi_write(openocd: OpenOcdTclRpc, address: int, data: List[int], data_len: int): @@ -419,6 +448,7 @@ def spifi_quad_page_program(openocd: OpenOcdTclRpc, ByteAddress: int, data: List if byte_count > 256: raise Exception("Byte count more than 256") + print("Writing page %s..." % hex(ByteAddress)) # spifi_intrq_clear(openocd) openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) @@ -494,7 +524,6 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, is_resume=T spifi_quad_enable(openocd) for page_offset in list(pages): - print("Writing page %s..." % hex(page_offset)) page_bytes = pages[page_offset] spifi_write_enable(openocd) diff --git a/mik32_upload.py b/mik32_upload.py index 7c485c1..fed0538 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -200,7 +200,7 @@ def upload_file( openocd_path, scripts_path), posix=False) print(cmd) proc = subprocess.Popen( - cmd) + cmd, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE) with OpenOcdTclRpc() as openocd: pages_eeprom = segments_to_pages(list(filter( From 23da63fa3c32f5dc856e1606ea7ef864b92c1f50 Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Tue, 30 May 2023 14:10:40 +0300 Subject: [PATCH 6/9] fix typing --- mik32_upload.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/mik32_upload.py b/mik32_upload.py index fed0538..7af6789 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -3,7 +3,7 @@ import argparse import subprocess import os from enum import Enum -from typing import List, Dict, NamedTuple +from typing import List, Dict, NamedTuple, Union from tclrpc import OpenOcdTclRpc import mik32_eeprom import mik32_spifi @@ -29,6 +29,7 @@ supported_formats = [".hex"] is_verbose = False + def test_connection(): output = "" with OpenOcdTclRpc() as openocd: @@ -52,8 +53,11 @@ class MemorySection(NamedTuple): length: int # Memory section length in bytes +MEMORY_SECTION_BOOT = MemorySection(MemoryType.BOOT, 0x0, 16 * 1024) + + mik32v0_sections: List[MemorySection] = [ - MemorySection(MemoryType.BOOT, 0x0, 16 * 1024), + MEMORY_SECTION_BOOT, MemorySection(MemoryType.EEPROM, 0x01000000, 8 * 1024), MemorySection(MemoryType.RAM, 0x02000000, 16 * 1024), MemorySection(MemoryType.SPIFI, 0x80000000, 8 * 1024 * 1024), @@ -76,7 +80,7 @@ def belongs_memory_section(memory_section: MemorySection, offset: int) -> bool: return True -def find_memory_section(offset: int) -> MemorySection or None: +def find_memory_section(offset: int) -> Union[MemorySection, None]: for section in mik32v0_sections: if belongs_memory_section(section, offset): return section @@ -96,7 +100,7 @@ def read_file(filename: str) -> List[Segment]: with open(filename, "rb") as f: contents = list(f.read()) segments.append( - Segment(offset=0, memory=find_memory_section(0), data=contents)) + Segment(offset=0, memory=MEMORY_SECTION_BOOT, data=contents)) else: raise Exception("Unsupported file format: %s" % (file_extension)) @@ -109,8 +113,10 @@ def read_file(filename: str) -> List[Segment]: drlo: int = record.address # Data Record Load Offset if (expect_address != lba+drlo) or (segments.__len__() == 0): expect_address = lba+drlo - segments.append(Segment( - offset=expect_address, memory=find_memory_section(expect_address), data=[])) + section = find_memory_section(expect_address) + if section is not None: + segments.append(Segment( + offset=expect_address, memory=section, data=[])) for byte in record.data: segments[-1].data.append(byte) @@ -194,7 +200,7 @@ def upload_file( raise Exception("ERROR: segment with offset %s and length %s overflows section %s" % ( hex(segment.offset), segment.data.__len__(), segment.memory.type.name)) - proc: subprocess.Popen or None = None + proc: Union[subprocess.Popen, None] = None if run_openocd: cmd = shlex.split("%s -s %s -f interface/ftdi/m-link.cfg -f target/mik32.cfg" % ( openocd_path, scripts_path), posix=False) From 42fb564db974ea07669b682f632414c212fdd053 Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Tue, 30 May 2023 15:01:39 +0300 Subject: [PATCH 7/9] unify read data functions --- mik32_spifi.py | 51 +++++++++++++++++++++++++------------------------ mik32_upload.py | 8 ++++++-- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/mik32_spifi.py b/mik32_spifi.py index cca07f2..b5b9d11 100644 --- a/mik32_spifi.py +++ b/mik32_spifi.py @@ -286,7 +286,7 @@ def spifi_wait_busy(openocd: OpenOcdTclRpc): def spifi_chip_erase(openocd: OpenOcdTclRpc): print("Chip erase...") - # spifi_intrq_clear(openocd) + spifi_intrq_clear(openocd) openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_CMD, (SECTOR_ERASE_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | @@ -298,7 +298,7 @@ def spifi_chip_erase(openocd: OpenOcdTclRpc): def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int): print("Erase sector %s..." % hex(address)) openocd.write_word(SPIFI_CONFIG_ADDR, address) - # spifi_intrq_clear(openocd) + spifi_intrq_clear(openocd) openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_CMD, (CHIP_ERASE_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | @@ -307,9 +307,7 @@ def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int): spifi_wait_intrq_timeout(openocd, "Timeout executing chip erase command") -def spifi_check_erase(openocd: OpenOcdTclRpc, address: int, byte_count: int): - print(f"Checking erase from {address:#0x} to {(byte_count-1):#0x}") - +def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int) -> List[int]: read_data: List[int] = [] openocd.write_word(SPIFI_CONFIG_ADDR, address) @@ -324,6 +322,13 @@ def spifi_check_erase(openocd: OpenOcdTclRpc, address: int, byte_count: int): read_data.append(data8) if config.is_verbose: print(f"DATA[{i+address}] = {read_data[i]:#0x}") + + return read_data + + +def spifi_check_erase(openocd: OpenOcdTclRpc, address: int, byte_count: int): + print(f"Checking erase from {address:#0x} to {(byte_count-1):#0x}") + read_data: List[int] = spifi_read_data(openocd, address, byte_count) for i in range(byte_count): if read_data[i] != 0: @@ -333,21 +338,11 @@ def spifi_check_erase(openocd: OpenOcdTclRpc, address: int, byte_count: int): return 0 -def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_data: List[int]) -> int: - read_data: List[int] = [] - openocd.write_word(SPIFI_CONFIG_ADDR, address) +def spifi_check_program(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_data: List[int]) -> int: + read_data: List[int] = spifi_read_data(openocd, address, byte_count) - spifi_intrq_clear(openocd) - openocd.write_word(SPIFI_CONFIG_CMD, (READ_DATA_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | - (SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR << SPIFI_CONFIG_CMD_FRAMEFORM_S) | - (SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL << SPIFI_CONFIG_CMD_FIELDFORM_S) | - (byte_count << SPIFI_CONFIG_CMD_DATALEN_S)) - # spifi_wait_intrq_timeout(openocd, "Timeout executing read data command") - for i in range(byte_count): - data8 = openocd.read_memory(SPIFI_CONFIG_DATA32, 8, 1)[0] - read_data.append(data8) - if config.is_verbose: - print(f"DATA[{i+address}] = {read_data[i]:#0x}") + if read_data.__len__ != byte_count: + return 1 for i in range(byte_count): if read_data[i] != bin_data[i]: @@ -399,7 +394,7 @@ def spifi_erase(openocd, erase_type: EraseType = EraseType.CHIP_ERASE, sectors: spifi_write_enable(openocd) spifi_sector_erase(openocd, sector) spifi_wait_busy(openocd) - spifi_check_erase(openocd, 0, 4096) + spifi_check_erase(openocd, sector, sector + 4096) def spifi_write(openocd: OpenOcdTclRpc, address: int, data: List[int], data_len: int): @@ -428,14 +423,14 @@ def spifi_write_file(bytes: List[int], openocd: OpenOcdTclRpc, is_resume=True): break print("address = ", address) spifi_write(openocd, address, bytes, 256) - if spifi_read_data(openocd, address, 256, bytes) == 1: + if spifi_check_program(openocd, address, 256, bytes) == 1: return 1 if (len(bytes) % 256) != 0: print( f"address = {address}, +{len(bytes) - address-1}[{address + len(bytes) - address-1}]") spifi_write(openocd, address, bytes, len(bytes) - address) - if spifi_read_data(openocd, address, len(bytes) - address, bytes) == 1: + if spifi_check_program(openocd, address, len(bytes) - address, bytes) == 1: return 1 print("end") if is_resume: @@ -513,12 +508,18 @@ def get_segments_list(pages_offsets: List[int], segment_size: int) -> List[int]: return list(segments) -def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, is_resume=True, use_quad_spi=False): +def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, is_resume=True, use_quad_spi=False, use_chip_erase=False): result = 0 openocd.halt() spifi_init(openocd) - spifi_erase(openocd, EraseType.SECTOR_ERASE, get_segments_list(list(pages), 4*1024)) + + if use_chip_erase: + erase_type = EraseType.CHIP_ERASE + else: + erase_type = EraseType.SECTOR_ERASE + + spifi_erase(openocd, erase_type, get_segments_list(list(pages), 4*1024)) address = 0 spifi_quad_enable(openocd) @@ -533,7 +534,7 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, is_resume=T spifi_page_program(openocd, page_offset, page_bytes, 256) spifi_wait_busy(openocd) - result = spifi_read_data(openocd, page_offset, 256, page_bytes) + result = spifi_check_program(openocd, page_offset, 256, page_bytes) if result == 1: print("Data error") diff --git a/mik32_upload.py b/mik32_upload.py index 7af6789..9fa67d7 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -166,7 +166,8 @@ def upload_file( port: int = OpenOcdTclRpc.DEFAULT_PORT, is_resume=True, run_openocd=False, - use_quad_spi=False + use_quad_spi=False, + use_chip_erase=False, ) -> int: """ Write ihex or binary file into MIK32 EEPROM or external flash memory @@ -222,7 +223,7 @@ def upload_file( if (pages_spifi.__len__() > 0): # print(pages_spifi) result |= mik32_spifi.write_pages( - pages_spifi, openocd, is_resume, use_quad_spi) + pages_spifi, openocd, is_resume, use_quad_spi, use_chip_erase) if (segments_ram.__len__() > 0): mik32_ram.write_segments(segments_ram, openocd, is_resume) result |= 0 @@ -254,6 +255,8 @@ def createParser(): action='store_true', default=False) parser.add_argument('-v', '--verbose', dest='is_verbose', action='store_true', default=False) + parser.add_argument('--use-chip-erase', dest='use_chip_erase', + action='store_true', default=False) # parser.add_argument('-b', '--boot-mode', default='undefined') return parser @@ -275,6 +278,7 @@ if __name__ == '__main__': is_resume=(not namespace.keep_halt), run_openocd=namespace.run_openocd, use_quad_spi=namespace.use_quad_spi, + use_chip_erase=namespace.use_chip_erase, ) else: print("Nothing to upload") From b9e217f35680f3fb554cc8c613871d5128c81786 Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Tue, 30 May 2023 15:36:33 +0300 Subject: [PATCH 8/9] wip --- mik32_spifi.py | 16 +++++++++------- mik32_upload.py | 3 +-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mik32_spifi.py b/mik32_spifi.py index b5b9d11..c452384 100644 --- a/mik32_spifi.py +++ b/mik32_spifi.py @@ -298,7 +298,9 @@ def spifi_chip_erase(openocd: OpenOcdTclRpc): def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int): print("Erase sector %s..." % hex(address)) openocd.write_word(SPIFI_CONFIG_ADDR, address) - spifi_intrq_clear(openocd) + # spifi_intrq_clear(openocd) + openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( + SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_CMD, (CHIP_ERASE_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | @@ -311,7 +313,9 @@ def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int) -> Li read_data: List[int] = [] openocd.write_word(SPIFI_CONFIG_ADDR, address) - spifi_intrq_clear(openocd) + # spifi_intrq_clear(openocd) + openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( + SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_CMD, (READ_DATA_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | (SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR << SPIFI_CONFIG_CMD_FRAMEFORM_S) | (SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL << SPIFI_CONFIG_CMD_FIELDFORM_S) | @@ -357,9 +361,7 @@ def spifi_page_program(openocd: OpenOcdTclRpc, ByteAddress: int, data: List[int] raise Exception("Byte count more than 256") print("Writing page %s..." % hex(ByteAddress)) - # spifi_intrq_clear(openocd) - openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( - SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) + spifi_intrq_clear(openocd) openocd.write_word(SPIFI_CONFIG_ADDR, ByteAddress) openocd.write_word(SPIFI_CONFIG_IDATA, 0x00) openocd.write_word(SPIFI_CONFIG_CLIMIT, 0x00000000) @@ -388,13 +390,13 @@ def spifi_erase(openocd, erase_type: EraseType = EraseType.CHIP_ERASE, sectors: spifi_write_enable(openocd) spifi_chip_erase(openocd) spifi_wait_busy(openocd) - spifi_check_erase(openocd, 0, 65536) + spifi_check_erase(openocd, 0, 4096) elif erase_type == EraseType.SECTOR_ERASE: for sector in sectors: spifi_write_enable(openocd) spifi_sector_erase(openocd, sector) spifi_wait_busy(openocd) - spifi_check_erase(openocd, sector, sector + 4096) + spifi_check_erase(openocd, sector, sector + 0x800) def spifi_write(openocd: OpenOcdTclRpc, address: int, data: List[int], data_len: int): diff --git a/mik32_upload.py b/mik32_upload.py index 9fa67d7..19d4e9a 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -67,7 +67,7 @@ mik32v0_sections: List[MemorySection] = [ @dataclass class Segment: offset: int - memory: MemorySection or None + memory: Union[MemorySection, None] data: List[int] @@ -205,7 +205,6 @@ def upload_file( if run_openocd: cmd = shlex.split("%s -s %s -f interface/ftdi/m-link.cfg -f target/mik32.cfg" % ( openocd_path, scripts_path), posix=False) - print(cmd) proc = subprocess.Popen( cmd, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE) From 48811516a4cd062890433958103e515cc9330b6c Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Tue, 30 May 2023 15:48:00 +0300 Subject: [PATCH 9/9] wip --- mik32_spifi.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mik32_spifi.py b/mik32_spifi.py index c452384..e9162e0 100644 --- a/mik32_spifi.py +++ b/mik32_spifi.py @@ -286,7 +286,7 @@ def spifi_wait_busy(openocd: OpenOcdTclRpc): def spifi_chip_erase(openocd: OpenOcdTclRpc): print("Chip erase...") - spifi_intrq_clear(openocd) + # spifi_intrq_clear(openocd) openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_CMD, (SECTOR_ERASE_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | @@ -299,8 +299,6 @@ def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int): print("Erase sector %s..." % hex(address)) openocd.write_word(SPIFI_CONFIG_ADDR, address) # spifi_intrq_clear(openocd) - openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( - SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd.write_word(SPIFI_CONFIG_CMD, (CHIP_ERASE_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | @@ -386,17 +384,20 @@ class EraseType(Enum): def spifi_erase(openocd, erase_type: EraseType = EraseType.CHIP_ERASE, sectors: List[int] = []): + result = 0 if erase_type == EraseType.CHIP_ERASE: spifi_write_enable(openocd) spifi_chip_erase(openocd) spifi_wait_busy(openocd) - spifi_check_erase(openocd, 0, 4096) + result |= spifi_check_erase(openocd, 0, 4096) elif erase_type == EraseType.SECTOR_ERASE: for sector in sectors: spifi_write_enable(openocd) spifi_sector_erase(openocd, sector) spifi_wait_busy(openocd) - spifi_check_erase(openocd, sector, sector + 0x800) + result |= spifi_check_erase(openocd, sector, sector + 0x800) + + return result def spifi_write(openocd: OpenOcdTclRpc, address: int, data: List[int], data_len: int): @@ -521,8 +522,11 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, is_resume=T else: erase_type = EraseType.SECTOR_ERASE - spifi_erase(openocd, erase_type, get_segments_list(list(pages), 4*1024)) - address = 0 + result = spifi_erase(openocd, erase_type, get_segments_list(list(pages), 4*1024)) + + if result == 1: + print("Erase error") + return result spifi_quad_enable(openocd) @@ -539,7 +543,7 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, is_resume=T result = spifi_check_program(openocd, page_offset, 256, page_bytes) if result == 1: - print("Data error") + print("Program error") return result spifi_quad_disable(openocd)