Created
December 13, 2023 08:23
-
-
Save natschil/12f90320ff3c2a70711f378eef7738cb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import sys,time | |
import base64 | |
jump_table = bytearray() | |
irom1 = bytearray() | |
xip = bytearray() | |
compiler = ['ARM','GCC'][1] | |
if compiler == 'ARM': | |
infile = './bin/Lenze_rf.hex' | |
SZ = '1454' | |
print(f'Flashing firmware produced with Keil: {infile}') | |
elif compiler == 'GCC': | |
infile = './build/Lenze_RF.hex' | |
SZ = '0858' | |
print(f'Flashing firmware produced with GCC: {infile}') | |
with open(infile) as f: | |
# hex file order is assumed to be ER_ROM_XIP - JUMP_TABLE - ER_IROM1 | |
sections = ['JUMP_TABLE','ER_IROM1','XIP'] | |
infiles = [jump_table,irom1,xip] | |
infile_current = -1 | |
inbuf = None | |
for line in f: | |
if line[7:9] == '04': | |
infile_current += 1 | |
print(f'Start of new ihex section found, assuming {sections[infile_current]}') | |
inbuf = infiles[infile_current] | |
elif line[7:9] == '00': | |
inbuf.extend(bytearray.fromhex(line[9:-3])) | |
c0 = bytearray() # hexf header | |
c0.extend(bytearray.fromhex(f'03000000FFFFFFFF3818FF1FFFFFFFFF')) # RF only code has only 2 ihex sections | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'00000200FFFF000000000211FFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'00500000FFFF00000000FF1FFFFFFFFF')) | |
c0.extend(bytearray.fromhex(f'{SZ}0000FFFF00003818FF1FFFFFFFFF')) | |
c0[-44:-42] = int.to_bytes(len(xip), 2, 'little') # length ER_ROM_XIP | |
c0[-28:-26] = int.to_bytes(len(jump_table), 2, 'little') # length JUMP_TABLE | |
c0[-12:-10] = int.to_bytes(len(irom1), 2, 'little') # length ER_IROM1 | |
c1 = bytearray() # JUMP_TABLE + ER_IROM1 | |
c1.extend(jump_table) | |
c1.extend(bytearray.fromhex('0' *16)) | |
c1.extend(irom1) | |
c2 = bytearray() | |
c2.extend(xip) | |
c = [c0,c1,c2] | |
#c_test = c0 | |
#c_test.extend(c1) | |
#with open('test.hexf', 'w') as f: | |
# j = 512 | |
# for i in range(0, len(c_test), 16): | |
# row = ':1' + int.to_bytes(j, 2, 'big').hex().upper() + '000' + c_test[i:i+16].hex().upper() | |
# f.write(row) | |
# f.write(hex((sum(bytearray.fromhex(row[1:])) % 256) - (1<<8))[-2:].upper().replace('X','0') + '\n') #UGLY! | |
# if j == 529: | |
# j = 1280 | |
# else: | |
# j += 1 | |
# f.close() | |
#exit(0) | |
import serial | |
uart = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.01, inter_byte_timeout=0.01) | |
res = uart.read(10) | |
while not res.endswith(b'cmd>>:'): | |
uart.write(b'UXTDWU') | |
time.sleep(0.05) | |
res = uart.read(10) | |
if res: print(res) | |
print('RESET MODE activated. Changing baudrate to 115200') | |
uart.baudrate = 115200 | |
print('Erase + Write') | |
cmds = [] | |
cmds.append(b'er512') # erase | |
cmds.append(b'rdrev+') | |
cmds.append(b'wrreg4000c890 ab000001 ') | |
cmds.append(b'wrreg4000c838 ff010005 ') | |
cmds.append(b'spifs 0 1 3 0 ') | |
cmds.append(b'sfmod 2 2 ') | |
cmds.append(b'cpnum ffffffff ') | |
cmds.append(b'cpbin c0 002000 ' + b'%x' % len(c0) + b' 11002000') | |
cmds.append(b'cpbin c1 005000 ' + b'%x' % len(c1) + b' 11005000') | |
cmds.append(b'cpbin c2 020000 ' + b'%x' % len(c2) + b' 11020000') | |
for cmd in cmds: | |
uart.write(cmd) | |
print('sent', cmd) | |
while not uart.in_waiting: | |
time.sleep(0.3) | |
msg = uart.read(uart.in_waiting) | |
print('Response is:', msg) | |
if cmd[5:9] in [b' c0 ', b' c1 ', b' c2 ']: | |
cfile = cmd[7] -48 | |
data = c[cfile] | |
ldata = uart.write(data) | |
print('sent c%d (len=%d)' % (cfile, ldata)) | |
while not uart.in_waiting: | |
time.sleep(0.3) | |
msg = uart.read(uart.in_waiting) | |
print('Response is:', msg) | |
uart.write(b'%08x' % sum(data)) | |
print('sent checksum') | |
while not uart.in_waiting: | |
time.sleep(0.3) | |
msg = uart.read(uart.in_waiting) | |
print('Response is:', msg) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Linker script to configure memory regions. */ | |
MEMORY | |
{ | |
JUMP_TABLE (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x400 | |
GLOBAL_CONFIG (rwx) : ORIGIN = 0x1FFF0400, LENGTH = 0x400 | |
FLASH (rx) : ORIGIN = 0x1FFF1838, LENGTH = 0x4000 | |
RAM (rwx) : ORIGIN = 0x1FFF6000, LENGTH = 0x2000 | |
XIP (rw) : ORIGIN = 0x11020000, LENGTH = 0x4000 | |
} | |
ENTRY(Reset_Handler) | |
SECTIONS | |
{ | |
.jump_table_mem_area : | |
{ | |
KEEP(*(.jump_table_mem_area)) | |
} > JUMP_TABLE | |
.global_config_area : | |
{ | |
KEEP(*(.global_config_area)) | |
} > GLOBAL_CONFIG | |
.text : | |
{ | |
KEEP(*(.vectors)) | |
*(.text*) | |
KEEP(*(.init)) | |
KEEP(*(.fini)) | |
/* .ctors */ | |
*crtbegin.o(.ctors) | |
*crtbegin?.o(.ctors) | |
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) | |
*(SORT(.ctors.*)) | |
*(.ctors) | |
/* .dtors */ | |
*crtbegin.o(.dtors) | |
*crtbegin?.o(.dtors) | |
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) | |
*(SORT(.dtors.*)) | |
*(.dtors) | |
*(.rodata*) | |
KEEP(*(.eh_frame*)) | |
} > FLASH | |
.xip : | |
{ | |
*(.xip) | |
} > XIP | |
.ARM.extab : | |
{ | |
*(.ARM.extab* .gnu.linkonce.armextab.*) | |
} > FLASH | |
__exidx_start = .; | |
.ARM.exidx : | |
{ | |
*(.ARM.exidx* .gnu.linkonce.armexidx.*) | |
} > FLASH | |
__exidx_end = .; | |
/* Location counter can end up 2byte aligned with narrow Thumb code but | |
__etext is assumed by startup code to be the LMA of a section in RAM | |
which must be 4byte aligned */ | |
__etext = ALIGN (4); | |
.data : AT (__etext) | |
{ | |
__data_start__ = .; | |
*(vtable) | |
*(.data*) | |
. = ALIGN(4); | |
/* preinit data */ | |
PROVIDE_HIDDEN (__preinit_array_start = .); | |
KEEP(*(.preinit_array)) | |
PROVIDE_HIDDEN (__preinit_array_end = .); | |
. = ALIGN(4); | |
/* init data */ | |
PROVIDE_HIDDEN (__init_array_start = .); | |
KEEP(*(SORT(.init_array.*))) | |
KEEP(*(.init_array)) | |
PROVIDE_HIDDEN (__init_array_end = .); | |
. = ALIGN(4); | |
/* finit data */ | |
PROVIDE_HIDDEN (__fini_array_start = .); | |
KEEP(*(SORT(.fini_array.*))) | |
KEEP(*(.fini_array)) | |
PROVIDE_HIDDEN (__fini_array_end = .); | |
KEEP(*(.jcr*)) | |
. = ALIGN(4); | |
/* All data end */ | |
__data_end__ = .; | |
} > RAM | |
.bss : | |
{ | |
. = ALIGN(4); | |
__bss_start__ = .; | |
*(.bss*) | |
*(COMMON) | |
. = ALIGN(4); | |
__bss_end__ = .; | |
} > RAM | |
.heap (COPY): | |
{ | |
__end__ = .; | |
PROVIDE(end = .); | |
*(.heap*) | |
__HeapLimit = .; | |
} > RAM | |
/* .stack_dummy section doesn't contain any symbols. It is only | |
* used for linker to calculate size of stack sections, and assign | |
* values to stack symbols later */ | |
.stack_dummy (COPY): | |
{ | |
*(.stack*) | |
} > RAM | |
/* Set stack top to end of RAM, and stack limit move down by | |
* size of stack_dummy section */ | |
__initial_sp = ORIGIN(RAM) + LENGTH(RAM); | |
__StackTop = ORIGIN(RAM) + LENGTH(RAM); | |
__StackLimit = __StackTop - SIZEOF(.stack_dummy); | |
PROVIDE(__stack = __StackTop); | |
/* Check if data + heap + stack exceeds RAM limit */ | |
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment