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
from tclrpc import OpenOcdTclRpc
from mik32_upload import Segment, MemorySection
from mik32_upload import Segment, MemorySection, bytes2words
# --------------------------
# 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))
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...")
openocd.write_word(EEPROM_REGS_EEA, 0x00000000)
openocd.write_word(EEPROM_REGS_EEA, offset)
word_num = 0
progress = 0
if print_progress:
print("[", end="", flush=True)
for word in words:
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
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
if print_progress:
print("]")
print("EEPROM check through APB done!")
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...")
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):
raise Exception("Wrong number of words in read_memory output!")
progress = 0
if print_progress:
print("[", end="", flush=True)
for word_num in range(len(words)):
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}")
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
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

View File

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

View File

@ -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]:
pages: Dict[int, List[int]] = {}
for segment in segments:
def segment_to_pages(segment: Segment, page_size: int, pages: Dict[int, List[int]]):
if segment.memory is None:
continue
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
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
@ -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:
# if segment_section.type == MemoryType.EEPROM:
# result = mik32_eeprom.write_words(bytes2words(
# segment.data), openocd, is_resume)
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)
# 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")