refactor spifi upload

This commit is contained in:
Sergey Shchelkanov 2023-06-22 18:33:55 +03:00
parent f787dd87c0
commit 5e49cc0c1a
2 changed files with 90 additions and 71 deletions

View File

@ -118,7 +118,7 @@ def eeprom_execute_operation(openocd: OpenOcdTclRpc, op: EEPROM_Operation, affec
openocd.write_word(EEPROM_REGS_EECON, (1 << EEPROM_BWE_S) openocd.write_word(EEPROM_REGS_EECON, (1 << EEPROM_BWE_S)
| (affected_pages.value << EEPROM_WRBEH_S)) | (affected_pages.value << EEPROM_WRBEH_S))
openocd.write_word(EEPROM_REGS_EEA, offset) openocd.write_word(EEPROM_REGS_EEA, offset)
if buffer.__len__() > 32: if buffer.__len__() > 32:
return return
for word in buffer: for word in buffer:
@ -130,9 +130,9 @@ def eeprom_execute_operation(openocd: OpenOcdTclRpc, op: EEPROM_Operation, affec
)) ))
def eeprom_configure_cycles(openocd: OpenOcdTclRpc, LD = 1, R_1 = 2, R_2 = 1, CYCEP1 = 66667, CYCEP2 = 500): def eeprom_configure_cycles(openocd: OpenOcdTclRpc, LD=1, R_1=2, R_2=1, CYCEP1=66667, CYCEP2=500):
openocd.write_word(EEPROM_REGS_NCYCRL, LD << EEPROM_N_LD_S | openocd.write_word(EEPROM_REGS_NCYCRL, LD << EEPROM_N_LD_S |
R_1 << EEPROM_N_R_1_S | R_2 << EEPROM_N_R_2_S) R_1 << EEPROM_N_R_1_S | R_2 << EEPROM_N_R_2_S)
openocd.write_word(EEPROM_REGS_NCYCEP1, CYCEP1) openocd.write_word(EEPROM_REGS_NCYCEP1, CYCEP1)
openocd.write_word(EEPROM_REGS_NCYCEP2, CYCEP2) openocd.write_word(EEPROM_REGS_NCYCEP2, CYCEP2)
@ -141,7 +141,8 @@ def eeprom_global_erase(openocd: OpenOcdTclRpc):
print("EEPROM global erase...", flush=True) print("EEPROM global erase...", flush=True)
with OpenOcdTclRpc() as openocd: with OpenOcdTclRpc() as openocd:
# configure cycles duration # configure cycles duration
eeprom_execute_operation(openocd, EEPROM_Operation.ERASE, EEPROM_AffectedPages.GLOBAL, 0x0, [0] * 32) eeprom_execute_operation(
openocd, EEPROM_Operation.ERASE, EEPROM_AffectedPages.GLOBAL, 0x0, [0] * 32)
def eeprom_global_erase_check(openocd: OpenOcdTclRpc): def eeprom_global_erase_check(openocd: OpenOcdTclRpc):
@ -159,12 +160,14 @@ def eeprom_global_erase_check(openocd: OpenOcdTclRpc):
def eeprom_write_word(openocd: OpenOcdTclRpc, address: int, word: int): def eeprom_write_word(openocd: OpenOcdTclRpc, address: int, word: int):
eeprom_execute_operation(openocd, EEPROM_Operation.PROGRAM, EEPROM_AffectedPages.SINGLE, address, [word]) eeprom_execute_operation(
openocd, EEPROM_Operation.PROGRAM, EEPROM_AffectedPages.SINGLE, address, [word])
time.sleep(0.001) time.sleep(0.001)
def eeprom_write_page(openocd: OpenOcdTclRpc, address: int, data: List[int]): def eeprom_write_page(openocd: OpenOcdTclRpc, address: int, data: List[int]):
eeprom_execute_operation(openocd, EEPROM_Operation.PROGRAM, EEPROM_AffectedPages.SINGLE, address, data) eeprom_execute_operation(
openocd, EEPROM_Operation.PROGRAM, EEPROM_AffectedPages.SINGLE, address, data)
time.sleep(0.001) time.sleep(0.001)
@ -301,7 +304,8 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, read_throug
for index, page_offset in enumerate(pages_offsets): for index, page_offset in enumerate(pages_offsets):
page_words = bytes2words(pages[page_offset]) page_words = bytes2words(pages[page_offset])
print(f"Writing page {page_offset:#06x}... {(index*100)//pages_offsets.__len__()}%", flush=True) print(
f"Writing page {page_offset:#06x}... {(index*100)//pages_offsets.__len__()}%", flush=True)
eeprom_write_page(openocd, page_offset, page_words) eeprom_write_page(openocd, page_offset, page_words)
if read_through_apb: if read_through_apb:
result = eeprom_check_data_apb( result = eeprom_check_data_apb(

View File

@ -178,7 +178,7 @@ SREG1_BUSY = 1
READ_SREG_LEN = 1 READ_SREG_LEN = 1
READ_LEN = 256 READ_LEN = 256
TIMEOUT = 100000 TIMEOUT = 1000
CHIP_ERASE_COMMAND = 0xC7 CHIP_ERASE_COMMAND = 0xC7
SECTOR_ERASE_COMMAND = 0x20 SECTOR_ERASE_COMMAND = 0x20
@ -255,27 +255,80 @@ def spifi_wait_intrq_timeout(openocd: OpenOcdTclRpc, error_message: str):
return return
class SPIFI_Frameform(Enum):
RESERVED = 0
OPCODE_NOADDR = 1
OPCODE_1ADDR = 2
OPCODE_2ADDR = 3
OPCODE_3ADDR = 4
OPCODE_4ADDR = 5
NOOPCODE_3ADDR = 6
NOOPCODE_4ADDR = 7
class SPIFI_Fieldform(Enum):
ALL_SERIAL = 0
DATA_PARALLEL = 1
OPCODE_SERIAL = 2
ALL_PARALLEL = 3
class SPIFI_Direction(Enum):
READ = 0
WRITE = 1
def spifi_send_command(
openocd: OpenOcdTclRpc,
cmd: int,
frameform: SPIFI_Frameform,
fieldform: SPIFI_Fieldform,
byte_count=0,
address=0,
idata=0,
cache_limit=0,
idata_length=0,
direction=SPIFI_Direction.READ,
data: List[int] = []
) -> List[int]:
openocd.write_word(SPIFI_CONFIG_ADDR, address)
openocd.write_word(SPIFI_CONFIG_IDATA, idata)
openocd.write_word(SPIFI_CONFIG_CLIMIT, cache_limit)
spifi_intrq_clear(openocd)
openocd.write_word(SPIFI_CONFIG_CMD, (cmd << SPIFI_CONFIG_CMD_OPCODE_S) |
(frameform.value << SPIFI_CONFIG_CMD_FRAMEFORM_S) |
(fieldform.value << SPIFI_CONFIG_CMD_FIELDFORM_S) |
(byte_count << SPIFI_CONFIG_CMD_DATALEN_S) |
(idata_length << SPIFI_CONFIG_CMD_INTLEN_S) |
(direction.value << SPIFI_CONFIG_CMD_DOUT_S))
# spifi_wait_intrq_timeout(openocd, "Timeout executing write enable command")
if direction == SPIFI_Direction.READ:
out_list = []
for i in range(byte_count):
out_list.append(openocd.read_memory(SPIFI_CONFIG_DATA32, 8, 1)[0])
return out_list
if direction == SPIFI_Direction.WRITE:
for i in range(byte_count):
# openocd.write_word(SPIFI_CONFIG_DATA32, data[i+ByteAddress])
openocd.write_memory(SPIFI_CONFIG_DATA32, 8, [data[i]])
return []
def spifi_write_enable(openocd: OpenOcdTclRpc): def spifi_write_enable(openocd: OpenOcdTclRpc):
# spifi_intrq_clear(openocd) spifi_send_command(openocd, WRITE_ENABLE_COMMAND,
openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_Frameform.OPCODE_NOADDR, SPIFI_Fieldform.ALL_SERIAL)
SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M)
openocd.write_word(SPIFI_CONFIG_CMD, (WRITE_ENABLE_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) |
(SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_NOADDR << SPIFI_CONFIG_CMD_FRAMEFORM_S) |
(SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL << SPIFI_CONFIG_CMD_FIELDFORM_S))
spifi_wait_intrq_timeout(openocd, "Timeout executing write enable command")
def spifi_read_sreg(openocd: OpenOcdTclRpc, sreg: SREG_Num) -> int: def spifi_read_sreg(openocd: OpenOcdTclRpc, sreg: SREG_Num) -> int:
read_sreg: int = 0 read_sreg: int = 0
# spifi_intrq_clear(openocd)
openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( return spifi_send_command(
SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) openocd, READ_SREG1_COMMAND | sreg.value, SPIFI_Frameform.OPCODE_NOADDR,
openocd.write_word(SPIFI_CONFIG_CMD, ((READ_SREG1_COMMAND | sreg.value) << SPIFI_CONFIG_CMD_OPCODE_S) | SPIFI_Fieldform.ALL_SERIAL, byte_count=READ_SREG_LEN
(SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_NOADDR << SPIFI_CONFIG_CMD_FRAMEFORM_S) | )[0]
(SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL << SPIFI_CONFIG_CMD_FIELDFORM_S) |
(READ_SREG_LEN << SPIFI_CONFIG_CMD_DATALEN_S))
spifi_wait_intrq_timeout(openocd, "Timeout executing read sreg1 command")
return openocd.read_memory(SPIFI_CONFIG_DATA32, 8, 1)[0]
def spifi_wait_busy(openocd: OpenOcdTclRpc): def spifi_wait_busy(openocd: OpenOcdTclRpc):
@ -287,43 +340,21 @@ def spifi_wait_busy(openocd: OpenOcdTclRpc):
def spifi_chip_erase(openocd: OpenOcdTclRpc): def spifi_chip_erase(openocd: OpenOcdTclRpc):
print("Chip erase...", flush=True) print("Chip erase...", flush=True)
# spifi_intrq_clear(openocd) spifi_send_command(openocd, CHIP_ERASE_COMMAND,
openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_Frameform.OPCODE_NOADDR, SPIFI_Fieldform.ALL_SERIAL)
SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M)
openocd.write_word(SPIFI_CONFIG_CMD, (CHIP_ERASE_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) |
(SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_NOADDR << SPIFI_CONFIG_CMD_FRAMEFORM_S) |
(SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL << SPIFI_CONFIG_CMD_FIELDFORM_S))
spifi_wait_intrq_timeout(openocd, "Timeout executing chip erase command")
def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int): def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int):
print("Erase sector %s..." % hex(address), flush=True) print("Erase sector %s..." % hex(address), flush=True)
openocd.write_word(SPIFI_CONFIG_ADDR, address) spifi_send_command(openocd, SECTOR_ERASE_COMMAND,
SPIFI_Frameform.OPCODE_3ADDR, SPIFI_Fieldform.ALL_SERIAL, address=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_CMD, (SECTOR_ERASE_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))
# spifi_wait_intrq_timeout(openocd, "Timeout executing chip erase command")
spifi_intrq_clear(openocd)
def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_data: List[int]) -> int: def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_data: List[int]) -> int:
read_data: List[int] = [] read_data: List[int] = []
openocd.write_word(SPIFI_CONFIG_ADDR, address)
spifi_intrq_clear(openocd) read_data = spifi_send_command(openocd, READ_DATA_COMMAND, SPIFI_Frameform.OPCODE_3ADDR,
openocd.write_word(SPIFI_CONFIG_CMD, (READ_DATA_COMMAND << SPIFI_CONFIG_CMD_OPCODE_S) | SPIFI_Fieldform.ALL_SERIAL, byte_count=byte_count, address=address)
(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)
# print(f"DATA[{i+address}] = {read_data[i]:#0x}")
for i in range(byte_count): for i in range(byte_count):
if read_data[i] != bin_data[i]: if read_data[i] != bin_data[i]:
@ -339,25 +370,9 @@ def spifi_page_program(openocd: OpenOcdTclRpc, ByteAddress: int, data: List[int]
if byte_count > 256: if byte_count > 256:
raise Exception("Byte count more than 256") raise Exception("Byte count more than 256")
# spifi_intrq_clear(openocd) spifi_send_command(openocd, PAGE_PROGRAM_COMMAND, SPIFI_Frameform.OPCODE_3ADDR,
openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word( SPIFI_Fieldform.ALL_SERIAL, byte_count=byte_count, address=ByteAddress,
SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M) idata=0, cache_limit=0, direction=SPIFI_Direction.WRITE, data=data)
openocd.write_word(SPIFI_CONFIG_ADDR, ByteAddress)
openocd.write_word(SPIFI_CONFIG_IDATA, 0x00)
openocd.write_word(SPIFI_CONFIG_CLIMIT, 0x00000000)
openocd.write_word(SPIFI_CONFIG_CMD, (PAGE_PROGRAM_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) |
(0 << SPIFI_CONFIG_CMD_INTLEN_S) |
(1 << SPIFI_CONFIG_CMD_DOUT_S) |
(0 << SPIFI_CONFIG_CMD_POLL_S) |
(byte_count << SPIFI_CONFIG_CMD_DATALEN_S))
for i in range(byte_count):
# openocd.write_word(SPIFI_CONFIG_DATA32, data[i+ByteAddress])
openocd.write_memory(SPIFI_CONFIG_DATA32, 8, [data[i]])
# spifi_intrq_clear(openocd)
openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word(
SPIFI_CONFIG_STAT) | SPIFI_CONFIG_STAT_INTRQ_M)
class EraseType(Enum): class EraseType(Enum):