Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.pyc
uploads
*.bin
.DS_Store
30 changes: 28 additions & 2 deletions README → README.md
Original file line number Diff line number Diff line change
@@ -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 <serial device> <image_file>
```

The image start address defaults to 0.
When the image start address is 0 a checksum is inserted in the reserved
Expand All @@ -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:

```
<path to python>\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
```
52 changes: 38 additions & 14 deletions nxpprog.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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")

Expand All @@ -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" +
Expand All @@ -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:
Expand Down Expand Up @@ -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):
Expand All @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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

Expand Down Expand Up @@ -947,29 +967,31 @@ 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))
else:
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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1057,19 +1080,20 @@ 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
elif result == str(COMPARE_ERROR):
self.dev_readline() # offset
success = False
else:
self.errexit("'%s' error" % cmd, status)
self.errexit("'%s' error" % cmd, result)

return success

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pyserial