#!/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; []; 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 = "" 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(" for with """ 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("> 4))