mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
1201 lines
42 KiB
Python
Executable File
1201 lines
42 KiB
Python
Executable File
#!/usr/bin/python3
|
|
"""
|
|
ISP Core commands implementation
|
|
|
|
In System Programming (ISP) protocol implementation
|
|
|
|
|
|
__author__ onyettr
|
|
"""
|
|
# pylint: disable=unused-argument, invalid-name
|
|
import os
|
|
import signal
|
|
import time
|
|
import sys
|
|
import struct
|
|
from isp_protocol import *
|
|
from isp_print import isp_print_color, isp_print_response, isp_print_message
|
|
from serom_errors import *
|
|
from toc_decode import display_toc_info, toc_decode_toc_info
|
|
from toc_decode import TOC_IMAGE_CPU_A32_0, TOC_IMAGE_CPU_A32_1
|
|
from toc_decode import TOC_IMAGE_CPU_M55_HP, TOC_IMAGE_CPU_M55_HE, TOC_IMAGE_CPU_MODEM
|
|
from toc_decode import TOC_IMAGE_CPU_GNSS, TOC_IMAGE_CPU_DSP
|
|
from version_decode import version_decode
|
|
from cpu_decode import display_cpu_info
|
|
from power_decode import display_power_info
|
|
from clock_decode import display_clock_info
|
|
from otp import display_otp_info
|
|
#from serom_trace import *
|
|
|
|
#from seram_trace import trace_buffer_decode
|
|
from trace_decode import trace_buffer_decode
|
|
|
|
# ISP Command set
|
|
# Command : Value
|
|
isp_command_lookup = {
|
|
ISP_COMMAND_START_ISP : "COMMAND_START_ISP ",
|
|
ISP_COMMAND_STOP_ISP : "COMMAND_STOP_ISP ",
|
|
ISP_COMMAND_ABORT : "COMMAND_ABORT ",
|
|
ISP_COMMAND_DOWNLOAD_DATA : "COMMAND_DOWNLOAD_DATA ",
|
|
ISP_COMMAND_DOWNLOAD_DONE : "COMMAND_DOWNLOAD_DONE ",
|
|
ISP_COMMAND_BURN_MRAM : "COMMAND_BURN_MRAM ",
|
|
ISP_COMMAND_RESET_DEVICE : "COMMAND_RESET_DEVICE ",
|
|
ISP_COMMAND_PRINT_DATA : "COMMAND_PRINT_DATA ",
|
|
ISP_COMMAND_MRAM_WRITE : "COMMAND_MRAM_WRITE ",
|
|
ISP_COMMAND_SECURE_DEBUG : "COMMAND_SECURE_DEBUG ",
|
|
ISP_COMMAND_ENQUIRY : "COMMAND_ENQUIRY ",
|
|
ISP_COMMAND_GET_BAUD_RATE : "COMMAND_GET_BAUD_RATE ",
|
|
ISP_COMMAND_SET_BAUD_RATE : "COMMAND_SET_BAUD_RATE ",
|
|
ISP_COMMAND_VERIFY_IMAGE : "COMMAND_VERIFY_IMAGE ",
|
|
ISP_COMMAND_GET_TOC_INFO : "COMMAND_GET_TOC_INFO ",
|
|
ISP_COMMAND_OTP_WRITE : "COMMAND_OTP_WRITE ",
|
|
ISP_COMMAND_OTP_READ : "COMMAND_OTP_READ ",
|
|
ISP_COMMAND_GET : "COMMAND_GET ",
|
|
ISP_COMMAND_ERASE_MRAM : "COMMAND_ERASE_MRAM ",
|
|
ISP_COMMAND_SET_MAINTENANCE_FLAG: "COMMAND_SET_MAINTENANCE_FLAG",
|
|
ISP_COMMAND_MRAM_READ : "COMMAND_MRAM_READ ",
|
|
ISP_COMMAND_SET : "COMMAND_SET ",
|
|
ISP_COMMAND_DMPU : "COMMAND_DMPU ",
|
|
ISP_COMMAND_SRAM_WRITE : "COMMAND SRAM WRITE ",
|
|
ISP_COMMAND_VERIFY_AND_EXECUTE : "ISP_COMMAND_VERIFY_AND_EXECUTE",
|
|
ISP_COMMAND_DATA_RESPONSE : "COMMAND_DATA_RESPONSE ",
|
|
ISP_COMMAND_ACK : "COMMAND_ACK ",
|
|
ISP_COMMAND_NAK : "COMMAND_NAK "
|
|
}
|
|
|
|
# ISP Sub commands
|
|
isp_subcommand_lookup = {
|
|
ISP_GET_TOC_INFO : "GET_TOC_INFO ",
|
|
ISP_GET_REVISION : "GET_REVISION ",
|
|
ISP_GET_BAUDRATE : "GET_BAUDRATE ",
|
|
ISP_GET_BANNER : "GET_BANNER ",
|
|
ISP_GET_MRAM_CONTENTS : "GET_MRAM_CONTENTS ",
|
|
ISP_GET_CPU_STATUS : "GET_CPU_STATUS ",
|
|
ISP_GET_SERAM_METRICS : "GET_SERAM_METRICS ",
|
|
ISP_GET_LOG_BUFFER_INFO : "GET_LOG_BUFFER_INFO ",
|
|
ISP_GET_LOG_DATA : "GET_LOG_DATA ",
|
|
ISP_GET_SERAM_UPDT_ADDR : "GET_STREAM_UPDT_ADDR ",
|
|
ISP_GET_TRACE_BUFFER : "GET_TRACE_BUFFER ",
|
|
ISP_GET_SERAM_TRACE_BUFFER : "GET_SERAM_TRACE_BUFFER",
|
|
ISP_GET_SECURE_DEBUG_TOKENS : "GET_SECURE_DEBUG_TOKENS",
|
|
ISP_GET_POWER_INFO : "GET_POWER_INFO ",
|
|
ISP_GET_PEEK_ADDRESS : "GET ADDRESS ",
|
|
ISP_GET_CLOCK_INFO : "GET CLOCK_INFO ",
|
|
ISP_GET_ECC_KEY : "GET ECC_KEY ",
|
|
ISP_GET_FIREWALL_CONFIG : "GET FIREWALL_CONFIG ",
|
|
ISP_SET_PRINTING_ENABLE : "SET PRINTING ENABLE ",
|
|
ISP_SET_PRINTING_DISABLE : "SET PRINTING DISABLE ",
|
|
ISP_SET_LOGGING_ENABLE : "SET LOGGING ENABLE ",
|
|
ISP_SET_LOGGING_DISABLE : "SET LOGGING DISABLE ",
|
|
ISP_SET_POKE_ADDRESS : "SET ADDRESS "
|
|
}
|
|
|
|
error_lookup = {
|
|
ISP_SUCCESS : "ISP_SUCCESS ",
|
|
ISP_ERROR : "ISP_ERROR ",
|
|
ISP_READ_TIMEOUT : "ISP_READ_TIMEOUT ",
|
|
ISP_WRITE_TIMEOUT : "ISP_WRITE_TIMEOUT ",
|
|
ISP_UNKNOWN_COMMAND : "ISP_UNKNOWN_COMMAND ",
|
|
ISP_COMMAND_STOP : "ISP_COMMAND_STOP ",
|
|
ISP_CHECKSUM_ERROR : "ISP_CHECKSUM_ERROR ",
|
|
ISP_NOT_SUPPORTED : "ISP_NOT_SUPPORTED ",
|
|
ISP_BAD_PACKET_SIZE : "ISP_BAD_PACKET_SIZE ",
|
|
ISP_BAD_DESTINATION_ADDR : "ISP_BAD_DEST_ADDRESS ",
|
|
ISP_UNEXPECTED_COMMAND : "ISP_UNEXPECTED_COMMAND",
|
|
ISP_HOST_AUTH_FAILED : "ISP_HOST_AUTH_FAILED ",
|
|
ISP_NOT_ALLOWED : "ISP_NOT_ALLOWED ",
|
|
ISP_BAD_AUTH_TOKEN : "ISP_BAD_AUTH_TOKEN ",
|
|
ISP_IMAGE_AUTHENTICATION_FAILED : "ISP_IMAGE_AUTHENTICATION_FAILED",
|
|
ISP_IMAGE_VERIFICATION_FAILED : "ISP_IMAGE_VERIFICATION_FAILED",
|
|
ISP_SECURE_DEBUG_FAILED : "ISP_SECURE_DEBUG_FAILED",
|
|
ISP_MRAM_WRITE_FAILED : "ISP_MRAM_WRITE_FAILED ",
|
|
ISP_UNKNOWN_GET_OBJECT : "ISP_UNKNOWN_GET_OBJECT",
|
|
ISP_ERROR_ILLEGAL_ADDRESS : "ISP_ERROR_ILLEGAL_ADDRESS",
|
|
ISP_ERROR_MISALIGNED : "ISP_ERROR_MISALIGNED",
|
|
ISP_UNKNOWN_MRAM_ERROR : "ISP_UNKNOWN_MRAM_ERROR",
|
|
ISP_MRAM_LENGTH_TOO_LARGE : "ISP_MRAM_LENGTH_TOO_LARGE",
|
|
ISP_UNKNOWN_SET_OBJECT : "ISP_UNKNOWN_SET_OBJECT",
|
|
ISP_CODE_VERIFY_FAILURE : "ISP_CODE_VERIFY_FAILURE",
|
|
ISP_INVALID_CODE_SIZE : "ISP_INVALID_CODE_SIZE",
|
|
ISP_MFG_DATA_MISCOMPARE : "ISP_MFG_DATA_MISCOMPARE",
|
|
ISP_SERAM_JUMP_FAILED : "ISP_SERAM_JUMP_FAILED"
|
|
}
|
|
|
|
cpu_name_lut = {
|
|
TOC_IMAGE_CPU_A32_0 : "A32_0 ",
|
|
TOC_IMAGE_CPU_A32_1 : "A32_1 ",
|
|
TOC_IMAGE_CPU_M55_HP : "M55-HP",
|
|
TOC_IMAGE_CPU_M55_HE : "M55-HE",
|
|
TOC_IMAGE_CPU_MODEM : "Modem ",
|
|
TOC_IMAGE_CPU_GNSS : "GNSS ",
|
|
TOC_IMAGE_CPU_DSP : "DSP "
|
|
}
|
|
|
|
serom_error_lookup = {
|
|
SEROM_STATUS_SUCCESS : "SEROM_STATUS_SUCCESS",
|
|
SEROM_BSV_INIT_FAIL : "SEROM_BSV_INIT_FAIL",
|
|
SEROM_BSV_LCS_GET_AND_INIT_FAIL : "SEROM_BSV_LCS_GET_AND_INIT_FAIL",
|
|
SEROM_BSV_LCS_GET_FAIL : "SEROM_BSV_LCS_GET_FAIL",
|
|
SEROM_BSV_SEC_MODE_SET_FAIL : "SEROM_BSV_SEC_MODE_SET_FAIL",
|
|
SEROM_BSV_PRIV_MODE_SET_FAIL : "SEROM_BSV_PRIV_MODE_SET_FAIL",
|
|
SEROM_BSV_CORE_CLK_GATING_ENABLE_FAIL : "SEROM_BSV_CORE_CLK_GATING_ENABLE_FAIL",
|
|
SEROM_MRAM_INITIALIZATION_FAILURE : "SEROM_MRAM_INITIALIZATION_FAILURE",
|
|
SEROM_MRAM_INITIALIZATION_TIMEOUT : "SEROM_MRAM_INITIALIZATION_TIMEOUT",
|
|
SEROM_MRAM_WRITE_FAILURE : "SEROM_MRAM_WRITE_FAILURE",
|
|
SEROM_ATOC_EXT_HDR_OFFSET_ZERO : "SEROM_ATOC_EXT_HDR_OFFSET_ZERO",
|
|
SEROM_ATOC_EXT_HDR_OFFSET_TOO_LARGE : "SEROM_ATOC_EXT_HDR_OFFSET_TOO_LARGE",
|
|
SEROM_ATOC_OBJECT_OFFSET_ZERO : "SEROM_ATOC_OBJECT_OFFSET_ZERO",
|
|
SEROM_ATOC_OBJECT_OFFSET_MISALIGNED : "SEROM_ATOC_OBJECT_OFFSET_MISALIGNED",
|
|
SEROM_ATOC_OBJECT_OFFSET_TOO_LARGE : "SEROM_ATOC_OBJECT_OFFSET_TOO_LARGE",
|
|
SEROM_ATOC_OBJECT_OFFSET_TOO_SMALL : "SEROM_ATOC_OBJECT_OFFSET_TOO_SMALL",
|
|
SEROM_ATOC_EXT_HDR_OFFSET_MISALIGNED : "SEROM_ATOC_EXT_HDR_OFFSET_MISALIGNED",
|
|
SEROM_ATOC_HEADER_OFFSET_INVALID : "SEROM_ATOC_HEADER_OFFSET_INVALID",
|
|
SEROM_ATOC_HEADER_CRC32_ERROR : "SEROM_ATOC_HEADER_CRC32_ERROR",
|
|
SEROM_ATOC_HEADER_STRING_INVALID : "SEROM_ATOC_HEADER_STRING_INVALID",
|
|
SEROM_ATOC_NUM_TOC_ENTRIES_INVALID : "SEROM_ATOC_NUM_TOC_ENTRIES_INVALID",
|
|
SEROM_CONTENT_CERTIFICATE_NULL : "SEROM_CONTENT_CERTIFICATE_NULL",
|
|
SEROM_CERTIFICATE_NULL : "SEROM_CERTIFICATE_NULL",
|
|
SEROM_CERTIFICATE_CHAIN_INVALID : "SEROM_CERTIFICATE_CHAIN_INVALID",
|
|
SEROM_INVALID_OEM_ROT : "SEROM_INVALID_OEM_ROT",
|
|
SEROM_CERTIFICATE_ERROR_BASE : "SEROM_CERTIFICATE_ERROR_BASE",
|
|
SEROM_CERTIFICATE_1_ERROR : "SEROM_CERTIFICATE_1_ERROR",
|
|
SEROM_CERTIFICATE_2_ERROR : "SEROM_CERTIFICATE_2_ERROR",
|
|
SEROM_CERTIFICATE_3_ERROR : "SEROM_CERTIFICATE_3_ERROR",
|
|
SEROM_BOOT_CODE_LOAD_ADDR_INVALID : "SEROM_BOOT_CODE_LOAD_ADDR_INVALID",
|
|
SEROM_BOOT_VERIFY_IN_MEMORY_CASE_INVALID : "SEROM_BOOT_VERIFY_IN_MEMORY_CASE_INVALID",
|
|
SEROM_BOOT_ZERO_IMAGE_LENGTH_INVALID : "SEROM_BOOT_ZERO_IMAGE_LENGTH_INVALID",
|
|
SEROM_BOOT_ENCRYPTED_IMAGE_INVALID : "SEROM_BOOT_ENCRYPTED_IMAGE_INVALID",
|
|
SEROM_BOOT_VERIFY_IN_FLASH_CASE_INVALID : "SEROM_BOOT_VERIFY_IN_FLASH_CASE_INVALID",
|
|
SEROM_BOOT_IMAGE_LENGTH_TOO_LARGE : "SEROM_BOOT_IMAGE_LENGTH_TOO_LARGE",
|
|
SEROM_BOOT_RAW_IMAGE_LOADING_NOT_ALLOWED : "SEROM_BOOT_RAW_IMAGE_LOADING_NOT_ALLOWED",
|
|
SEROM_BOOT_SERAM_JUMP_RETURN_ERROR : "SEROM_BOOT_SERAM_JUMP_RETURN_ERROR",
|
|
SEROM_BOOT_FAILED : "SEROM_BOOT_FAILED",
|
|
SEROM_BOOT_JUMP_ADDRESS_NOT_VALID : "SEROM_BOOT_JUMP_ADDRESS_NOT_VALID",
|
|
SEROM_BOTH_BANKS_INVALID : "SEROM_BOTH_BANKS_INVALID",
|
|
SEROM_ATOC_EXT_HDR_OFFSET_TOO_SMALL : "SEROM_ATOC_EXT_HDR_OFFSET_TOO_SMALL",
|
|
SEROM_BOOT_END_OF_MAIN_ERROR : "SEROM_BOOT_END_OF_MAIN_ERROR",
|
|
SEROM_INVALID_NULL_PTR : "SEROM_INVALID_NULL_PTR",
|
|
SEROM_INVALID_TOC_OFFSET : "SEROM_INVALID_TOC_OFFSET",
|
|
}
|
|
|
|
def convert_from_ms(milliseconds):
|
|
"""
|
|
from the web
|
|
"""
|
|
seconds, milliseconds = divmod(milliseconds,1000)
|
|
minutes, seconds = divmod(seconds,60)
|
|
hours, minutes = divmod(minutes, 60)
|
|
days, hours = divmod(hours, 24)
|
|
|
|
# days = 0
|
|
# seconds = (milliseconds/1000)%60
|
|
# seconds = int(seconds)
|
|
# minutes = (milliseconds/(1000*60))%60
|
|
# minutes = int(minutes)
|
|
# hours = (milliseconds/(1000*60*60))%24
|
|
# hours = int(hours)
|
|
return days, hours, minutes, seconds
|
|
|
|
class CtrlCHandler():
|
|
"""
|
|
CtrlCHandler - handler for Ctrl-C key press
|
|
"""
|
|
def __init__(self):
|
|
"""
|
|
ctor
|
|
"""
|
|
self.running = False
|
|
signal.signal(signal.SIGINT, self.Handler)
|
|
|
|
def Handler(self, signal_number, frame):
|
|
"""
|
|
Handle the interupt signal
|
|
"""
|
|
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
|
self.running = True
|
|
|
|
def Handler_reset(self):
|
|
"""
|
|
start over
|
|
"""
|
|
self.running = False
|
|
|
|
def Handler_exit(self):
|
|
"""
|
|
return handler state
|
|
"""
|
|
return self.running
|
|
|
|
def int_to_bytes(number):
|
|
"""
|
|
int_to_bytes
|
|
- integer number gets turned into bytes
|
|
"""
|
|
_hrepr = hex(number).replace('0x', '')
|
|
return number.to_bytes(4,byteorder='little')
|
|
|
|
def isp_decode_packet(isp, prompt_str, packet):
|
|
"""
|
|
DecodePacket
|
|
|
|
prints details of header and packet
|
|
"""
|
|
|
|
command = ISP_UNKNOWN_COMMAND
|
|
|
|
if isp.getVerbose() is True:
|
|
print("%s" %prompt_str, end='')
|
|
print(" length= %3d" %len(packet), end='')
|
|
|
|
# Decode further
|
|
if len(packet) > ISP_PACKET_HEADER_LENGTH:
|
|
lastbyte = len(packet)
|
|
command = packet[ISP_PACKET_COMMAND_FIELD]
|
|
# Uncomment for more details
|
|
# hexized = [hex(x) for x in packet]
|
|
# print(hexized)
|
|
|
|
cmdstr = isp_command_lookup.get(command)
|
|
if not cmdstr:
|
|
cmdstr = ">> COMMAND_UNKNOWN << "
|
|
command = ISP_UNKNOWN_COMMAND
|
|
if isp.getVerbose() is True:
|
|
print(" cmd = %3x" %command, end='')
|
|
print(" command=", cmdstr, end='')
|
|
if (command == ISP_COMMAND_GET or command == ISP_COMMAND_SET):
|
|
sub_command = int.from_bytes(packet[2:6], "little")
|
|
sub_command_str = isp_subcommand_lookup.get(sub_command)
|
|
if not sub_command_str:
|
|
sub_command_str = ">> SUB COMMAND UNKNOWN <<"
|
|
print(" sub command= %4x %s"
|
|
%(sub_command, sub_command_str),end='')
|
|
if sub_command == ISP_GET_PEEK_ADDRESS:
|
|
address = int.from_bytes(packet[6:10], "little")
|
|
print("address= 0x%8x" %(address))
|
|
if sub_command == ISP_SET_POKE_ADDRESS:
|
|
address = int.from_bytes(packet[6:10], "little")
|
|
data = int.from_bytes(packet[10:14], "little")
|
|
print("address= 0x%x, data= 0x%x" %(address,data))
|
|
print(" chksum =", hex(packet[lastbyte-1]),end='')
|
|
|
|
# if command != ISP_COMMAND_DOWNLOAD_DATA:
|
|
# print(" packet=", packet,end='')
|
|
|
|
if command == ISP_COMMAND_NAK: # NACK, check error code#
|
|
# Uncomment for more details
|
|
# hexized = [hex(x) for x in packet]
|
|
# print(hexized)
|
|
errstr = error_lookup.get(packet[ISP_PACKET_DATA_FIELD])
|
|
if not errstr:
|
|
errstr = ">> ERROR UNKNOWN <<"
|
|
if isp.getVerbose() is False:
|
|
print("%s" %prompt_str, end='')
|
|
print(" length= %3d" %len(packet), end='')
|
|
print(" command=", cmdstr, end='')
|
|
print(" chksum=", hex(packet[lastbyte-1]),end='')
|
|
print(" error=", errstr)
|
|
else:
|
|
print(" error=", errstr, end='')
|
|
if command == ISP_COMMAND_DATA_RESPONSE:
|
|
payload = packet[ISP_PACKET_DATA_FIELD:len(packet)-1]
|
|
if isp.getVerbose() is True:
|
|
if packet[ISP_TOC_COMMAND_FIELD] == ISP_TOC_INFO_START_MARKER:
|
|
print(" ISP_TOC_INFO_START_MARKER ", end='')
|
|
if packet[ISP_TOC_COMMAND_FIELD] == ISP_TOC_INFO_END_MARKER:
|
|
print(" ISP_TOC_INFO_STOP_MARKER ", end='')
|
|
if packet[ISP_TOC_COMMAND_FIELD] == ISP_DATA_START_MARKER:
|
|
print(" ISP_DATA_START_MARKER ", end='')
|
|
if packet[ISP_TOC_COMMAND_FIELD] == ISP_DATA_END_MARKER:
|
|
print(" ISP_DATA_END_MARKER ", end='')
|
|
|
|
# for each_word in range(0,160,4):
|
|
# trace_value = payload[each_word:each_word+4]
|
|
# value = int.from_bytes(trace_value,byteorder='little')
|
|
# print("{:4d} 0x{:08x} ".format(each_word,value))
|
|
|
|
hexed = [hex(x) for x in payload]
|
|
print(" response payload=", hexed, end='')
|
|
print(hexed)
|
|
|
|
if isp.getVerbose() is True:
|
|
print(" ")
|
|
sys.stdout.flush()
|
|
|
|
return command
|
|
|
|
def isp_readmessage(isp):
|
|
"""
|
|
read a message from the serial port
|
|
|
|
Length; Command; [<payload>]; Checksum
|
|
"""
|
|
packet_contents = []
|
|
|
|
packet_header = isp.readSerial(ISP_PACKET_HEADER_LENGTH)
|
|
|
|
if len(packet_header) == 0:
|
|
return []
|
|
|
|
if len(packet_header) != ISP_PACKET_HEADER_LENGTH:
|
|
return []
|
|
|
|
packet_length = packet_header[ISP_PACKET_LENGTH_FIELD]
|
|
packet_command= packet_header[ISP_PACKET_COMMAND_FIELD]
|
|
|
|
if packet_command == ISP_COMMAND_DATA_RESPONSE:
|
|
packet_contents = list(bytearray(isp.readSerial(packet_length - 3)))
|
|
if packet_contents == []:
|
|
return []
|
|
|
|
if packet_command == ISP_COMMAND_PRINT_DATA:
|
|
packet_contents = list(bytearray(isp.readSerial(packet_length - 3)))
|
|
if packet_contents == []:
|
|
return []
|
|
|
|
if packet_command == ISP_COMMAND_NAK: # NACK packet or
|
|
packet_contents = list(bytearray(isp.readSerial(1))) # Error code
|
|
|
|
# read the checksum
|
|
packet_checksum = list(bytearray(isp.readSerial(1)))
|
|
if packet_checksum == []:
|
|
return []
|
|
|
|
if packet_command == ISP_COMMAND_NAK or packet_command != ISP_COMMAND_ACK:
|
|
packet = packet_header + packet_contents + packet_checksum
|
|
else:
|
|
packet = packet_header + packet_checksum
|
|
|
|
# print("message = ", packet)
|
|
|
|
return packet
|
|
|
|
def isp_wait(isp):
|
|
"""
|
|
wait for trigger to proceed
|
|
"""
|
|
_event = isp.eventFlag.wait(1) # Wait for operation to complete
|
|
isp.eventFlag.clear()
|
|
|
|
def isp_signal(isp):
|
|
"""
|
|
tigeger signal to wait
|
|
"""
|
|
isp.eventFlag.set() # tell TX we are done
|
|
|
|
|
|
def isp_build_packet(isp, isp_command, isp_sub_commands = None, delay=0):
|
|
"""
|
|
build the packet and send, receive and decode response
|
|
"""
|
|
if isp_sub_commands is None:
|
|
isp_sub_commands = []
|
|
|
|
cmd_packet = [0x00, isp_command]
|
|
|
|
for sub in isp_sub_commands:
|
|
if sub == 'padding':
|
|
cmd_packet.append(0x55)
|
|
continue
|
|
|
|
if isinstance( sub, int ):
|
|
cmd_packet = cmd_packet + list(int_to_bytes(sub))
|
|
else:
|
|
cmd_packet = cmd_packet + list(sub)
|
|
|
|
cmd_packet[0] = len(cmd_packet) + 1
|
|
cmd_packet = isp.checkSum(cmd_packet) # add the checksum packet
|
|
|
|
isp.writeSerial(bytearray(cmd_packet))
|
|
isp_decode_packet(isp,"TX--> ", cmd_packet)
|
|
if delay>0:
|
|
time.sleep(delay)
|
|
message = isp_readmessage(isp)
|
|
command = isp_decode_packet(isp,"RX<-- ", message)
|
|
|
|
while command == ISP_COMMAND_PRINT_DATA:
|
|
isp_print_message('blue', message)
|
|
|
|
message = isp_readmessage(isp)
|
|
command = isp_decode_packet(isp,"RX<-- ", message)
|
|
|
|
return message
|
|
|
|
def isp_test_target(baud_rate, isp):
|
|
"""
|
|
isp_test_target
|
|
|
|
This command is similar to isp_start() but it does NOT exit
|
|
when the target did not respond...Int rather resturns:
|
|
1 - when target responded
|
|
-1 - when target did not respond
|
|
"""
|
|
cmd_packet = [0x03, ISP_COMMAND_START_ISP] # start isp
|
|
cmd_packet = isp.checkSum(cmd_packet) # add the checksum packet
|
|
|
|
isp.writeSerial(bytearray(cmd_packet))
|
|
isp_decode_packet(isp,"TX--> ", cmd_packet)
|
|
|
|
# ISP START always succeeds, so there is no need to read the Ack like for the other commands.
|
|
# Two things to look for are -
|
|
# 1. ISP_COMMAND_ACK byte - to verify that the target responded
|
|
# 2. Any leftover data, e.g., Flicker animations - it needs to be read/flushed
|
|
got_ack = False
|
|
while True:
|
|
data = isp.readSerial(1)
|
|
if len(data) == 0:
|
|
break
|
|
if data[0] == ISP_COMMAND_ACK:
|
|
got_ack = True
|
|
if not got_ack:
|
|
sys.stdout.flush()
|
|
return -1
|
|
|
|
if isp.getVerbose() is True:
|
|
print("RX<-- command= COMMAND_ACK")
|
|
|
|
if got_ack == True:
|
|
return 1
|
|
|
|
def isp_start(isp):
|
|
"""
|
|
isp_start
|
|
|
|
ISP_COMMAND_START puts the SERAM isp_handler into an ISP mode. Flicker
|
|
will be disabled, however there maybe some residual characters which
|
|
get consumed.
|
|
"""
|
|
cmd_packet = [0x03, ISP_COMMAND_START_ISP] # start isp
|
|
cmd_packet = isp.checkSum(cmd_packet) # add the checksum packet
|
|
|
|
isp.writeSerial(bytearray(cmd_packet))
|
|
isp_decode_packet(isp,"TX--> ", cmd_packet)
|
|
|
|
# ISP START always succeeds, so there is no need to read the Ack like for the other commands.
|
|
# Two things to look for are -
|
|
# 1. ISP_COMMAND_ACK byte - to verify that the target responded
|
|
# 2. Any leftover data, e.g., Flicker animations - it needs to be read/flushed
|
|
got_ack = False
|
|
while True:
|
|
data = isp.readSerial(1)
|
|
if len(data) == 0:
|
|
break
|
|
if data[0] == ISP_COMMAND_ACK:
|
|
got_ack = True
|
|
if not got_ack:
|
|
print("[ERROR] Target did not respond")
|
|
sys.stdout.flush()
|
|
# isp_start is called before any dynamic baud rate change, so it is ok to sys.exit()
|
|
isp.closeSerial()
|
|
sys.exit(-1)
|
|
|
|
if isp.getVerbose() is True:
|
|
print("RX<-- command= COMMAND_ACK")
|
|
|
|
def isp_stop(isp):
|
|
"""
|
|
isp_Stop
|
|
- Send Command to Stop the isp handler on the target
|
|
"""
|
|
isp_build_packet(isp, ISP_COMMAND_STOP_ISP)
|
|
|
|
def getFilesize(fileHandle):
|
|
"""
|
|
getFileSize
|
|
- given a file handle return the size in bytes
|
|
"""
|
|
fileHandle.seek(0,os.SEEK_END)
|
|
sizeinbytes = fileHandle.tell()
|
|
|
|
return sizeinbytes
|
|
|
|
def isp_reset(isp):
|
|
"""
|
|
isp_reset
|
|
"""
|
|
isp_build_packet(isp, ISP_COMMAND_RESET_DEVICE)
|
|
|
|
def isp_secure_debug(isp, auth_token, data):
|
|
"""
|
|
isp_secure_debug
|
|
"""
|
|
subCmd = []
|
|
if auth_token != 0x0:
|
|
subCmd.append(auth_token)
|
|
|
|
if len(data) != 0:
|
|
subCmd.append(data)
|
|
|
|
#print("*** sub command: ", subCmd)
|
|
isp_build_packet(isp, ISP_COMMAND_SECURE_DEBUG, subCmd)
|
|
|
|
def isp_download_start(isp, address, size, auth_token):
|
|
"""
|
|
isp_download_start
|
|
"""
|
|
subCmd = [address,size]
|
|
if auth_token != 0x0:
|
|
subCmd.append(auth_token)
|
|
isp_build_packet(isp, ISP_COMMAND_DOWNLOAD_START, subCmd)
|
|
|
|
def isp_download_data(isp, data):
|
|
"""
|
|
isp_download_data
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_DOWNLOAD_DATA,
|
|
['padding', 'padding', bytearray(data)])
|
|
if len(message) == 0:
|
|
print("[ERROR] No response")
|
|
return False
|
|
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
print("[ERROR] Command NAK")
|
|
return False
|
|
|
|
return True
|
|
|
|
def isp_download_done(isp, delay = 0):
|
|
"""
|
|
isp_download_done
|
|
Does not wait for reader task
|
|
"""
|
|
isp_build_packet(isp, ISP_COMMAND_DOWNLOAD_DONE, None, delay)
|
|
|
|
def isp_burn_mram(isp, address, file_size, auth_token):
|
|
"""
|
|
isp_burn_mram
|
|
"""
|
|
subCmd = [address,file_size]
|
|
if auth_token != 0x0:
|
|
subCmd.append(auth_token)
|
|
message = isp_build_packet(isp, ISP_COMMAND_BURN_MRAM, subCmd)
|
|
|
|
# same error handling as in isp_download_data
|
|
if len(message) == 0:
|
|
print("[ERROR] No response")
|
|
return False
|
|
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
print("[ERROR] Command NAK")
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
def isp_enquiry(isp):
|
|
"""
|
|
isp_enquiry
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_ENQUIRY)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
|
|
cmd = message[ISP_PACKET_COMMAND_FIELD]
|
|
if cmd == ISP_COMMAND_DATA_RESPONSE:
|
|
#isp_print_response("blue",message)
|
|
Maintenance_string = ""
|
|
error_string = ""
|
|
length = message[ISP_PACKET_LENGTH_FIELD]
|
|
state = message[ISP_PACKET_DATA_FIELD]
|
|
|
|
ErrorCode = (message[3:7]) # bytes 3 through 6 (limit 7)
|
|
ExtendedErrorCode = [0,0,0,0]
|
|
ExtendedErrorCode = (message[7:11]) # bytes 7 through 10 (limit 11)
|
|
if state & ISP_SOURCE_SEROM:
|
|
isp_print_color("blue","SEROM")
|
|
error_string = serom_error_lookup.get(int.from_bytes(ErrorCode,"little"))
|
|
Maintenance_string = "<None>"
|
|
if state & ISP_SOURCE_SERAM:
|
|
isp_print_color("blue","SERAM")
|
|
MaintenanceMode = int.from_bytes(message[11:15],"little")
|
|
Maintenance_string = "Enabled" if (MaintenanceMode == 1) else "Disabled "
|
|
|
|
isp_print_color("blue"," Error = ")
|
|
isp_print_color("blue",hex(int.from_bytes(ErrorCode,"little")))
|
|
if error_string:
|
|
isp_print_color("blue"," (" + error_string + ") ")
|
|
isp_print_color("blue"," Extended Error = ")
|
|
isp_print_color("blue",hex(int.from_bytes(ExtendedErrorCode,"little")))
|
|
isp_print_color("blue"," Maintenance Mode = " + Maintenance_string)
|
|
print(" ")
|
|
|
|
|
|
def isp_show_maintenance_mode(isp, maintenance_mode):
|
|
"""
|
|
isp_show_maintenance_mode
|
|
- disply the maintence mode status
|
|
"""
|
|
Maintenance_string = "Enabled" if (maintenance_mode == 1) else "Disabled "
|
|
isp_print_color("blue","Maintenance Mode = " + Maintenance_string)
|
|
print(" ")
|
|
|
|
def isp_get_maintenance_status(isp):
|
|
"""
|
|
isp_get_maintenance_status
|
|
- This is wrapper around isp_enquiry which returns the error code
|
|
data as well, this is ignored.
|
|
"""
|
|
MaintenanceMode = 0
|
|
message = isp_build_packet(isp, ISP_COMMAND_ENQUIRY)
|
|
if len(message) != 0:
|
|
cmd = message[ISP_PACKET_COMMAND_FIELD]
|
|
|
|
if cmd == ISP_COMMAND_DATA_RESPONSE:
|
|
# isp_print_response("blue",message)
|
|
length = message[ISP_PACKET_LENGTH_FIELD]
|
|
state = message[ISP_PACKET_DATA_FIELD]
|
|
if state & ISP_SOURCE_SERAM:
|
|
MaintenanceMode = int.from_bytes(message[11:15],"little")
|
|
|
|
return MaintenanceMode
|
|
|
|
def isp_get_revision(isp):
|
|
"""
|
|
isp_get_revision handler
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_REVISION])
|
|
|
|
if len(message) == 0:
|
|
return
|
|
cmd = message[ISP_PACKET_COMMAND_FIELD]
|
|
|
|
if cmd == ISP_COMMAND_DATA_RESPONSE:
|
|
version_decode(isp,message)
|
|
|
|
def isp_get_baud_rate(isp):
|
|
"""
|
|
isp_get_baud_rate
|
|
"""
|
|
baud_rate = 0
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET_BAUD_RATE)
|
|
baud_rate = int.from_bytes(message[2:6],"little")
|
|
isp_print_color("blue",baud_rate)
|
|
print(" ")
|
|
|
|
return baud_rate
|
|
|
|
def isp_get_toc_data(isp):
|
|
"""
|
|
isp_get_toc_data
|
|
"""
|
|
isp_print_color("blue",
|
|
" +----------+--------+------------+------------+------------+------------+----------+-----------+--------+----------+\n")
|
|
isp_print_color("blue",
|
|
" | Name | CPU | Store Addr | Obj Addr | Dest Addr | Boot Addr | Size | Version | Flags | Time (ms)|\n")
|
|
isp_print_color("blue",
|
|
" +----------+--------+------------+------------+------------+------------+----------+-----------+--------+----------+\n")
|
|
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_TOC_INFO])
|
|
|
|
if len(message) == 0:
|
|
return
|
|
|
|
# This uses a "stream" of packets sent back from SERAM
|
|
while (message[ISP_PACKET_COMMAND_FIELD] == ISP_COMMAND_DATA_RESPONSE and
|
|
message[ISP_DATA_START_FIELD] == ISP_DATA_START_MARKER):
|
|
|
|
display_toc_info(message[3::]) # Skip header, payload only
|
|
|
|
message = isp_readmessage(isp)
|
|
command = isp_decode_packet(isp,"RX<-- ", message)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
isp_print_color("blue",
|
|
" +----------+--------+------------+------------+------------+------------+----------+-----------+--------+----------+\n")
|
|
|
|
def isp_get_power_data(isp):
|
|
"""
|
|
isp_get_power_data
|
|
"""
|
|
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_POWER_INFO])
|
|
|
|
if len(message) == 0:
|
|
return
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
return
|
|
|
|
display_power_info(message[2::]) # Skip header, payload only
|
|
# display_power_info(message) # Skip header, payload only
|
|
|
|
def isp_get_clock_data(isp):
|
|
"""
|
|
isp_get_power_data
|
|
"""
|
|
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_CLOCK_INFO])
|
|
|
|
if len(message) == 0:
|
|
return
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
return
|
|
|
|
display_clock_info(message[2::]) # Skip header, payload only
|
|
|
|
def isp_get_banner(isp):
|
|
"""
|
|
isp_get_banner - retrieve seram banner
|
|
sub-command ISP_GET_BANNER
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_BANNER])
|
|
|
|
if len(message) == 0:
|
|
return
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_DATA_RESPONSE:
|
|
isp_print_message("blue", message)
|
|
print(" ")
|
|
|
|
def isp_get_mram_contents(isp):
|
|
"""
|
|
isp_get_mram_contents - retrieve MRAM details
|
|
sub-command ISP_GET_MRAM_CONTENTS
|
|
"""
|
|
delay = 10
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_MRAM_CONTENTS], delay)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
|
|
while (message[ISP_PACKET_COMMAND_FIELD] == ISP_COMMAND_DATA_RESPONSE and
|
|
message[ISP_TOC_COMMAND_FIELD] == ISP_TOC_INFO_START_MARKER):
|
|
toc_decode_toc_info(isp, message)
|
|
|
|
message = isp_readmessage(isp)
|
|
isp_decode_packet(isp,"RX<-- ", message)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
|
|
def isp_get_cpu_status(isp):
|
|
"""
|
|
isp_get_cpu_state
|
|
|
|
ISP_DATA_RESPONSE packet for return data
|
|
|
|
CPU_ID Booted Boot Addess
|
|
<1-byte> <1-byte> <4-bytes> = 6-bytes
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_CPU_STATUS])
|
|
|
|
if len(message) == 0: # Nothing came back
|
|
return
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_DATA_RESPONSE:
|
|
display_cpu_info(message)
|
|
|
|
def isp_get_seram_metrics(isp):
|
|
"""
|
|
isp_get_seram_metrics
|
|
|
|
ISP_DATA_RESPONSE packet for return data
|
|
|
|
Task Name Size Used
|
|
<16-bytes> <4-byte> <4-bytes> = 24-bytes
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_SERAM_METRICS])
|
|
|
|
if len(message) == 0: # Nothing came back
|
|
return
|
|
|
|
if message[ISP_PACKET_COMMAND_FIELD] == ISP_COMMAND_DATA_RESPONSE:
|
|
isp_print_color("blue", " +-------------------------------+\n")
|
|
isp_print_color("blue", " | TaskName | Size | Used |\n")
|
|
isp_print_color("blue", " +-----------------+------+------+\n")
|
|
|
|
# unpack the data in the response. 2 CPUS x 6-bytes of data
|
|
# @todo magic numbers need to go away and less cut and paste code
|
|
packet_start = ISP_PACKET_DATA_FIELD
|
|
element = message[packet_start::]
|
|
|
|
# uint32_t number of tasks
|
|
# uint32_t uptime
|
|
# struct {
|
|
# uint32_t stack_size
|
|
# uint32_t stack_used
|
|
# char task_name[16]
|
|
#} [number_of_tasks]
|
|
(number_of_tasks,) = struct.unpack("<I",bytes(element[0:4]))
|
|
(uptime,) = struct.unpack("<I",bytes(element[4:8]))
|
|
|
|
packet_start = 8 # skip over first 2 words
|
|
for each_task in range(number_of_tasks):
|
|
stack_size, stack_used, seram_task_name = \
|
|
struct.unpack("<II16s", bytes(element[packet_start:packet_start+24]))
|
|
stack_left = (stack_size*4) - (stack_used*4)
|
|
name_str = ''.join([chr(e) for e in seram_task_name])
|
|
|
|
print_string = \
|
|
" | {:16s} | {:4d} | {:4d} |\n".format(str(name_str),
|
|
stack_size*4,
|
|
stack_left)
|
|
isp_print_color("blue", print_string)
|
|
packet_start = packet_start + 24
|
|
isp_print_color("blue", " +-----------------+------+------+\n")
|
|
|
|
days, hours, minutes, seconds = convert_from_ms(uptime)
|
|
isp_print_color("blue",
|
|
" SES uptime {}:{:02}:{:02}:{:02}".format(days,hours,minutes,seconds))
|
|
print(" ")
|
|
|
|
def isp_get_trace_buffer(isp):
|
|
"""
|
|
isp_get_trace_buffer
|
|
SEROM pull back the trace buffer and processes through the decoder
|
|
"""
|
|
delay = 0
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_TRACE_BUFFER], delay)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
|
|
# This uses a "stream" of packets sent back from SERAM
|
|
trace_buffer = message[3:7]
|
|
while (message[ISP_PACKET_COMMAND_FIELD] == ISP_COMMAND_DATA_RESPONSE and
|
|
message[ISP_DATA_START_FIELD] == ISP_DATA_START_MARKER):
|
|
#
|
|
message = isp_readmessage(isp)
|
|
command = isp_decode_packet(isp,"RX<-- ", message)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
trace_buffer += message[3:7]
|
|
|
|
for each_word in range(0,516,4):
|
|
trace_value = trace_buffer[each_word:each_word+4]
|
|
value = int.from_bytes(trace_value,byteorder='little')
|
|
# DEBUG lives here
|
|
# print("{:4d} 0x{:08x} ".format(each_word,value))
|
|
trace_buffer_decode(trace_buffer, 0)
|
|
|
|
def isp_get_seram_trace_buffer(isp):
|
|
"""
|
|
isp_get_seram_trace_buffer
|
|
SERAM pull back the trace buffer and processes through the decoder
|
|
"""
|
|
delay = 0
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_SERAM_TRACE_BUFFER], delay)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
|
|
# This uses a "stream" of packets sent back from SERAM
|
|
trace_buffer = message[3:7]
|
|
while (message[ISP_PACKET_COMMAND_FIELD] == ISP_COMMAND_DATA_RESPONSE and
|
|
message[ISP_DATA_START_FIELD] == ISP_DATA_START_MARKER):
|
|
#
|
|
message = isp_readmessage(isp)
|
|
command = isp_decode_packet(isp,"RX<-- ", message)
|
|
|
|
if len(message) == 0:
|
|
return
|
|
trace_buffer += message[3:7]
|
|
|
|
for each_word in range(0,516,4):
|
|
trace_value = trace_buffer[each_word:each_word+4]
|
|
value = int.from_bytes(trace_value,byteorder='little')
|
|
# DEBUG lives here
|
|
# print("{:4d} 0x{:08x} ".format(each_word,value))
|
|
trace_buffer_decode(trace_buffer, 1)
|
|
|
|
def isp_get_address(isp, address):
|
|
"""
|
|
isp_get_address
|
|
"""
|
|
delay = 0
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET,
|
|
[ISP_GET_PEEK_ADDRESS,address],
|
|
delay)
|
|
if len(message) != 0:
|
|
cmd = message[ISP_PACKET_COMMAND_FIELD]
|
|
|
|
if cmd == ISP_COMMAND_DATA_RESPONSE:
|
|
length = message[ISP_PACKET_LENGTH_FIELD]
|
|
value = int.from_bytes(message[ISP_PACKET_DATA_FIELD:6],"little")
|
|
print(hex(value))
|
|
|
|
def isp_set_address(isp, address, data):
|
|
"""
|
|
isp_set_address
|
|
"""
|
|
delay = 0
|
|
message = isp_build_packet(isp, ISP_COMMAND_SET,
|
|
[ISP_SET_POKE_ADDRESS,address,data],
|
|
delay)
|
|
if len(message) != 0:
|
|
cmd = message[ISP_PACKET_COMMAND_FIELD]
|
|
|
|
if cmd == ISP_COMMAND_DATA_RESPONSE:
|
|
length = message[ISP_PACKET_LENGTH_FIELD]
|
|
value = int.from_bytes(message[ISP_PACKET_DATA_FIELD:6],"little")
|
|
print(hex(value))
|
|
|
|
def isp_set_log_enable(isp, enable):
|
|
"""
|
|
SET capability - LOGGER enable/disable
|
|
"""
|
|
# delay = 0
|
|
if enable:
|
|
response = isp_build_packet(isp, ISP_COMMAND_SET, [ISP_SET_LOGGING_ENABLE])
|
|
else:
|
|
response = isp_build_packet(isp, ISP_COMMAND_SET, [ISP_SET_LOGGING_DISABLE])
|
|
|
|
if len(response) == 0:
|
|
return
|
|
|
|
command = response[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
error_string = error_lookup.get(response[ISP_PACKET_DATA_FIELD])
|
|
if not error_string:
|
|
error_string = "UNKNOWN"
|
|
isp_print_color("blue","[ERROR] {}".format(error_string))
|
|
print(" ")
|
|
return # Exit this function
|
|
|
|
return
|
|
|
|
def isp_set_print_enable(isp, enable):
|
|
"""
|
|
SET capability - PRINT enable/disable
|
|
"""
|
|
delay = 0
|
|
if enable:
|
|
response = isp_build_packet(isp, ISP_COMMAND_SET, [ISP_SET_PRINTING_ENABLE])
|
|
else:
|
|
response = isp_build_packet(isp, ISP_COMMAND_SET, [ISP_SET_PRINTING_DISABLE])
|
|
|
|
if len(response) == 0:
|
|
return
|
|
|
|
command = response[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
error_string = error_lookup.get(response[ISP_PACKET_DATA_FIELD])
|
|
if not error_string:
|
|
error_string = "UNKNOWN"
|
|
isp_print_color("blue","[ERROR] {}".format(error_string))
|
|
print(" ")
|
|
return # Exit this function
|
|
|
|
return
|
|
|
|
def isp_get(isp,getobject):
|
|
"""
|
|
isp_get
|
|
get an "object"
|
|
"""
|
|
isp_build_packet(isp, ISP_COMMAND_GET)
|
|
|
|
def isp_set(isp,getobject):
|
|
"""
|
|
isp_set
|
|
set an attribute "object"
|
|
"""
|
|
isp_build_packet(isp, ISP_COMMAND_SET)
|
|
|
|
def isp_read_otp(isp,word_offset):
|
|
"""
|
|
isp_read_otp
|
|
retrieve otp @ word_offset
|
|
"""
|
|
response = isp_build_packet(isp, ISP_COMMAND_OTP_READ, [int(word_offset)])
|
|
if len(response) == 0:
|
|
return
|
|
|
|
command = response[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
error_string = error_lookup.get(response[ISP_PACKET_DATA_FIELD])
|
|
if not error_string:
|
|
error_string = "UNKNOWN"
|
|
otp_value = int.from_bytes(response[2:6],"little")
|
|
isp_print_color("blue","[ERROR] 0x{:04x} {}".format(
|
|
word_offset, error_string))
|
|
print(" ")
|
|
|
|
return # Exit this function
|
|
|
|
if command != ISP_COMMAND_DATA_RESPONSE:
|
|
isp_print_color("blue","[ERROR] No response")
|
|
return None # Exit this function
|
|
|
|
# Display the OTP data
|
|
display_otp_info(word_offset, response)
|
|
|
|
def isp_set_baud_rate(isp, baud_rate):
|
|
"""
|
|
isp_get_baud_rate
|
|
"""
|
|
isp_build_packet(isp, ISP_COMMAND_SET_BAUD_RATE, [baud_rate])
|
|
|
|
def isp_set_host_baud_rate(isp, baud_rate):
|
|
"""
|
|
set the host baud rate
|
|
"""
|
|
isp.setBaudRate(baud_rate)
|
|
|
|
def isp_mram_write(isp, offset, data):
|
|
"""
|
|
isp_Mram_Write
|
|
- send data to write to the MRAM - SEROM style
|
|
(used by icv-recovery.py and recovery.py)
|
|
"""
|
|
isp_build_packet(isp, ISP_COMMAND_MRAM_WRITE, [offset, bytearray(data)])
|
|
|
|
def isp_read_mram(isp,word_offset=0x0):
|
|
"""
|
|
isp_read_mram
|
|
retrieve mram @ word_offset
|
|
"""
|
|
response = isp_build_packet(isp, ISP_COMMAND_MRAM_READ, [int(word_offset),b'\x10'])
|
|
if len(response) == 0:
|
|
return
|
|
|
|
command = response[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_NAK:
|
|
error_string = error_lookup.get(response[ISP_PACKET_DATA_FIELD])
|
|
if not error_string:
|
|
error_string = "UNKNOWN"
|
|
isp_print_color("blue","[ERROR] 0x{:04x} {}".format(
|
|
word_offset, error_string))
|
|
print(" ")
|
|
if command != ISP_COMMAND_DATA_RESPONSE:
|
|
return None
|
|
|
|
# write out the 4 int32 values of the MRAM line
|
|
isp_print_color("blue","[0x{:x}] ".format(word_offset))
|
|
for each_word in range(2,18,4):
|
|
mram_value = response[each_word:each_word+4]
|
|
value = int.from_bytes(mram_value,byteorder='little')
|
|
isp_print_color("blue","0x{:08x} ".format(value))
|
|
print(" ")
|
|
|
|
def isp_mram_erase(isp, address, size=0,pattern=0x00000000):
|
|
"""
|
|
isp_erase_mram
|
|
- erase ATOC memory from <address> for <size> with <pattern>
|
|
"""
|
|
delay = 0
|
|
if size >= 1048576: # ACK will take some time at this size
|
|
delay = 20
|
|
isp_build_packet(isp, ISP_COMMAND_ERASE_MRAM, [address,size,pattern], delay)
|
|
|
|
def isp_sram_write(isp, offset, data):
|
|
"""
|
|
isp_Sram_Write
|
|
- send data to write to the SE RAM - SEROM only
|
|
(used by recovery-execute-package.py)
|
|
"""
|
|
|
|
#print("* write to offset ", hex(offset))
|
|
#print("* data: ", data)
|
|
isp_build_packet(isp, ISP_COMMAND_SRAM_WRITE, [offset, bytearray(data)])
|
|
|
|
def isp_set_maintenance_flag(isp):
|
|
"""
|
|
isp_set_maintenance_flag
|
|
- Send Command to set the maintenance flag on the target
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_SET_MAINTENANCE_FLAG)
|
|
|
|
def isp_get_log_data(isp):
|
|
"""
|
|
isp_get_log_data
|
|
"""
|
|
|
|
# get log buffer info
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_LOG_BUFFER_INFO])
|
|
if len(message) == 0:
|
|
return None
|
|
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command != ISP_COMMAND_DATA_RESPONSE:
|
|
return None
|
|
|
|
(buffer_size,) = struct.unpack("<I",bytes(message[2:6]))
|
|
(head_offset,) = struct.unpack("<I",bytes(message[6:10]))
|
|
(tail_offset,) = struct.unpack("<I",bytes(message[10:14]))
|
|
|
|
#print('buffer_size: ', buffer_size)
|
|
#print('head_offset: ', head_offset)
|
|
#print('tail_offset: ', tail_offset)
|
|
|
|
# get log data
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_LOG_DATA])
|
|
if len(message) == 0:
|
|
return None
|
|
|
|
log_data = []
|
|
while message[ISP_PACKET_COMMAND_FIELD] == ISP_COMMAND_DATA_RESPONSE:
|
|
# process message
|
|
data = message[ISP_PACKET_DATA_FIELD:len(message)-1]
|
|
#print("data: ", data)
|
|
|
|
log_data += data
|
|
|
|
message = isp_readmessage(isp)
|
|
command = isp_decode_packet(isp,"RX<-- ", message)
|
|
if len(message) == 0:
|
|
break
|
|
|
|
#print("log_data: ", log_data)
|
|
return (buffer_size, head_offset, tail_offset, log_data)
|
|
|
|
def isp_get_seram_update_address(isp):
|
|
"""
|
|
isp_get_seram_update_address
|
|
"""
|
|
address = 0
|
|
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_SERAM_UPDT_ADDR])
|
|
_expected_length = ISP_PACKET_HEADER_LENGTH + 4 + 1
|
|
if len(message) == ISP_PACKET_HEADER_LENGTH:
|
|
return address
|
|
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command == ISP_COMMAND_DATA_RESPONSE:
|
|
address = int.from_bytes(message[2:6],"little")
|
|
|
|
return address
|
|
|
|
def isp_get_ecc_key(isp):
|
|
"""
|
|
isp_get_ecc_key
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_ECC_KEY])
|
|
if len(message) == 0:
|
|
return
|
|
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command != ISP_COMMAND_DATA_RESPONSE:
|
|
print("ECC query error")
|
|
return
|
|
|
|
ecc_key = message[2:66]
|
|
print("ECC key (HEX): ", "".join("{:02X}".format(n) for n in ecc_key))
|
|
|
|
|
|
def isp_get_firewall_config(isp):
|
|
"""
|
|
isp_get_firewall_config
|
|
"""
|
|
message = isp_build_packet(isp, ISP_COMMAND_GET, [ISP_GET_FIREWALL_CONFIG])
|
|
if len(message) == 0:
|
|
return
|
|
|
|
command = message[ISP_PACKET_COMMAND_FIELD]
|
|
if command != ISP_COMMAND_DATA_RESPONSE:
|
|
print("Firewall configuration query error")
|
|
return
|
|
|
|
firewall_config = message[2:202]
|
|
print("Firewall configuration:")
|
|
for idx in range(0, 200, 2):
|
|
if 0 == firewall_config[idx]:
|
|
continue
|
|
data = int.from_bytes(firewall_config[idx:idx+2],"little")
|
|
print("FC: " + str(data & 0xF) + " region: " + str((data & 0xFF0) >> 4))
|