mirror of
https://github.com/MikronMIK32/mik32-uploader.git
synced 2026-01-01 21:37:05 +03:00
form pages, write and check eeprom by pages
This commit is contained in:
parent
9ec1de7e0b
commit
ba101bbac1
@ -1,7 +1,7 @@
|
|||||||
from typing import List
|
from typing import Dict, List
|
||||||
import time
|
import time
|
||||||
from tclrpc import OpenOcdTclRpc
|
from tclrpc import OpenOcdTclRpc
|
||||||
from mik32_upload import Segment, MemorySection
|
from mik32_upload import Segment, MemorySection, bytes2words
|
||||||
|
|
||||||
# --------------------------
|
# --------------------------
|
||||||
# PM register offset
|
# PM register offset
|
||||||
@ -152,11 +152,13 @@ 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))
|
openocd.write_word(EEPROM_REGS_EECON, (1 << EEPROM_EX_S) | (1 << EEPROM_BWE_S) | (EEPROM_OP_PR << EEPROM_OP_S))
|
||||||
time.sleep(0.001)
|
time.sleep(0.001)
|
||||||
|
|
||||||
def eeprom_check_data_apb(openocd: OpenOcdTclRpc, words: List[int]) -> int:
|
def eeprom_check_data_apb(openocd: OpenOcdTclRpc, words: List[int], offset: int, print_progress=True) -> int:
|
||||||
|
if print_progress:
|
||||||
print("EEPROM check through APB...")
|
print("EEPROM check through APB...")
|
||||||
openocd.write_word(EEPROM_REGS_EEA, 0x00000000)
|
openocd.write_word(EEPROM_REGS_EEA, offset)
|
||||||
word_num = 0
|
word_num = 0
|
||||||
progress = 0
|
progress = 0
|
||||||
|
if print_progress:
|
||||||
print("[", end="", flush=True)
|
print("[", end="", flush=True)
|
||||||
for word in words:
|
for word in words:
|
||||||
value:int = openocd.read_word(EEPROM_REGS_EEDAT)
|
value:int = openocd.read_word(EEPROM_REGS_EEDAT)
|
||||||
@ -165,19 +167,22 @@ def eeprom_check_data_apb(openocd: OpenOcdTclRpc, words: List[int]) -> int:
|
|||||||
return 1
|
return 1
|
||||||
word_num += 1
|
word_num += 1
|
||||||
curr_progress = int((word_num * 50) / len(words))
|
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)
|
print("#"*(curr_progress - progress), end="", flush=True)
|
||||||
progress = curr_progress
|
progress = curr_progress
|
||||||
|
if print_progress:
|
||||||
print("]")
|
print("]")
|
||||||
print("EEPROM check through APB done!")
|
print("EEPROM check through APB done!")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def eeprom_check_data_ahb_lite(openocd: OpenOcdTclRpc, words: List[int]) -> int:
|
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...")
|
print("EEPROM check through AHB-Lite...")
|
||||||
mem_array = openocd.read_memory(0x01000000, 32, len(words))
|
mem_array = openocd.read_memory(0x01000000 + offset, 32, len(words))
|
||||||
if len(words) != len(mem_array):
|
if len(words) != len(mem_array):
|
||||||
raise Exception("Wrong number of words in read_memory output!")
|
raise Exception("Wrong number of words in read_memory output!")
|
||||||
progress = 0
|
progress = 0
|
||||||
|
if print_progress:
|
||||||
print("[", end="", flush=True)
|
print("[", end="", flush=True)
|
||||||
for word_num in range(len(words)):
|
for word_num in range(len(words)):
|
||||||
if words[word_num] != mem_array[word_num]:
|
if words[word_num] != mem_array[word_num]:
|
||||||
@ -185,15 +190,16 @@ def eeprom_check_data_ahb_lite(openocd: OpenOcdTclRpc, words: List[int]) -> int:
|
|||||||
get {mem_array[word_num]:#0x}")
|
get {mem_array[word_num]:#0x}")
|
||||||
return 1
|
return 1
|
||||||
curr_progress = int((word_num * 50) / len(words))
|
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)
|
print("#"*(curr_progress - progress), end="", flush=True)
|
||||||
progress = curr_progress
|
progress = curr_progress
|
||||||
|
if print_progress:
|
||||||
print("]")
|
print("]")
|
||||||
print("EEPROM check through APB done!")
|
print("EEPROM check through APB done!")
|
||||||
return 0
|
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
|
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)
|
eeprom_write_page(openocd, page_num*page_size*4, page)
|
||||||
print("]")
|
print("]")
|
||||||
if read_through_apb:
|
if read_through_apb:
|
||||||
result = eeprom_check_data_apb(openocd, words)
|
result = eeprom_check_data_apb(openocd, words, 0)
|
||||||
else:
|
else:
|
||||||
result = eeprom_check_data_ahb_lite(openocd, words)
|
result = eeprom_check_data_ahb_lite(openocd, words, 0)
|
||||||
if is_resume:
|
if is_resume:
|
||||||
openocd.resume(0)
|
openocd.resume(0)
|
||||||
|
|
||||||
@ -258,3 +264,36 @@ def write_words(words: List[int], openocd: OpenOcdTclRpc, write_by_word = False,
|
|||||||
print("EEPROM write file done!")
|
print("EEPROM write file done!")
|
||||||
return result
|
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<<EEPROM_N_LD_S | 3<<EEPROM_N_R_1_S | 1<<EEPROM_N_R_2_S)
|
||||||
|
openocd.write_word(EEPROM_REGS_NCYCEP1, 100000)
|
||||||
|
openocd.write_word(EEPROM_REGS_NCYCEP2, 1000)
|
||||||
|
time.sleep(0.1)
|
||||||
|
print("EEPROM writing...")
|
||||||
|
|
||||||
|
for page_offset in list(pages):
|
||||||
|
print("Writing page %s, " % hex(page_offset))
|
||||||
|
page_words = bytes2words(pages[page_offset])
|
||||||
|
eeprom_write_page(openocd, page_offset, page_words)
|
||||||
|
if read_through_apb:
|
||||||
|
result = eeprom_check_data_apb(openocd, page_words, page_offset, False)
|
||||||
|
else:
|
||||||
|
result = eeprom_check_data_ahb_lite(openocd, page_words, page_offset, False)
|
||||||
|
|
||||||
|
if result == 1:
|
||||||
|
print("Page mismatch!")
|
||||||
|
return result
|
||||||
|
|
||||||
|
if is_resume:
|
||||||
|
openocd.resume(0)
|
||||||
|
|
||||||
|
if result == 0:
|
||||||
|
print("EEPROM write file done!")
|
||||||
|
return result
|
||||||
|
|||||||
@ -175,16 +175,3 @@ def parse_hex(file: str) -> Dict:
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
return memory_blocks
|
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
|
|
||||||
|
|||||||
@ -123,19 +123,28 @@ def read_file(filename: str) -> List[Segment]:
|
|||||||
return segments
|
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]]):
|
||||||
pages: Dict[int, List[int]] = {}
|
|
||||||
|
|
||||||
for segment in segments:
|
|
||||||
if segment.memory is None:
|
if segment.memory is None:
|
||||||
continue
|
return
|
||||||
|
|
||||||
internal_offset = segment.offset - segment.memory.offset
|
internal_offset = segment.offset - segment.memory.offset
|
||||||
|
|
||||||
for i, byte in enumerate(segment.data):
|
for i, byte in enumerate(segment.data):
|
||||||
byte_offset = internal_offset + i
|
byte_offset = internal_offset + i
|
||||||
|
page_n = byte_offset // page_size
|
||||||
|
page_offset = page_n * page_size
|
||||||
|
|
||||||
pages[byte_offset % 256]
|
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:
|
||||||
|
segment_to_pages(segment, page_size, pages)
|
||||||
|
|
||||||
return 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" % (
|
raise Exception("ERROR: segment with offset %s and length %s overflows section %s" % (
|
||||||
hex(segment.offset), segment.data.__len__(), segment.memory.type.name))
|
hex(segment.offset), segment.data.__len__(), segment.memory.type.name))
|
||||||
|
|
||||||
print(segments_to_pages(list(filter(
|
proc: subprocess.Popen | None = None
|
||||||
lambda segment: (segment.memory is not None) and (segment.memory.type == MemoryType.EEPROM), segments)), 128))
|
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
|
with OpenOcdTclRpc() as openocd:
|
||||||
# if run_openocd:
|
pages_eeprom = segments_to_pages(list(filter(
|
||||||
# cmd = shlex.split("%s -s %s -f interface/ftdi/m-link.cfg -f target/mcu32.cfg" % (
|
lambda segment: (segment.memory is not None) and (segment.memory.type == MemoryType.EEPROM), segments)), 128)
|
||||||
# DEFAULT_OPENOCD_EXEC_FILE_PATH, DEFAULT_OPENOCD_SCRIPTS_PATH), posix=False)
|
result = mik32_eeprom.write_pages(pages_eeprom, openocd, is_resume)
|
||||||
# proc = subprocess.Popen(
|
|
||||||
# cmd, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE)
|
|
||||||
|
|
||||||
# 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:
|
# elif segment_section.type == MemoryType.SPIFI:
|
||||||
# result = mik32_spifi.spifi_write_file(segment.data, openocd, is_resume)
|
# result = mik32_spifi.spifi_write_file(segment.data, openocd, is_resume)
|
||||||
|
|
||||||
# if run_openocd and proc is not None:
|
if run_openocd and proc is not None:
|
||||||
# proc.kill()
|
proc.kill()
|
||||||
|
|
||||||
return result
|
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():
|
def createParser():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('filepath', nargs='?')
|
parser.add_argument('filepath', nargs='?')
|
||||||
@ -204,6 +223,8 @@ def createParser():
|
|||||||
'--openocd-host', dest='openocd_host', default='127.0.0.1')
|
'--openocd-host', dest='openocd_host', default='127.0.0.1')
|
||||||
parser.add_argument('--openocd-port', dest='openocd_port',
|
parser.add_argument('--openocd-port', dest='openocd_port',
|
||||||
default=OpenOcdTclRpc.DEFAULT_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')
|
# parser.add_argument('-b', '--boot-mode', default='undefined')
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
@ -215,6 +236,6 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
if namespace.filepath:
|
if namespace.filepath:
|
||||||
upload_file(namespace.filepath, namespace.openocd_host,
|
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:
|
else:
|
||||||
print("Nothing to upload")
|
print("Nothing to upload")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user