mirror of
https://github.com/MikronMIK32/mik32-uploader.git
synced 2026-01-01 13:37:03 +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
|
||||
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<<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()
|
||||
|
||||
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
|
||||
|
||||
|
||||
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")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user