Content
If you are working directly on OpenRex
If you are using a Linux host machine
If you are using Windows
- Setting up an IDE environment
- Preparing a binary
- Testing with iMX6 Rex
- Programming procedure with OpenRex
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
- 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
- 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.