Skip to content

Commit 15c9f34

Browse files
committed
moved from chip models to lpctools config file
updating readme fixed __init__ Update README.md Delete LICENSE Create LICENSE
1 parent caa5979 commit 15c9f34

10 files changed

+165
-172
lines changed

ISPProgrammer/ISPChip.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ def ClearBuffer(self):
8080
self.frame.clear()
8181

8282
def Read(self):
83-
self.DataBufferIn.extend(self.iodevice.ReadAll())
83+
data_in = self.iodevice.ReadAll()
84+
#if len(data_in):
85+
# print(data_in.decode("utf-8"))
86+
self.DataBufferIn.extend(data_in)
8487

8588
def ReadFrame(self):
8689
'''

ISPProgrammer/LPC175_6x.py

-40
This file was deleted.

ISPProgrammer/LPC80x.py

-27
This file was deleted.

ISPProgrammer/LPC84x.py

-39
This file was deleted.

ISPProgrammer/NXPChip.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ class NXPChip(ISPChip):
6363
"CRP3" : 0x43218765,
6464
}
6565

66+
def __init__(self, *args, **kwargs):
67+
super().__init__(*args, **kwargs)
68+
self.CrystalFrequency = 12000#khz == 30MHz
69+
self.SectorCount = 0
70+
self.RAMSize = 0
71+
self.RAMRange = 0
72+
self.FlashRange = 0
73+
self.RAMStartWrite = 0
74+
self.kCheckSumLocation = 7 #0x0000001c
75+
6676
@classmethod
6777
def GetErrorCodeName(cls, code : int) -> str:
6878
code = int(code)
@@ -326,7 +336,6 @@ def InitConnection(self):
326336
self.ClearBuffer()
327337
except TimeoutError:
328338
pass
329-
self.CheckPartType()
330339
uid = self.ReadUID()
331340
print("Part UID: %s"%uid)
332341
bootCodeVersion = self.ReadBootCodeVersion()
@@ -404,12 +413,6 @@ def SetCrystalFrequency(self, frequency_khz : int):
404413
raise UserWarning("Verification Failure")
405414

406415

407-
def CheckPartType(self):
408-
PartID = self.ReadPartID()
409-
if(PartID not in self.PartIDs):
410-
raise UserWarning("%s recieved 0x%08x"%(self.ChipName, PartID))
411-
print("Part Check Successful, 0x%08x"%(PartID))
412-
413416
def CheckFlashWrite(Data, FlashAddress : int):
414417
'''
415418
Read Memory and compare it to what was written

ISPProgrammer/__init__.py

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
from .ISPChip import *
22
from .NXPChip import NXPChip
3-
from .LPC80x import LPC80x
4-
from .LPC84x import LPC84x
5-
from .LPC175_6x import LPC175_6x

LICENSE

+20-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
/*
2-
* ----------------------------------------------------------------------------
3-
* "THE BEER-WARE LICENSE" (Revision 42):
4-
* <[email protected]> wrote this file. As long as you retain this notice you
5-
* can do whatever you want with this stuff. If we meet some day, and you think
6-
* this stuff is worth it, you can buy me a beer in return.
7-
* ----------------------------------------------------------------------------
8-
*/
1+
MIT License
92

3+
Copyright (c) 2020 Simon Hobbs
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+24-4
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,38 @@ ISP Programmer for NXP Cortex-M Chips
33

44
Command line programmer for the NXP ISP interface.
55

6+
## Features
7+
### Secure Write
8+
The checksum in flash is written to zero as the first write, so if the upload
9+
fails the chip will boot back into the ISP mode.
10+
The image is then written from the top most page down to the first page.
11+
The first sector contains the valid image checksum so a failed write will
12+
keep the device in ISP mode instead of just being bricked.
13+
614
## Chip Families Supported:
715
LPC84x
8-
LPC804
16+
LPC80x
17+
18+
NXP chips with 1kB sector sizes should work by adding their information to the
19+
lpctools_parts.def configuration file.
20+
21+
The configuration file is identical to that used by the lpctools project
22+
<http://git.techno-innov.fr/?p=lpctools>
923

1024
## Usage
1125

12-
Erase Entire Flash: ISPProgrammer -c LPC845 masserase -d /dev/ttyUSB0
13-
Program Flash: ISPProgrammer -c LPC804 writeimage --imagein blinky804.hex -d /dev/ttyUSB0
14-
Read Chip Info: ISPProgrammer -c LPC844 querychip -d /dev/ttyUSB0
26+
Erase Entire Flash: ISPProgrammer --device /dev/ttyUSB0 -b 9600 -crystal_frequency 12000 masserase
27+
Program Flash: ISPProgrammer --device /dev/ttyUSB0 -b 9600 -crystal_frequency 12000 writeimage --imagein blinky804.hex
28+
Read Chip Info: ISPProgrammer --device /dev/ttyUSB0 -b 9600 -crystal_frequency 12000 querychip
1529

1630
## Installation
1731
NXPISP is a python3 package and can be installed using pip.
32+
Clone the repository, enter the directory with setup.py in it and run
33+
pip install .
34+
The default location for the configuration file is at /etc/lpctools_parts.def.
35+
The file can either be copied there or the path passed in when calling the tool
36+
with the --config_file/-f flag.
1837

1938
1. cd NXPISP
2039
2. pip install .
40+
3. cp lpctools_parts.def /etc

bin/ISPProgrammer

+67-43
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
#!/usr/bin/env python3
2-
from ISPProgrammer import LPC80x, LPC84x, LPC175_6x, MockUart, UartDevice
2+
from ISPProgrammer import MockUart, UartDevice, NXPChip
33
import click
4+
from timeout_decorator import TimeoutError
45

5-
INSTALLED_FAMILIES = (
6-
LPC80x,
7-
LPC84x,
8-
LPC175_6x
9-
)
106
BAUDRATES = (
117
9600,
128
19200,
@@ -16,65 +12,93 @@ BAUDRATES = (
1612
230400,
1713
460800
1814
)
19-
DEFAULT_BAUD = BAUDRATES[3]# breaks with 115200
20-
21-
CHIPS = []
22-
for family in INSTALLED_FAMILIES:
23-
CHIPS.extend(family.Family)
24-
2515
@click.group()
26-
def gr1():
27-
pass
16+
@click.option('--device', '-d', default='/dev/ttyUSB0', help='Serial device')
17+
@click.option('--baud', '-b', type = int, default=9600, help='Baudrate')
18+
@click.option('--crystal_frequency', '-c', type = int, default=12000, help="Crystal frequency of chip in khz")
19+
@click.option('--config_file', '-f', default='/etc/lpctools_parts.def', help='Parts definition file')
20+
@click.pass_context
21+
def gr1(ctx, **kwargs):
22+
ctx.ensure_object(dict)
23+
ctx.obj.update(kwargs)
2824

25+
def ReadChipFile(fname):
26+
data = []
27+
with open(fname, 'r') as f:
28+
for line in f:
29+
if line.strip()[0] == '#':
30+
continue
31+
elif len(line.strip()) == 0:
32+
continue
33+
data.append(line.split(","))
34+
return data
2935

30-
def SetupChip(chipname, device = "/dev/ttyUSB0"):
31-
chip = None
32-
for ChipFamily in INSTALLED_FAMILIES:
33-
if chipname in ChipFamily.Family:
34-
#iodevice = MockUart(device, baudrate = ChipFamily.MAXBAUDRATE)
35-
iodevice = UartDevice(device, baudrate = ChipFamily.MAXBAUDRATE)
36-
chip = ChipFamily(iodevice)
37-
break
38-
if(chip is None):
39-
raise UserWarning("Chip %s unknown"%chipname)
36+
def GetPartDescriptor(fname, partid):
37+
entries = ReadChipFile(fname)
38+
for entry in entries:
39+
if partid == int(entry[0], 0):
40+
return entry
4041

42+
def SetupChip(baudrate, device, crystal_frequency, chip_file):
43+
#print(baudrate, device, crystal_frequency, chip_file)
44+
iodevice = UartDevice(device, baudrate = baudrate)
45+
chip = NXPChip(iodevice)
4146
chip.InitConnection()
42-
print("Initiated %s"%chipname)
43-
chip.ChangeBaudRate(chip.MAXBAUDRATE)
44-
print("Setup chip Baudrate set to:", chip.MAXBAUDRATE)
47+
while True:
48+
try:
49+
part_id = chip.ReadPartID()
50+
break
51+
except TimeoutError:
52+
pass
53+
descriptor = GetPartDescriptor(chip_file, part_id)
54+
if(descriptor is None):
55+
raise UserWarning("Warning chip %s not found in file %s"%(hex(part_id), chip_file))
56+
57+
print(part_id, descriptor[1])
58+
chip.CrystalFrequency = 12000#khz == 30MHz
59+
chip.SectorCount = int(descriptor[4])
60+
chip.RAMSize = int(descriptor[7], 0)
61+
62+
ramstart = int(descriptor[6], 0)
63+
chip.RAMRange = (ramstart, ramstart + chip.RAMSize - 1)
64+
65+
flashstart = int(descriptor[2], 0)
66+
flashsize = int(descriptor[3], 0)
67+
chip.FlashRange = (flashstart, flashstart + flashsize - 1)
68+
69+
ram_buffer_offset = int(descriptor[8], 0)
70+
chip.RAMStartWrite = ramstart + ram_buffer_offset
71+
chip.kCheckSumLocation = 7 #0x0000001c
4572

73+
assert(chip.RAMRange[1]-chip.RAMRange[0] == chip.RAMSize - 1)
4674
return chip
4775

48-
@click.option('--device', '-d', type = str, default = "/dev/ttyUSB0", help='Serial Device, defaults to /dev/ttyUSB0')
49-
@click.option('--chipname', '-c', type = click.Choice(CHIPS), required = True, help='Chip Type')
5076
@gr1.command()
51-
def QueryChip(device, chipname):
52-
chip = SetupChip(chipname, device)
77+
@click.pass_context
78+
def QueryChip(ctx):
79+
chip = SetupChip(ctx.obj['baud'], ctx.obj['device'], ctx.obj['crystal_frequency'], ctx.obj['config_file'])
5380

54-
@click.option('--device', '-d', type = str, default = "/dev/ttyUSB0", help='Serial Device, defaults to /dev/ttyUSB0')
55-
@click.option('--chipname', '-c', type = click.Choice(CHIPS), required = True, help='Chip Type')
5681
@gr1.command()
57-
def MassErase(device, chipname):
58-
chip = SetupChip(chipname, device)
82+
@click.pass_context
83+
def MassErase(ctx):
84+
chip = SetupChip(ctx.obj['baud'], ctx.obj['device'], ctx.obj['crystal_frequency'], ctx.obj['config_file'])
5985
chip.MassErase()
6086
print("Mass Erase Successful")
6187

62-
@click.option('--device', '-d', type = str, default = "/dev/ttyUSB0", help='Serial Device, defaults to /dev/ttyUSB0')
63-
@click.option('--chipname', '-c', type = click.Choice(CHIPS), required = True, help='Chip Type')
6488
@click.option('--imagein', type = str, required = True, help='Location of hex file to program')
6589
@gr1.command()
66-
def WriteImage(device, chipname, imagein):
67-
chip = SetupChip(chipname, device)
90+
@click.pass_context
91+
def WriteImage(ctx, imagein):
92+
chip = SetupChip(ctx.obj['baud'], ctx.obj['device'], ctx.obj['crystal_frequency'], ctx.obj['config_file'])
6893
chip.WriteImage(imagein)
6994
#chip.Go(0, ThumbMode=False)
7095
chip.Go(0, ThumbMode=True)
7196

72-
@click.option('--device', '-d', type = str, default = "/dev/ttyUSB0", help='Serial Device, defaults to /dev/ttyUSB0')
73-
@click.option('--chipname', '-c', type = click.Choice(CHIPS), required = True, help='Chip Type')
7497
@click.option('--imageout', type = str, required = True, help='Name of hex file output')
7598
@gr1.command()
76-
def ReadImage(device, chipname, imageout):
77-
chip = SetupChip(chipname, device)
99+
@click.pass_context
100+
def ReadImage(ctx, imageout):
101+
chip = SetupChip(ctx.obj['baud'], ctx.obj['device'], ctx.obj['crystal_frequency'], ctx.obj['config_file'])
78102
chip.ReadImage(imageout)
79103

80104
if __name__ == "__main__":

0 commit comments

Comments
 (0)