BA / Mbed OS BaBoRo1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NCS.py Source File

NCS.py

00001 """
00002 @copyright (c) 2012 ON Semiconductor. All rights reserved.
00003 ON Semiconductor is supplying this software for use with ON Semiconductor
00004 processor based microcontrollers only.
00005 THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
00006 OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
00007 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
00008 ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
00009 INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
00010 """
00011 
00012 from __future__ import absolute_import
00013 from __future__ import print_function
00014 
00015 import itertools
00016 import binascii
00017 import intelhex
00018 from tools.config import Config
00019 
00020 FIB_BASE = 0x2000
00021 TRIM_BASE = 0x2800
00022 FLASH_BASE = 0x3000
00023 FLASHA_SIZE = 0x52000
00024 FLASHB_BASE = 0x00102000
00025 FLASHB_SIZE = 0x52000
00026 FW_REV = 0x01000100
00027 
00028 def ranges(i):
00029     for _, b in itertools.groupby(enumerate(i), lambda x_y: x_y[1] - x_y[0]):
00030         b = list(b)
00031         yield b[0][1], b[-1][1]
00032 
00033 
00034 def add_fib_at_start(arginput):
00035     input_file = arginput + ".hex"
00036     file_name_hex = arginput + ".hex"
00037     file_name_bin = arginput + ".bin"
00038 
00039     # Read in hex file
00040     input_hex_file = intelhex.IntelHex()
00041     input_hex_file.loadhex(input_file)
00042     #set padding value to be returned when reading from unspecified address
00043     input_hex_file.padding = 0xFF
00044     # Create new hex file
00045     output_hex_file = intelhex.IntelHex()
00046 
00047     # Get the starting and ending address
00048     addresses = input_hex_file.addresses()
00049     addresses.sort()
00050     start_end_pairs = list(ranges(addresses))
00051     regions = len(start_end_pairs)
00052 
00053     if regions == 1:
00054         #single range indicating fits within first flash block (<320K)
00055         start, end = start_end_pairs[0]
00056         print("Memory start 0x%08X, end 0x%08X" % (start, end))
00057         # Compute checksum over the range (don't include data at location of crc)
00058         size = end - start + 1
00059         data = input_hex_file.tobinarray(start=start, size=size)
00060         crc32 = binascii.crc32(data) & 0xFFFFFFFF
00061     else:
00062         #multiple ranges indicating requires both flash blocks (>320K)
00063         start, end = start_end_pairs[0]
00064         start2, end2 = start_end_pairs[1]
00065         print("Region 1: memory start 0x%08X, end 0x%08X" % (start, end))
00066         print("Region 2: memory start 0x%08X, end 0x%08X" % (start2, end2))
00067         # Compute checksum over the range (don't include data at location of crc)
00068         # replace end with end of flash block A
00069         end = FLASHA_SIZE - 1
00070         size = end - start + 1
00071         data = input_hex_file.tobinarray(start=start, size=size)
00072 
00073         # replace start2 with base of flash block B
00074         start2 = FLASHB_BASE
00075         size2 = end2 - start2 + 1
00076         data2 = input_hex_file.tobinarray(start=start2, size=size2)
00077 
00078         #concatenate data and data2 arrays together
00079         data.extend(data2)
00080         crc32 = binascii.crc32(data) & 0xFFFFFFFF
00081 
00082         #replace size with sum of two memory region sizes
00083         size = size + size2
00084 
00085     assert start >= FLASH_BASE, ("Error - start 0x%x less than begining of user\
00086     flash area" %start)
00087 
00088     assert regions <= 2, ("Error - more than 2 memory regions found")
00089 
00090     fw_rev = FW_REV
00091 
00092     checksum = (start + size + crc32 + fw_rev) & 0xFFFFFFFF
00093 
00094     print("Writing FIB: base 0x%08X, size 0x%08X, crc32 0x%08X, fw rev 0x%08X,\
00095     checksum 0x%08X" % (start, size, crc32, fw_rev, checksum))
00096 
00097 #expected initial values used by daplink to validate that it is a valid bin
00098 #file added as dummy values in this file because the fib area preceeds the
00099 #application area the bootloader will ignore these dummy values
00100 #  00 is stack pointer (RAM address)
00101 #  04 is Reset vector  (FLASH address)
00102 #  08 NMI_Handler      (FLASH address)
00103 #  0C HardFault_Handler(FLASH address)
00104 #  10 dummy
00105     dummy_sp = 0x3FFFFC00
00106     dummy_reset_vector = 0x00003625
00107     dummy_nmi_handler = 0x00003761
00108     dummy_hardfault_handler = 0x00003691
00109     dummy_blank = 0x00000000
00110 
00111 #expected fib structure
00112 #typedef struct fib{
00113     #uint32_t base;     /**< Base offset of firmware, indicating what flash the
00114     #                        firmware is in. (will never be 0x11111111) */
00115     #uint32_t size;     /**< Size of the firmware */
00116     #uint32_t crc;      /**< CRC32 for firmware correctness check */
00117     #uint32_t rev;      /**< Revision number */
00118     #uint32_t checksum; /**< Check-sum of information block */
00119 #}fib_t, *fib_pt;
00120 
00121     fib_start = FIB_BASE
00122     dummy_fib_size = 20
00123     fib_size = 20
00124     trim_size = 24
00125     user_code_start = FLASH_BASE
00126     trim_area_start = TRIM_BASE
00127 
00128     # Write FIB to the file in little endian
00129     output_hex_file[fib_start + 0] = (dummy_sp >> 0) & 0xFF
00130     output_hex_file[fib_start + 1] = (dummy_sp >> 8) & 0xFF
00131     output_hex_file[fib_start + 2] = (dummy_sp >> 16) & 0xFF
00132     output_hex_file[fib_start + 3] = (dummy_sp >> 24) & 0xFF
00133 
00134     output_hex_file[fib_start + 4] = (dummy_reset_vector >> 0) & 0xFF
00135     output_hex_file[fib_start + 5] = (dummy_reset_vector >> 8) & 0xFF
00136     output_hex_file[fib_start + 6] = (dummy_reset_vector >> 16) & 0xFF
00137     output_hex_file[fib_start + 7] = (dummy_reset_vector >> 24) & 0xFF
00138 
00139     output_hex_file[fib_start + 8] = (dummy_nmi_handler >> 0) & 0xFF
00140     output_hex_file[fib_start + 9] = (dummy_nmi_handler >> 8) & 0xFF
00141     output_hex_file[fib_start + 10] = (dummy_nmi_handler >> 16) & 0xFF
00142     output_hex_file[fib_start + 11] = (dummy_nmi_handler >> 24) & 0xFF
00143 
00144     output_hex_file[fib_start + 12] = (dummy_hardfault_handler >> 0) & 0xFF
00145     output_hex_file[fib_start + 13] = (dummy_hardfault_handler >> 8) & 0xFF
00146     output_hex_file[fib_start + 14] = (dummy_hardfault_handler >> 16) & 0xFF
00147     output_hex_file[fib_start + 15] = (dummy_hardfault_handler >> 24) & 0xFF
00148 
00149     output_hex_file[fib_start + 16] = (dummy_blank >> 0) & 0xFF
00150     output_hex_file[fib_start + 17] = (dummy_blank >> 8) & 0xFF
00151     output_hex_file[fib_start + 18] = (dummy_blank >> 16) & 0xFF
00152     output_hex_file[fib_start + 19] = (dummy_blank >> 24) & 0xFF
00153 
00154     # Write FIB to the file in little endian
00155     output_hex_file[fib_start + 20] = (start >> 0) & 0xFF
00156     output_hex_file[fib_start + 21] = (start >> 8) & 0xFF
00157     output_hex_file[fib_start + 22] = (start >> 16) & 0xFF
00158     output_hex_file[fib_start + 23] = (start >> 24) & 0xFF
00159 
00160     output_hex_file[fib_start + 24] = (size >> 0) & 0xFF
00161     output_hex_file[fib_start + 25] = (size >> 8) & 0xFF
00162     output_hex_file[fib_start + 26] = (size >> 16) & 0xFF
00163     output_hex_file[fib_start + 27] = (size >> 24) & 0xFF
00164 
00165     output_hex_file[fib_start + 28] = (crc32 >> 0) & 0xFF
00166     output_hex_file[fib_start + 29] = (crc32 >> 8) & 0xFF
00167     output_hex_file[fib_start + 30] = (crc32 >> 16) & 0xFF
00168     output_hex_file[fib_start + 31] = (crc32 >> 24) & 0xFF
00169 
00170     output_hex_file[fib_start + 32] = (fw_rev >> 0) & 0xFF
00171     output_hex_file[fib_start + 33] = (fw_rev >> 8) & 0xFF
00172     output_hex_file[fib_start + 34] = (fw_rev >> 16) & 0xFF
00173     output_hex_file[fib_start + 35] = (fw_rev >> 24) & 0xFF
00174 
00175     output_hex_file[fib_start + 36] = (checksum >> 0) & 0xFF
00176     output_hex_file[fib_start + 37] = (checksum >> 8) & 0xFF
00177     output_hex_file[fib_start + 38] = (checksum >> 16) & 0xFF
00178     output_hex_file[fib_start + 39] = (checksum >> 24) & 0xFF
00179 
00180     #pad the rest of the file
00181     for i in range(fib_start + dummy_fib_size + fib_size, trim_area_start):
00182         output_hex_file[i] = 0xFF
00183 
00184     # Read in configuration data from the config parameter in targets.json
00185     configData = Config('NCS36510')
00186     paramData = configData.get_target_config_data()
00187     for v in paramData.values():
00188         if (v.name == "target.mac-addr-high"):
00189             mac_addr_high = int(v.value, 16)
00190         elif (v.name == "target.mac-addr-low"):
00191             mac_addr_low = int(v.value,16)
00192         elif (v.name == "target.32KHz-clk-trim"):
00193             clk_32k_trim = int(v.value,16)
00194         elif (v.name == "target.32MHz-clk-trim"):
00195             clk_32m_trim = int(v.value,16)
00196         elif (v.name == "target.rssi-trim"):
00197             rssi = int(v.value,16)
00198         elif (v.name == "target.txtune-trim"):
00199             txtune = int(v.value,16)
00200         else:
00201             print("Not a valid param")
00202 
00203     output_hex_file[trim_area_start + 0] = mac_addr_low & 0xFF
00204     output_hex_file[trim_area_start + 1] = (mac_addr_low >> 8)  & 0xFF
00205     output_hex_file[trim_area_start + 2] = (mac_addr_low >> 16) & 0xFF
00206     output_hex_file[trim_area_start + 3] = (mac_addr_low >> 24) & 0xFF
00207 
00208     output_hex_file[trim_area_start + 4] = mac_addr_high & 0xFF
00209     output_hex_file[trim_area_start + 5] = (mac_addr_high >> 8)  & 0xFF
00210     output_hex_file[trim_area_start + 6] = (mac_addr_high >> 16) & 0xFF
00211     output_hex_file[trim_area_start + 7] = (mac_addr_high >> 24) & 0xFF
00212 
00213     output_hex_file[trim_area_start + 8] = clk_32k_trim & 0xFF
00214     output_hex_file[trim_area_start + 9] = (clk_32k_trim >> 8)  & 0xFF
00215     output_hex_file[trim_area_start + 10] = (clk_32k_trim >> 16) & 0xFF
00216     output_hex_file[trim_area_start + 11] = (clk_32k_trim >> 24) & 0xFF
00217 
00218     output_hex_file[trim_area_start + 12] = clk_32m_trim & 0xFF
00219     output_hex_file[trim_area_start + 13] = (clk_32m_trim >> 8)  & 0xFF
00220     output_hex_file[trim_area_start + 14] = (clk_32m_trim >> 16) & 0xFF
00221     output_hex_file[trim_area_start + 15] = (clk_32m_trim >> 24) & 0xFF
00222 
00223     output_hex_file[trim_area_start + 16] = rssi & 0xFF
00224     output_hex_file[trim_area_start + 17] = (rssi >> 8)  & 0xFF
00225     output_hex_file[trim_area_start + 18] = (rssi >> 16) & 0xFF
00226     output_hex_file[trim_area_start + 19] = (rssi >> 24) & 0xFF
00227 
00228     output_hex_file[trim_area_start + 20] = txtune & 0xFF
00229     output_hex_file[trim_area_start + 21] = (txtune >> 8)  & 0xFF
00230     output_hex_file[trim_area_start + 22] = (txtune >> 16) & 0xFF
00231     output_hex_file[trim_area_start + 23] = (txtune >> 24) & 0xFF
00232 
00233     # pad the rest of the area with 0xFF
00234     for i in range(trim_area_start + trim_size, user_code_start):
00235         output_hex_file[i] = 0xFF
00236 
00237     #merge two hex files
00238     output_hex_file.merge(input_hex_file, overlap='error')
00239 
00240     # Write out file(s)
00241     output_hex_file.tofile(file_name_hex, 'hex')