From 9861b697a6a7b808ae089f9d186747c51974b265 Mon Sep 17 00:00:00 2001 From: MKesenheimer Date: Sat, 15 Feb 2025 23:27:49 +0100 Subject: [PATCH] Added support for the LPC1311; added support for python3 --- .gitignore | 2 ++ README => README.md | 30 ++++++++++++++++++++++++-- nxpprog.py | 52 +++++++++++++++++++++++++++++++++------------ requirements.txt | 1 + 4 files changed, 69 insertions(+), 16 deletions(-) rename README => README.md (67%) create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 7cd0b87..1ce233c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.pyc uploads +*.bin +.DS_Store diff --git a/README b/README.md similarity index 67% rename from README rename to README.md index d4b3e2d..2d55ef2 100644 --- a/README +++ b/README.md @@ -1,12 +1,16 @@ -Programmer for NXP arm processors using ISP protocol. +# Programmer for NXP arm processors using ISP protocol. For help run the command with no arguments: +``` ./nxpprog.py +``` Program image file to processor: +``` ./nxpprog.py +``` The image start address defaults to 0. When the image start address is 0 a checksum is inserted in the reserved @@ -19,12 +23,34 @@ converters on windows and doesn't seem necessary in my setup. If you in your setup need flow control, for example if you get programming errors, then try enabling this. -Windows Advice +## Windows Advice When you have installed python for windows and the (py)serial module then something like this should work: +``` \python.exe nxpprog.py COM1 image.bin +``` It is very important that the serial port name is written in capital letters, lower case names will not be matched against possible serial devices. + +## Examples programming the LPC1311 + +Flash an image: + +``` +python nxpprog.py --eraseall /dev/tty.usbserial-A50285BI test.bin +``` + +Check if flash is blank after programming (should fail): + +``` +python nxpprog.py --blankcheck /dev/tty.usbserial-A50285BI +``` + +Dump image: + +``` +python nxpprog.py --read dump.bin --addr=0 --len=32 /dev/tty.usbserial-A50285BI +``` \ No newline at end of file diff --git a/nxpprog.py b/nxpprog.py index 60d3624..71deff5 100755 --- a/nxpprog.py +++ b/nxpprog.py @@ -94,6 +94,16 @@ 4, 4, 4, 4, 4, 4, 4, 4, ) +# flash sector sizes for lpc1311 processors (number of sectors and size in kB) +flash_sector_lpc1311 = ( + 4, 4, + ) + +# flash sector sizes for lpc1313 processors (number of sectors and size in kB) +flash_sector_lpc1313 = ( + 4, 4, 4, 4, 4, 4, 4, 4, + ) + # flash sector sizes for lpc18xx processors flash_sector_lpc18xx = ( 8, 8, 8, 8, 8, 8, 8, 8, @@ -326,6 +336,12 @@ "devid": 0x0444102B, "flash_prog_buffer_size" : 1024 }, + "lpc1311" : { + "flash_sector" : flash_sector_lpc1311, + "flash_prog_buffer_base" : 0x10000400, + "devid": 0x2C42502B, + "flash_prog_buffer_size" : 1024 + }, # lpc18xx "lpc1817" : { "flash_sector" : flash_sector_lpc18xx, @@ -447,7 +463,7 @@ def __init__(self, device, baud, xonxoff=False, control=False): # or the device is in the wrong mode. # This timeout is too short for slow baud rates but who wants to # use them? - self._serial.setTimeout(5) + self._serial.timeout = 5 # device wants Xon Xoff flow control if xonxoff: self._serial.setXonXoff(1) @@ -491,8 +507,8 @@ def write(self, data): def readline(self, timeout=None): if timeout: - ot = self._serial.getTimeout() - self._serial.setTimeout(timeout) + ot = self._serial.timeout + self._serial.timeout = timeout line = b'' while True: @@ -512,7 +528,7 @@ def readline(self, timeout=None): line += c if timeout: - self._serial.setTimeout(ot) + self._serial.timeout = ot return line.decode("UTF-8", "ignore") @@ -533,6 +549,8 @@ def __init__(self, address): res = obj.communicate() stdout_text = res[0].decode('ascii', 'ignore') if res[0] else "" stderr_text = res[1].decode('ascii', 'ignore') if res[1] else "" + log(stdout_text) + log(stderr_text) if obj.returncode or stderr_text: panic("Failed to register IP address " + "(Administrative privileges may be required)\r\n" + @@ -550,7 +568,7 @@ def readline(self, timeout=None): try: line, addr = self._sock.recvfrom(1024) - except Exception as e: + except Exception as _: line = b"" if timeout: @@ -797,7 +815,7 @@ def uudecode(self, line): ch %= 64 c = c * 64 + ch s = [] - for j in range(0, 3): + for _ in range(0, 3): s.append(c % 256) c = c // 256 for j in reversed(s): @@ -818,7 +836,7 @@ def read_block(self, addr, data_len, fd=None): if lines > 20: lines = 20 cdata = "" - for i in range(0, lines): + for _ in range(0, lines): line = self.dev_readline() decoded = self.uudecode(line) @@ -869,6 +887,8 @@ def write_ram_data(self, addr, data): def find_flash_sector(self, addr): table = self.get_cpu_parm("flash_sector") flash_base_addr = self.get_cpu_parm("flash_bank_addr", 0) + #print(f"table = {table}") + #print(f"flash_base_addr = {flash_base_addr}") if flash_base_addr == 0: faddr = 0 else: @@ -883,7 +903,7 @@ def find_flash_sector(self, addr): def bytestr(self, ch, count): data = b'' - for i in range(0, count): + for _ in range(0, count): data += bytes([ch]) return data @@ -947,6 +967,7 @@ def blank_check_sectors(self, start_sector, end_sector): global panic old_panic = panic panic = log + cmd = "" for i in range(start_sector, end_sector+1): if self.sector_commands_need_bank: cmd = ("I %d %d 0" % (i, i)) @@ -954,22 +975,23 @@ def blank_check_sectors(self, start_sector, end_sector): cmd = ("I %d %d" % (i, i)) result = self.isp_command(cmd) if result == str(CMD_SUCCESS): + log(f"Sector {i} blank.") pass elif result == str(SECTOR_NOT_BLANK): self.dev_readline() # offset self.dev_readline() # content else: - self.errexit("'%s' error" % cmd, status) + self.errexit("'%s' error" % cmd, result) panic = old_panic def erase_flash_range(self, start_addr, end_addr, verify=False): start_sector = self.find_flash_sector(start_addr) end_sector = self.find_flash_sector(end_addr) - + #print(f"start address = {start_addr}, end address = {end_addr}") + #print(f"start sector = {start_sector}, end sector = {end_sector}") self.erase_sectors(start_sector, end_sector, verify) - def get_cpu_parm(self, key, default=None): ccpu_parms = cpu_parms.get(self.cpu) if not ccpu_parms: @@ -1027,6 +1049,7 @@ def prog_image(self, image, flash_addr_base=0, image_len += pad_count log("Padding with %d bytes" % pad_count) + log(f"erase_all = {erase_all}") if erase_all: self.erase_all(verify) @@ -1057,11 +1080,12 @@ def prog_image(self, image, flash_addr_base=0, (flash_addr_start, ram_addr, a_ram_block)) # optionally compare ram and flash + cmd = "" if verify: old_panic = panic panic = log - result = self.isp_command("M %d %d %d" % - (flash_addr_start, ram_addr, a_ram_block)) + cmd = ("M %d %d %d" % (flash_addr_start, ram_addr, a_ram_block)) + result = self.isp_command(cmd) panic = old_panic if result == str(CMD_SUCCESS): pass @@ -1069,7 +1093,7 @@ def prog_image(self, image, flash_addr_base=0, self.dev_readline() # offset success = False else: - self.errexit("'%s' error" % cmd, status) + self.errexit("'%s' error" % cmd, result) return success diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f6c1a1f --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pyserial