I had some problems getting my ROV on-board controller (which uses a LPC1347) programmed from LPCXpresso.
After doing the research I should have done before I had the PCBs made (doh), I found out I had messed up the SWD programming/debugging connections.
And so, in order to spare anyone else the same trouble, here is a small recap of which wires to connect to what.
Connections from LPC11U24/LPC1347
These are the minimal connections from the MCU to the LPC-Link:
|Pin name||LQFP48 pin no.||Connect to|
|#RESET/PIO0_0||3||SWD pin 10 (#RST)|
|SWDIO/PIO0_15/AD4/ 25 CT32B1_MAT2||39||SWD pin 2|
|SWCLK/PIO0_10/SCK0/CT16B0_MAT2||29||SWD pin 4|
Note: It is not necessary to have pull-up resistor on #RESET (or any other pin) unless other parts of the circuit might affect the levels since it is internally pulled up to VDD.
Connections from JTAG/SWD
These are the minimal connections from the LPC-Link to the MCU board.
|Pin number||Connect to||LQFP48 pin no.||Comment|
|1||3.3V on MCU||8, 44|
|3||n/c||Optional GND (see note 1)|
|5||n/c||Optional GND (see note 1)|
|6||n/c||Optional SWO (see note 2)|
Note 1: It is sufficient to connect one of the GND pins (e.g. SWD pin 9) as pins 3, 5 and 9 are all connected on the LPC-Link.
Note 2: SWD pin 6 can be connected to PIO0_9/MOSI0/CT16B0_MAT1/SWO (LQFP pin 28) but this is not required.
This image shows the pin numbering on the LPC-Link. Pin 1 has been marked in red.
Do yourself a favor and perform a continuity check from the LPC-Link side to your MCU board to make sure which pins go where.
Be aware that the 0.1" pins on the right edge of the board do not follow the JTAG pin numbering but have these connections:
- EXT. PWR
The required pins are 1, 2, 3, 6 and 8.
Sometimes LPCXpresso can't initialize the LPC-Link even though it is connected. I have found that following the following procedure works every time:
- Launch LPCXpresso IDE
- Power up device
- Attach to LPC-Link
- Connect LPC-Link to computer by USB
- Debug firmware from LPCXpresso
I’ve made quite a bit of headway with the firmware for the GPS Tracker project but there are still some problems – mainly with the command parser and the USB CDC interface.
So I decided I needed some way of debugging the firmware. After looking at several options (they have to run on Mac OS X), I decided to get a LPC1347-based LPCXpresso.
The LPCXpresso consists of two parts:
- An LPC MCU with a minimal amount of support components: crystal, capacitors, an LED and a mini-USB socket with the required resistors and PNP transistor.
- The “LPC-Link” which is a programmer and JTAG debugger which connects to the computer by USB. The LPC Link can actually be severed from the MCU part of the board and will then work as a normal JTAG debugger which can be connected to MCUs (LPCXpresso or otherwise) using a 10-pin connector.
The LPCXpresso also comes with a free version of Code Red’s Eclipse-based IDE with built-in/preconfigured support for the GNU tool chain and standard C libraries and debugging views for inspecting memory and peripherals and whatnot.
I prefer the LPCXpresso to the mbed because the MCU board contains no extra components (compared to what I will use on my own boards) and all code is standard C and CMSIS libraries (so no proprietary firmware environment and libraries) – and still I have the ability to debug code and inspect memory at will.
LPC11U24 + LPC1343 –> LPC1347
The LPCXpresso is available with a number of different LPC MCUs. I chose the LPC1347-based one.
Basically, the LPC1347 is a newer version of the LPC1343 and it has the same GPIO structure as the LPC11Uxx devices and the same USB ROM drivers and it now has EEPROM as well. Read this blog entry on microBuilder.eu for a comparison between the LPC1343 and the LPC1347.
I have decided to focus on only one ARM MCU instead of both the LPC11U24 and the LPC1343 – and that will be the LPC1347 (for now at least). Yes, it has a slightly higher power consumption than the LPC11Uxx but on the other hand it is faster and has a Cortex M3 core instead of a Cortex M0 core.
So the plan is:
- Make the necessary changes to compile the current firmware code for an LPC1347 (which shouldn’t be too much of a hassle since peripherals for the LPC11U24 and the LPC1347 are pretty much the same) in the LPCXpresso IDE (removing the current linker script and CMSIS files).
- Rebuild the breadboard prototype using the LPCXpresso.
- Debug, find the problems and fix them…
For the GPS Tracker project I’ve been working on – struggling with, actually – getting all the communications subsystems working. I need to use UART for communication with the GSM module, soft UART (since the LPC11U24 has only one hardware UART port) for the GPS module and USB CDC for command and debugging.
And apart from the occasional programming blunders (like forgetting to increase a pointer when iterating elements in an array) I’ve had lots and lots of weird problems. But I finally got UART and soft UART working together and then I took a really long, hard look at the example USB CDC code I’ve been working with.
And it turned out that I needed to change a couple of things:
- The linker script (which should be for an LPC11U24 device) specified a RAM size of only 4 KB. This has been fixed to specify an SRAM size of 6 KB.
- The USB interface was initialized with a memory buffer at what was, in effect, an arbitrary place in the SRAM memory. The original code used
usb_param.mem_base = 0x10001000and
usb_param.mem_size = 0x1000.
For an LPC11U24, location 0x10001000 is at two thirds up in the SRAM area (which is from 0x1000000 to 0x10001800).
This has now been changed to use
usb_param.mem_base = 0x20004800and
usb_param.mem_size = 0x0800pointing to the top of the USB RAM area with a size of 2 KB (which is the size of the USB RAM).
USB_CDC_send()function calls the
WriteEPdirectly. This has been changed to copy data into a serial fifo buffer and calling
VCOM_bulk_in_hdlr()function when the USB host requests data. And the max packet size is also observed now.
And with these changes in place I was rewarded with the following session on the USB CDC terminal connection:
sys test OK - Response from SYS TEST sys version OK - b155 on 2012-09-02 13:34:17 +0200, git 31db1bb904695fc5347a136dbf2c819520162099 gps status OK - GPS status: 1, sats: 6/12, time: 121246.854, lat: 5538.7522N, lng: 01233.1385E
Next steps are getting the ADC working for monitoring the battery level and implementing the interface for the GSM module.
…the unabbreviated title would be very long :)
Anywho, this is just a quick post to link to my Github project which contains firmware for using an LPC11U24 as a USB "communications device" – i.e. a serial port.
At the moment, it simply writes input from the serial interface to the USB and vice versa. So you can connect the device to a computer with both USB and a serial cable (I use a serial-to-USB cable since I have no "real" serial ports on my MacBook Pro) and then open terminal connections to both interfaces (using "screen /dev/tty.xxx 9600" or something similar) and everything typed in one window gets written in the other window.
There's probably a couple of debugging messages as well.
The project is based on NXP's example code found here: http://www.lpcware.com/content/nxpfile/usb-rom-driver-examples-using-lpcxpresso-lpc11uxx and compiles with the Yagarto toolchain.
Why would I want to do USB connectivity by way of CDC instead of e.g. HID? Because implementing HID functionality in Mac OS X applications is a pain in the ass, that's why.
Serial port connectivity, however, is so very much simpler. Especially if you use the excellent ORSSerialPort library.
Right here: https://github.com/jenswilly/LPC11U24-USBCDC
Here is how to flash an LPC11U24 or LPC1343 from Mac OS X using the ROM-based USB bootloader.
This post is just code snippet-style and I'm assuming you have a compiled .bin file and have the MCU connected with a USB cable so a disk named "CRP DISABLD" appears on the desktop.
- Add the required checksum using the crc executable as described here: http://vn1k.blogspot.dk/2010/11/lpc1343-loading-binaries-using-on-chip.html
- In Terminal do
$ df -h
to identify the filesystem device that is mounted as the CRP DISABLD disk. It will be something like "/dev/disk1" (which I will use in this example).
- Unmount the disk using
$ diskutil unmount /dev/disk1
- Copy binary file to device using
$ dd if=firmware.bin of=/dev/disk1 seek=4
This is where the tricky stuff happens. In order for everything to work we must write data beginning at sector 4. And if we just copy the file in the Finder the OS will start at sector 6.
The info here is extracted from http://vn1k.blogspot.dk/2010/11/lpc1343-loading-binaries-using-on-chip.html and http://jogglerwiki.info/index.php?title=Writing_image_files_to_USB_drives