mxli - an open source ISP programmer for NXP LPC controllers

[webserver home]
By Marc Prager (

WARNING: The author is NOT your friendly neighbour. He has harsh opinions and these opinions may be expressed here or in the program's output.

Go directly to latest release (of version 2.x)


mxli can be used on Unix-like platforms like OpenBSD, Linux, Cygwin to download program images into the FLASH memory of NXP (formerly Philips) LPC ARM devices through the ISP (in-system programming) handler of these devices. I was inspired by lpc21isp although I found necessary features not implemented or not implemented in the way I like. mxli is released under GPLv3.. I recommed to have at least a look at the Quick guide to GPLv3.
There are similar tools open source tools: Everything NOT open source is a security risk for my computer. I avoid to use such potential malware whereever possible.


Command-line tool

mxli is a pure command-line tool that can easily embeded into your makefiles, shell-scripts and IDEs. Therefore, mxli provides options to easily extract information out of the devices and redirect this information into a file or other process. It can be very verbose or it can be very silent and print only, what you need.

When looking at mxli's help, you will notice not only an enormous number of options, but also a very sophisticated style of passing information to the program. I dare to say, that you've never before worked with a program that allows such powerful, yet intuitive command-line options. For example you can specify the number 1024 as 1024, as 0x400 or as 1ki. And why should a program force you to write 12000000 instead of 12M for a crystal frequency, when we all know how easily we type a 0 in excess or forget one? Some options of mxli accept lists of tuples and you can write them down easily like for example "10@0x00,0x20@1024" for some byte ranges defined by length and starting addresses. In some cases, numbers can be replaced by symbolic names to avoid repeating the same number on the command-line or to rely on something that has to be extracted from the device. This reduces the probability of errors.

mxli tries to serve you. You tell it, what to do. Like most command line tools, mxli is the same every time you start it. There's no (hidden) state somewhere. If you use the same command line, mxli will do the same. This is very different from many a GUI application that remembers some things but not others or sets defaults that you have to change every time you start it and you can't do it in an easy and reliable way. With a command-line application, you can store as much settings as you want in a script file. You can build different wrapper scripts with different default settings around mxli, easily. mxli is a versatile component in your environment. You can't do that with GUI application. In that context, I want to cite an advice, given by Professor James Leslie Keedy in one of his lectures about operating systems:

"Provide functionality, not policy."

Command-line options are orthogonal. That means: when it comes to interpretation of command-line options, mxli's does not change the context of an option, depending on another. As an extreme example: if you decide to read the FLASH contents of a controller AND you also specify to output its serial number you will get both output to stdout with no error. There's no built in logic, that says: if you read a FLASH image, then reading serial number will corrupt the image output, so I ignore reading serial number. No. mxli does not constantly doubt the user knows, what he's doing. In general, any option A does not alter the meaning of any option B. The order of command-line options does not matter as long a you don't repeat them. Repeating an option (even with a different value) is NOT considered an error but a mechanim for overriding. Options causing actions on your LPC device are always executed in a predefined, immutable order: probe - identify device and/or boot code - read - erase FLASH - write FLASH - verify - execute program.

Free tool for professional application

mxli strives for being a powerfull and perfectly legal tool for small companies that don't want to spend money on an administrator for their licensed software. This admin's sole task is keeping track of all the licenses and to master the hurdles created by that professional (licensed) software. While I understand that a tool creator wants to get make money for his work, I personally do not understand why tool creators put their customers into the hassle associated with licence keys and binding of tools to hardware. It's like buying a DVD instead of downloading an illegal copy and then not beeing able to skip the advertizing, the warning that illegal copies do cost my money and above all, not beeing able to create a backup. Once, when I was watching a movie in the cinema, and that same warning was displayed a voice raised out of the dark and asked:

"What is an illegal copy?" He went on answering: "It's the original with the advertizing and the piracy warning removed. Only those who already paid for the original are forced to watch the advertizing and the piracy warning!"

In my opinion software needs only to be licensed, if it's not up-to-date and the vendor still wants to make money out of that b***sh*t. Write once, sell anywhere. No! So for short, mxli can be seen as an alternative to so-called 'professional' tools but without the license hassle.

mxli provides interesting features for code read protection (CRP) to protect your intellectual property, see below.

Flexibility: support for future LPC devices

mxli should be able to support devices released by NXP after the compile time of mxli. To provide that, mxli offers the possibility to define a devices memory description through command-line options. So everything you need is a new device and its data sheet and you should be able to flash it!.

Sometimes, really new features emerge. Multiple flash banks appeared in the LPC1800 family, maybe earlier. LPC800 uses a new binary (opposed to a uuencoded) data transmission protocol not seen in any of the other families before. Such new features do require a modification of mxli's code. The good new is: that doesn't happen very often.

For the same reason, mxli supports debugging output by command-line switch to find out what's going wrong if something goes wrong.

Flexibility: generic mechanisms

As already pointed out, mxli tries to provide general concepts instead of special exceptions. Other tools - as an example - provide an option to invert the control signals and another option to not use the control signals. mxli does not. Instead mxli allows you to define what you really wanted in the first place: what sequence of control signals is used to RESET a board, what sequence is used to enter the ISP handler. And other situations. And - of course - it provides a resonable default so you don't have to specify details in the most common use cases. Another generic concept is mxli's flow control mechanism. You can interrupt or delay mxli's program flow before most ISP commands. It's up to you, if you use this to slow down data transfer for an old device or use this feature to ask the user for confirmation of commands.

Code read protection

When using mxli as FLASH programmer the responsibility for code read protection (CRP) does not rest solely on the creator of the FLASH image, but also on the person who does the FLASH programming. Apart from the possibility to modify CRP levels on the command line, mxli safely prevents accidental setting CRP level 3 which might render your device/board unusable. CRP is possible, but you have to enable it explicitely.

Shared library code

This headline is misleading. I don't provide a shared library in the sense of a DLL/(.so). It's meant in a different way: the library that is used in mxli to determine memory layout and sizes and CRP can also be used for in-application programming on the target device itself! I hope this explains, why some parts of the library are built the way they are. The library has to scale well - from the tiny microcontroller up to the full blown *nix application, that knows 'all' devices.

Supported devices

At least the following families are supported by compiled-in device descriptions.

The following device families should be supported, if the user provides the memory description.

Devices tested by the author (mxli-r79).

device max baud rate crystal other options remarks
LPC812M101 230400 IRC
LPC1110 38400 IRC -R 0x200,0x100 baud may be higher (untested)
LPC1114FN28/102 115200 IRC
LPC1764/1766/1769230400 IRC
LPC2106 230400 14.7456MHz
LPC2124 14.7456MHz
LPC2132 38400 12MHz -E
LPC2136/01 38400 12MHz -E
LPC2148 12MHz


Invocation is in the most simple case (recent LPC controller, USB-to-serial converter = /dev/ttyUSB0):
$ mxli
This command tries to connect to your controller and outputs its type. If mxli times out, only then try auto-bauding. Make sure the crystal frequency is correct for devices without IRC (LPC21xx for example).
$ mxli -p
To perform flash programming, provide an image on the command line, either binary data or Intel-hex format:
$ mxli yourBinaryImage
$ mxli yourImage.hex

If you don't know, how to create such a .hex or .bin file, or you don't know how to build one you can rely on, please visit Frank's "LPC17xx ARM Cortex M3 Assembly Language Example".

If your controller is a LPC21 family member running on a 12MHz crystal and your serial device is connected to /dev/ttyS0 then your command line should look like this:

$ mxli -d/dev/ttyS0 -b38400 -c12M -E yourBinaryImage
The -E option turns on echo in ISP communication protocol. This makes mxli wait for LPC's anwers before proceeding, especially while transferring image data.

Download and compile

The source code of different versions of mxli can be downloaded below. I used to name the program "isp" until version 2.1. I noticed the need for less generic name. So I chose mxli (Marc's eXquisite LPC ISP). The following tools need to be installed on your system: After downloading, you can verify the the hash sum of the downloaded archive. (Compare to md5sum.txt).
To generate the executable, the following steps are required:
$ tar xfj mxli-2.1.tar.bz2
$ cd c-linux-mxli-2.1/lib
$ make
$ cd ../programs/mxli
$ make
This puts the executable mxli into that final directory. Simply move it to the location you want.


The author is an active member of the LPCware Forum. If you run into trouble, please post there.

Latest version - rolling release

mxli is part of my 'c-linux' project project and can be found there, too. However, c-linux is a rolling release, so that version of mxli might change unnoticed.


Added LPC13, LPC177x, LPC178x. So this version should support very well, by compiled-in IDs, the families LPC800, LPC1100, LPC1200, LPC1300, LPC1700, LPC2100. Support for other families is not that comprehensive. Use the option -S to query the supported devices.
This is a library update, so don't search for modifications (other than version info) inside mxli.c .
Released: 02/2014 Download mxli-2.3


Bug fix of mxli-2.1. Added LPC11Exx family.
Released: 02/2014 Download mxli-2.2

mxli-2.1 (isp-2.1)

This release contains the feature set I had in mind after scanning through the documentation of NXPs new families. New naming schemes, new flash segmentation/block sizes, a new transmission protocol for data, CRC-checksum, multi-bank FLASH, new CRP-mode NO_ISP forced me to change even some basic library parts.
Released: 08/2013 Download mxli-2.1-r79
Known BUGS
Download mxli-2.1-r78
Known BUGS Screenshot of mxli-2.1:
mxli 2.1 ($Rev: 79+ $) (C) Marc Prager 2011-2013.. GPLv3 license.
Marc's exquisite LPC ISP command-line programmer for NXP ARM devices.

Usage: mxli <options> [<inputFile>]
Options: (values in [] show the defaults, *=not yet implemented)
  -? or --help              : display this help screen.
  -0 <q-command-list>       : use sector 0 even for questionable operations specified
  -1                        : blank check device (= filled with all ones).
  -2 <bank>|Y               : select flash bank <bank> or from parameter -Y
  -a <destinationAddress>   : image destination address (LMA) (sector boundary!!) [0x0]
  -b <baud rate>            : communication baud rate [230400]
  -c <f crystal/Hz>         : crystal frequency [14748000]
  -d <device>               : serial device [/dev/ttyUSB0]
  -e {<sect>[..<sect>]|all} : erase FLASH sectors, or all
  -f <flashSize>            : FLASH size override
  -g                        : debugging output (in honor of gcc's option -g)
  -h <topic>                : display manual <topic>, start with "contents"
  -i                        : print member info
  -j {addr|LMA|LMA+1}       : jump to address [unset]
  -k                        : read boot code version (ISP 'K' command)
  -l <CRP level>            : lock code. Set code read protection (CRP) level [-1]
  -m <RAM size>             : RAM 0 size override
  -n                        : do not output controller as default action
  -o <imageFile>            : set image output file (instead of stdout)
  -p                        : probe baud rates and print to stdout. -q => only highest
  -q                        : quick mode: prefer speed to security/kindness
  -r <imageSize>            : read <imageSize> bytes from RAM/FLASH
  -s {960@64>|file|flash}   : calculate CRC checksum from addr 64 to <1024 | whole file | whole FLASH
  -t <time/ms>              : time mxli waits after RESET deassertion [200]
  -u                        : output UID
  -v                        : verify FLASH contents after programming
  -w                        : write to uC (default, if <inputFile> provided
  -x                        : execute by issuing RESET without BSL
  -y <sub-block size>       : binary transfer sub-block size [64]
  -z                        : zero output in case of success
  -A                        : starting address of truly readable FLASH [64]
  -B 256,512,1024,4096      : define copy-ram-to-flash block sizes to be 256,512... 
  -C <CRP address>          : address of the 4-byte CRP code [0x2FC]
  -E                        : use echo on [normally off]
  -F 4kix16,32kix14         : define FLASH sector layout to be 16x4kiB, then 14x32kiB
  -H                        * set error output handle [2][stderr]
  -I <uC ID>                : set user-defined id
  -L <CRP level>            : enable CRP level (dangerous especially for level 3) [0]
  -M 8ki@0x40000000,8ki@... : define uC RAM to be 8kiB at address 0x40000000 and ...
  -N <uC number>            : set user-defined number
  -P {UUENCODE|BINARY}      : data encoding protocol override
  -R <bottom>,<top>         : set RAM0 spaces reserved for ISP [0x270,0x120]
  -S                        : show all compiled-in devices.
  -T <time/ms>              : timeout of serial communication, step: 100ms [1000]
  -U {<uC-number>|user}     : force uC like 2101, do not use part ID.
  -V {CRC|READ}             * use verification method CRC or read & compare
  -W <waveform>             : RESET/BSL control, see -h waveforms
  -X <flow-control>         : execution flow control, see -h flow-control
  -Y <flashBank>            : FLASH multiplexing: use flashbank parameter for commands
  -Z                        : zero output, even in case of failure. (return code only)

<inputFile> can be in Intel hex-format (if named *.hex) or binary.

If your controller does not work correctly with mxli, read mxli -h troubleshooting
Try -h contents for online manual

Please report bugs to marc @


This was released to provide the first version of isp that can flash LPC800 devices although quite a few features I wanted were still missing.
Released: 07/2013

Download isp-2.0


This is the original program developed in late 2011. Not released to the puplic until March 2013.
It supports LPC2100 and LPC1700 devices from compiled in tables. Nearly all other NXP ARM LPC devices should be supported by providing command-line options. LPC800 devices are NOT supported (different ISP protocol).

Download isp-1.1

Last modified: 2014-02-06