form pages, write and check eeprom by pages

This commit is contained in:
Sergey Shchelkanov 2023-05-18 13:16:39 +03:00
parent 9ec1de7e0b
commit ba101bbac1
3 changed files with 107 additions and 60 deletions

View File

@ -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,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)) 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:
print("EEPROM check through APB...") if print_progress:
openocd.write_word(EEPROM_REGS_EEA, 0x00000000) print("EEPROM check through APB...")
openocd.write_word(EEPROM_REGS_EEA, offset)
word_num = 0 word_num = 0
progress = 0 progress = 0
print("[", end="", flush=True) if print_progress:
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)
if words[word_num] != value: if words[word_num] != value:
@ -165,35 +167,39 @@ 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
print("]") if print_progress:
print("EEPROM check through APB done!") print("]")
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:
print("EEPROM check through AHB-Lite...") if print_progress:
mem_array = openocd.read_memory(0x01000000, 32, len(words)) print("EEPROM check through AHB-Lite...")
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
print("[", end="", flush=True) if print_progress:
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]:
print(f"Unexpect value at {word_num} word, expect {words[word_num]:#0x}, \ print(f"Unexpect value at {word_num} word, expect {words[word_num]:#0x}, \
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
print("]") if print_progress:
print("EEPROM check through APB done!") print("]")
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

View File

@ -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

View File

@ -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]]):
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]] = {} pages: Dict[int, List[int]] = {}
for segment in segments: for segment in segments:
if segment.memory is None: segment_to_pages(segment, page_size, pages)
continue
internal_offset = segment.offset - segment.memory.offset
for i, byte in enumerate(segment.data):
byte_offset = internal_offset + i
pages[byte_offset % 256]
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( # elif segment_section.type == MemoryType.SPIFI:
# cmd, creationflags=subprocess.CREATE_NEW_CONSOLE | subprocess.SW_HIDE) # result = mik32_spifi.spifi_write_file(segment.data, openocd, is_resume)
# with OpenOcdTclRpc() as openocd: if run_openocd and proc is not None:
# if segment_section.type == MemoryType.EEPROM: proc.kill()
# 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()
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")