NXP Microcontroller LPC13xx programming & testing

Content

If you are working directly on OpenRex

If you are using a Linux host machine

If you are using Windows

Appendix

Editing, Compiling, Flashing LPC13xx directly on OpenRex

1) Download CodeSourcery Compiled directly for OpenRex

cd
mkdir codesourcery
cd codesourcery
wget http://www.imx6rex.com/download/released-files/openrex/v1i1/firmware/gcc-arm-none-eabi-5_2-2015q4-20151219-install-native.tar.gz
tar -zxvf gcc-arm-none-eabi-5_2-2015q4-20151219-install-native.tar.gz

2) Set PATH

export PATH=$PATH:~/codesourcery/install-native/bin

3) Test if ‘arm-none-eabi-gcc’ is recognized

cd
fedevel@ubuntu:~$ arm-none-eabi-gcc
arm-none-eabi-gcc: fatal error: no input files
compilation terminated.
fedevel@ubuntu:~$

4) Get Blinky example

cd
mkdir nxp
cd nxp
git clone -b master https://github.com/FEDEVEL/LPC1347-Blinky.git
cd LPC1347-Blinky

5) Modify LPC1347-Blinky.c, just to be sure everything works oki:

#open LPC1347-Blinky.c
nano LPC1347-Blinky.c

#modify following line
while(msTicks < (timer_mark + 1000));
#change it to
while(msTicks < (timer_mark + 100)); 

*Note: After this modification, MCU LED will be flahing every 100ms, original is set to 1s
6) Compile the code

make

Note: Check time and date of LPC1347-Blinky-CM3.bin
7) Download the software needed for LPC13xx flashing

cd
cd nxp
wget https://github.com/FEDEVEL/openrex-nxp-lpc13xx/archive/LPC1347.zip
unzip LPC1347.zip
cd openrex-nxp-lpc13xx-LPC1347/

8) FLASH the firmware

./openrex-isp-handler.sh ../LPC1347-Blinky/LPC1347-Blinky-CM3.bin

After this command, MCU LED (the red LED close to the Power Jack) should start blinking.

Setting up an IDE environment

For initial testing we used LCPXpresso board LPC1347 REV A board.

There are many ways how to start with LPCXpresso development boards. For example you can use a simple LED blinking code with FreeRTOS operating system (follow chapter 4 and 5 of PLCXpresso V7 User Guide). There is also an option to use a semihosted project and print messages in the debug environment (use first part in Hello World example).

We decided to test LED blinking as simple as possible – without an OS. This is also the way which the microcontroller will be used in an actual OpenRex board. To setup the default environment follow these steps:

1. Go to LPCXpresso download page and select installer of IDE Development Tool for your operating system

2. Install the tool (use Chapter 2 of PLCXpresso V7 User Guide if you need more info)

3. Activate the product

  • Go to menu Help -> Activate -> Create Serial number and register (Free Edition)…
  • Copy the serial number of your LPCXpresso board, press OK
  • Enter the key in the opened browser (you need to be log in)
  • Go back to LPCXpresso
  • Copy Activation code and paste it to Help -> Activate -> Activate (Free Edition)…
  • Click Next

4. Setup directory for workspace

5. Import CMSIS Library

  • Click on Import project(s) (locates on the bottom left panel)
  • Browse in the archived projects
  • Find “CMSIS_CORE_Latest.zip” in the directory tree (located in LPCXpresso_7.7.2_379\lpcxpresso\Examples\CMSIS_CORE)
  • Select only library of our chip family. Important: for LPC1347 with a 12-bit ADC you need to select CMSIS_CORE_LPC13Uxx
  • Click to finish

6. Create an empty project

  • Click on New project (locates on the bottom left corner)
  • Select MCU (LPC13 / LPC15 / LPC17 / LPC18 -> LPC13xx (12bit ADC) )
  • Choose version of project (use C Project for this example)
  • Type project name
  • Choose specific MCU (in our case LPC1347)
  • Select CMSIS-Core Library which we have imported in point 5 (CMSIS_CORE_LPC13Uxx)
  • Do not use CMSIS DSP for this example
  • Click on Finish

7. Setup binary generation

  • Click on project name on the top left corner
  • Go to Project -> Properties -> C/C++ Build -> Settings -> Build steps
  • Edit the Post-build steps
  • Uncomment (remove ‘#’ string) in the second and third column. It will look like this:
    arm-none-eabi-size "${BuildArtifactFileName}"
    arm-none-eabi-objcopy -v -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin"
    checksum -p ${TargetChip} -d "${BuildArtifactFileBaseName}.bin"
    
  • Confirm the changes

Preparing a binary file

Now we are going to generate an output binary which will be then sent into the microcontroller. At this point we have setup PLCXpresso software or opened it from the last time. Here are the steps you need to follow to prepare binary output:

1. Be sure we have opened library project for your microcontroller – for LPC1347 open CMSIS_CORE_LPC13Uxx project, for other chip from LPC13xx family apart from LPC1347, use CMSIS_CORE_LPC13xx project instead.
Follow this step if you haven’t done it yet.

2. Open an existing project (You can use this project as a starting point)

  • Go to Quickstart Panel (located on the bottom left corner) and click on Import project(s)
  • Select Project directory (unpacked) and click on Browse
  • Choose directory where an existing project is located
  • Select the project and click to Finish
  • Be sure the binary generation is enabled for this project

3. Build your project (click on Hammer in the bottom left corner). Be aware about errors during the compiling. They are not very visible and Build finished message is displayed even if they occur.

4. Test the code (only available if you have connected LPCXpresso to your PC)

  • Click on Debug (first bug in the bottom left corner)
  • Connect LPC link board (be sure you plug the USB cable to the link side and that the board are bridged – solder paste between the J4 pads are not removed)
  • Press Search for any enable emulator
  • After the LPC Link is found press OK
  • Execution is halted at the first. Press Resume (F8) to start it (green play button on the top panel)
  • LED2 on the target side should start blinking

5. Program MCU using generated binary file

  • Go to Debug directory and copy the binary file (don’t forget to check if the date of the file is correct)
  • Download prepared folder from our GitHub repository
  • Store the binary file into this unpacked directory (to transfer use e.g. USB stick of ftp transfer)
  • Run the ISP handler using this command (change the parameter for your binary name):
    	./openrex-isp-handler.sh LPC1347-userLED.bin
    	
  • MCU user LED should (D24 on OpenRex V1I1 board) now start blinking

Testing with iMX6 Rex

Before we finish designing process of OpenRex we wanted to make sure that ISP programming procces will work – we test it using our iMX6 Rex board first.

Connecting PLCXpresso with iMX6 Rex board

We connected the LPCXpresso board with iMX6 Rex Development board the following way:

iMX6 Rex LPCXpresso LPC1347
UART2_RXD (J31 pin 3) <<<< TXD (J6 pin 9)
UART2_TXD (J31 pin 5) >>>> RXD (J6 pin 10)
GPIO 2 (J34 pin 4) >>>> ISP# (J6 pin 38)
GPIO 3 (J34 pin 5) >>>> RST# (J6 pin 4)
GND (J31 pin 9) - – - - GND (J6 pin 1)
+3.3V (J31 pin 10) - – - - +3.3V (J6 pin 28)

Important: Before you start, solder pull-down resistor (e.g. 1k) between PIO0_3 (J6 pin 39) and GND.

Adding LPC13XX support into ISP software

We choose lpc21isp utility for programming NXP LPC devices. As a starting point we will use our updated version for iMX6 Rex which we have used in our previous testing.

To add support for LPC1347 we need to define a new device in lpcprog.c on line 137:

{ 0x8020543, "1347",         64,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },

Recompile the tool to apply the change:

$ make -f Makefile clean all

You can follow further changes of the project on GitHub.

Flashing a binary file using iMX6 Rex

To put RESET and ISP to LOW (don’t forget, these two signals we have connected to our GPIO expander), we used i2cset command:

$ i2cset 1 0x27 0x02 0xF3 // set GPIO 0.2 and GPIO 0.3 to low
$ i2cset 1 0x27 0x06 0xF3 // set GPIO 0.2 and GPIO 0.3 as output

Release RESET to HIGH

$ i2cset 1 0x27 0x02 0xFB // set GPIO 0.3 to high

Now the NXP is in ISP mode. Run the lpc21isp tool:

$ ./lpc21isp -bin blinky.bin /dev/ttymxc1 115200 12000
lpc21isp version 1.83
File blinky.bin:
        loaded...
        image size : 1068
Image size : 1068
Synchronizing (ESC to abort).Answer Synchronized

String:53 79 6E 63 68 72 6F 6E 69 7A 65 64 D A 0  OK
Read bootcode version: 2
5
Read part ID: LPC1347, 64 kiB ROM / 8 kiB SRAM (0x8020543)
Read Unique ID:
succeeded
Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last.
Erasing sector 0 first, to invalidate checksum. OK
Sector 0: ..........................
Download Finished... taking 0 seconds
Now launching the code

Release the board from ISP mode and go to RESET

$ i2cset 1 0x27 0x02 0xF7 // set GPIO 0.2 to high and GPIO 0.3 to low

Release RESET

$ i2cset 1 0x27 0x02 0xFF // set GPIO 0.2 and GPIO 0.3 to high

Now your new binary should be running on the NXP. We tested it with a simple blink program.

Programming procedure on OpenRex board

The programming process is very similar as we use for iMX6 Rex. The main difference with on-board MCU is that we don’t need to use any cables. ISP and Reset signal will be controlled directly by CPU. To simplify the process we created a simple shell script:

#!/bin/sh
# OpenRex ISP programmer handler
# This is a script to perform programming procedure for on-board LPC13xx microcontroller
#
# Parameters:
# $1 - relative path to binary which will be used
#
# Hardware connection:
# for communication is used UART2
# MCU_ISPn -> GPIO1_IO18 -> mapped as gpio18
ISP=18
# MCU_RSTINn -> GPIO1_IO16 -> mapped as gpio16
RST=16
#
# Initialize GPIO pins
echo $RST > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio$RST/direction
echo 1 > /sys/class/gpio/gpio$RST/value

echo $ISP > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio$ISP/direction
echo 1 > /sys/class/gpio/gpio$ISP/value

echo 0 > /sys/class/gpio/gpio$ISP/value # set ISP to low
echo "ISP low"
sleep 0.01
echo 0 > /sys/class/gpio/gpio$RST/value # set RST to low
echo "RST low"
sleep 0.01
echo 1 > /sys/class/gpio/gpio$RST/value # release reset - start ISP routine
echo "RST released"
sleep 0.01

./lpc21isp -bin $1 /dev/ttymxc1 115200 12000

echo 0 > /sys/class/gpio/gpio$RST/value # set RST to low
echo "RST low"
sleep 0.01
echo 1 > /sys/class/gpio/gpio$ISP/value # set ISP to low
echo "ISP high"
echo in > /sys/class/gpio/gpio$ISP/direction
sleep 0.01
echo 1 > /sys/class/gpio/gpio$RST/value # release reset - start ISP routine
echo "RST released"

Save it and update the permission:

chmod 777 openrex-isp-handler.sh

Now you can program the binary into the MCU using a single command:

./openrex-isp-handler.sh LPC1347-userLED.bin

Building LPC13xx code on an x86 Linux machine

Install CodeSourcery from: https://launchpad.net/gcc-arm-embedded/+download

wget https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2
tar xjf gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2
export PATH=$PATH:$install_dir/gcc-arm-none-eabi-*/bin
arm-none-eabi-gcc

*Note: update the PATH according to your installation directory

Test if you can access the compiler. You should see something like this

cd
fedevel@ubuntu:~$ arm-none-eabi-gcc
arm-none-eabi-gcc: fatal error: no input files
compilation terminated.
fedevel@ubuntu:~$

Create a directory

cd
mkdir nxp
cd nxp

Get a simple Blinky example

git clone -b master https://github.com/FEDEVEL/LPC1347-Blinky.git
cd LPC1347-Blinky

To compile the code, use “make”. Here is what you should see:

fedevel@ubuntu:~/nxp/LPC1347-Blinky$ make
arm-none-eabi-gcc LPC1347-Blinky.c lpc1300/system_LPC13Uxx.c startup/startup_ARMCM3.S -mthumb -mcpu=cortex-m3 -D__STARTUP_CLEAR_BSS -D__START=main -DTARGET_LPC13XX -Os -flto -ffunction-sections -fdata-sections -Ilpc1300 --specs=nano.specs -lc -lc -lnosys -L. -L.//ldscripts -T gcc.ld -Wl,--gc-sections -Wl,-Map=LPC1347-Blinky.map -o LPC1347-Blinky-CM3.axf
In file included from lpc1300/LPC13Uxx.h:102:0,
                 from LPC1347-Blinky.c:1:
lpc1300/core_cm3.h: In function '__ISB':
lpc1300/core_cm3.h:789:22: warning: type of 'arg' defaults to 'int' [-Wimplicit-int]
 static __INLINE void __ISB(arg)                   { __ASM volatile ("isb");   }
                      ^
lpc1300/core_cm3.h: In function '__DSB':
lpc1300/core_cm3.h:790:22: warning: type of 'arg' defaults to 'int' [-Wimplicit-int]
 static __INLINE void __DSB(arg)                   { __ASM volatile ("dsb");   }
                      ^
lpc1300/core_cm3.h: In function '__DMB':
lpc1300/core_cm3.h:791:22: warning: type of 'arg' defaults to 'int' [-Wimplicit-int]
 static __INLINE void __DMB(arg)                   { __ASM volatile ("dmb");   }
                      ^
In file included from lpc1300/LPC13Uxx.h:102:0,
                 from lpc1300/system_LPC13Uxx.c:27:
lpc1300/core_cm3.h: In function '__ISB':
lpc1300/core_cm3.h:789:22: warning: type of 'arg' defaults to 'int' [-Wimplicit-int]
 static __INLINE void __ISB(arg)                   { __ASM volatile ("isb");   }
                      ^
lpc1300/core_cm3.h: In function '__DSB':
lpc1300/core_cm3.h:790:22: warning: type of 'arg' defaults to 'int' [-Wimplicit-int]
 static __INLINE void __DSB(arg)                   { __ASM volatile ("dsb");   }
                      ^
lpc1300/core_cm3.h: In function '__DMB':
lpc1300/core_cm3.h:791:22: warning: type of 'arg' defaults to 'int' [-Wimplicit-int]
 static __INLINE void __DMB(arg)                   { __ASM volatile ("dmb");   }
                      ^
arm-none-eabi-objcopy -O binary LPC1347-Blinky-CM3.axf LPC1347-Blinky-CM3.bin
fedevel@ubuntu:~/nxp/LPC1347-Blinky$

To copy the file to OpenRex, we will use TFTP. First, copy it to the host /tftp folder

cp LPC1347-Blinky-CM3.bin /tftp/

Go to OpenRex and download the binary. Use IP address of your host computer.

root@ubuntu-imx6:~/openrex-nxp-lpc13xx-LPC1347# tftp 192.168.0.74
tftp> get LPC1347-Blinky-CM3.bin
Received 430 bytes in 0.0 seconds
tftp> quit
root@ubuntu-imx6:~/openrex-nxp-lpc13xx-LPC1347#

Flash the binary and watch if the LED starts blinking

root@ubuntu-imx6:~/openrex-nxp-lpc13xx-LPC1347# ./openrex-isp-handler.sh LPC1347-Blinky-CM3.bin
ISP low
RST low
RST released
lpc21isp version 1.83
File LPC1347-Blinky-CM3.bin:
        loaded...
        image size : 428
Image size : 428
Synchronizing (ESC to abort).Answer Synchronized

String:53 79 6E 63 68 72 6F 6E 69 7A 65 64 D A 0  OK
Read bootcode version: 2
5
Read part ID: LPC1347, 64 kiB ROM / 8 kiB SRAM (0x8020543)
Read Unique ID:
succeeded
Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last.
Erasing sector 0 first, to invalidate checksum. OK
Sector 0: ..............
Download Finished... taking 0 seconds
Now launching the code
RST low
ISP high
RST released
root@ubuntu-imx6:~/openrex-nxp-lpc13xx-LPC1347#

Done! The RED LED close to the Power jack should start blinking in approximately 1s interval.

Appendix – How to compile LPC13xx compiler (toolchain) for ARM

To be able to compile source codes for LPC13xx directly on OpenRex, you will need “gcc-arm-none-eabi” compiled for ARM. You can download the one I have compiled here (and follow the steps here), or you can try to compile it by yourself. Important! It takes a long time (over 10 hours) to compile the gcc-arm-none-eabi on OpenRex. It is recommended to use a SATA drive.

1) Prepare the filesystem

I used the filesystem, described here: Using a downloaded filesystem (supports apt-get command) >

2) Install common tools and libraries

sudo apt-get update
sudo apt-get install python2.7-dev
sudo apt-get install apt-src \
scons \
mingw32-runtime \
p7zip-full \
gawk \
gzip \
perl \
autoconf \
m4 \
automake \
libtool \
libncurses5-dev \
gettext \
gperf \
dejagnu \
expect \
tcl \
autogen \
flex \
flip \
bison \
tofrodos \
texinfo \
g++ \
gcc-multilib \
libgmp3-dev \
libmpfr-dev \
debhelper \
texlive \
texlive-extra-utils

3) Download the compiler source code

To be able to compile LPC13xx, you need gcc-arm-none-eabi compiler. The source code can be found at: GCC ARM Embedded – Pre-built GNU toolchain from ARM Cortex-M & Cortex-R processors (Cortex-M0/M0+/M3/M4/M7, Cortex-R4/R5/R7). Here are the files I was using: GCC ARM Embedded 5-2015-q4-major. You may want to have a look at readme.txt and How-to-build-toolchain.pdf

cd
mkdir codesourcery
cd codesourcery
wget https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-src.tar.bz2

4) Unpack it

tar -xjf gcc-arm-none-eabi-5_2-2015q4-20151219-src.tar.bz2
cd gcc-arm-none-eabi-5_2-2015q4-20151219/src
find -name '*.tar.*' | xargs -I% tar -xf %
cd ..

5) Prepare to build prerequisites

Now, this is the tricky part. In case you start building the prerequisites, you will notice a lot of errors. To go around it, we will download the latest versions of the problematic packages and replace them in the src directory. It’s not the correct way to do it, but it is quick, simple and it does the job:

cd ~/codesourcery
wget http://www.bastoul.net/cloog/pages/download/count.php3?url=./cloog-0.18.4.tar.gz
wget http://downloads.sourceforge.net/project/expat/expat/2.1.1/expat-2.1.1.tar.bz2
wget https://gmplib.org/download/gmp/gmp-6.1.0.tar.bz2
wget ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz
wget http://www.mpfr.org/mpfr-current/mpfr-3.1.4.tar.bz2

If needed, rename the files, so the names of the files look nice:

mv count.php3\?url\=.%2Fcloog-0.18.4.tar.gz cloog-0.18.4.tar.gz

*Note: If some links are not available anymore, try to find the latest version or download the files from our server:

wget http://www.imx6rex.com/rex-uploads/cloog-0.18.4.tar.gz
wget http://www.imx6rex.com/rex-uploads/expat-2.1.1.tar.bz2
wget http://www.imx6rex.com/rex-uploads/gmp-6.1.0.tar.bz2
wget http://www.imx6rex.com/rex-uploads/mpc-1.0.3.tar.gz
wget http://www.imx6rex.com/rex-uploads/mpfr-3.1.4.tar.bz2

Backup the old packages:

cd ~/codesourcery/gcc-arm-none-eabi-5_2-2015q4-20151219/src
mkdir tmp
cp -prv cloog-0.18.1 tmp/
cp -prv expat-2.0.1 tmp/
cp -prv gmp-4.3.2 tmp/
cp -prv mpc-0.8.1 tmp/
cp -prv mpc-0.8.1 tmp/
cp -prv mpfr-2.4.2 tmp/

Now, delete the old packages and copy there the new versions:

cd ~/codesourcery/
#
rm -rf gcc-arm-none-eabi-5_2-2015q4-20151219/src/cloog-0.18.1/*
tar -zxvf cloog-0.18.4.tar.gz
cp -prv cloog-0.18.4/* gcc-arm-none-eabi-5_2-2015q4-20151219/src/cloog-0.18.1/
#
rm -rf gcc-arm-none-eabi-5_2-2015q4-20151219/src/expat-2.0.1/*
 tar -xvf expat-2.1.1.tar.bz2
cp -prv expat-2.1.1/* gcc-arm-none-eabi-5_2-2015q4-20151219/src/expat-2.0.1/
#
rm -rf gcc-arm-none-eabi-5_2-2015q4-20151219/src/gmp-4.3.2/*
tar -xvf gmp-6.1.0.tar.bz2
cp -prv gmp-6.1.0/* gcc-arm-none-eabi-5_2-2015q4-20151219/src/gmp-4.3.2/
#
rm -rf gcc-arm-none-eabi-5_2-2015q4-20151219/src/mpc-0.8.1/*
tar -zxvf mpc-1.0.3.tar.gz
cp -prv mpc-1.0.3/* gcc-arm-none-eabi-5_2-2015q4-20151219/src/mpc-0.8.1/
#
rm -rf gcc-arm-none-eabi-5_2-2015q4-20151219/src/mpfr-2.4.2/*
tar -xvf mpfr-3.1.4.tar.bz2
cp -prv mpfr-3.1.4/* gcc-arm-none-eabi-5_2-2015q4-20151219/src/mpfr-2.4.2/

6) Build prerequisites

cd ~/codesourcery/gcc-arm-none-eabi-5_2-2015q4-20151219
./build-prerequisites.sh --skip_steps=mingw32

7) Build the toolchain

./build-toolchain.sh --skip_steps=mingw32

8) Try it

Download LPC1347 Blinky example:

cd
mkdir nxp
cd nxp
git clone -b master https://github.com/FEDEVEL/LPC1347-Blinky.git
cd LPC1347-Blinky

Modify LPC1347-Blinky.c, so you can see the difference in LED flashing frequency:

#open LPC1347-Blinky.c
nano LPC1347-Blinky.c
 
#modify following line
while(msTicks < (timer_mark + 1000));
#change it to
while(msTicks < (timer_mark + 100)); 

Set the PATH to compiler:

export PATH=$PATH:~/codesourcery/gcc-arm-none-eabi-5_2-2015q4-20151219/install-native//bin

Compile the code:

make

Download the software needed for LPC13xx flashing:

cd
cd nxp
wget https://github.com/FEDEVEL/openrex-nxp-lpc13xx/archive/LPC1347.zip
unzip LPC1347.zip
cd openrex-nxp-lpc13xx-LPC1347/

FLASH the firmware:

./openrex-isp-handler.sh ../LPC1347-Blinky/LPC1347-Blinky-CM3.bin

After this command, MCU LED (the red LED close to the Power Jack) should start blinking.