There has been a lot of questions in the forum about just how easy it would be to move forward from an mbed Microcontroller to actually use the target MCU (NXP LPC1768), avoiding the need to design in £30+ modules
Before showning just how easy it can be, there are a couple of points to make clear:
You can use the mbed libraries commercially for free, on an unsupported as-is basis
The mbed compiler generates a raw binary targetting the MCU, there is no bootloader magic going on inthe binary
The binary runs on the LPC1768 bare metal, there is no runtime environment
The only magic taking place on the mbed Microcontroller is the "mbed Interface" - It's not actually all that magic, it is just a USB device that can program the raw binary into the LPC1768s flash memory
So with that in mind it should be clear that if you wish to take your design to the next stage you can spin your own PCB, solder down the LPC1768 and reuse the binary you made with your mbed Microcontroller prototype, you can.
The purpose is to show you how you can get your binary into the LPC1768 on your own PCB, and what other things you can do.
mbed Prototype
The first thing to do is write a (very) simple program that prints "hello world!" to hyperterminal, and flashes and LED forever. I'll do this on an mbed module first, and then attempt to port it to an LPC1768 on an custom PCB.
I'm driving both ends of the LED as I have a PCB for an LPC1768 that i can port the binary to as an experiment, and doing the double ended driving is the simplest way.
#include "mbed.h"
Serial pc (USBTX,USBRX);
DigitalOut ledA(p26);
DigitalOut ledK(p24);
int main() {
pc.printf("Hello world!\n");
ledK = 0;
while(1) {
ledA = 1;
wait(0.2);
ledA = 0;
wait(0.2);
}
}
The source code
The teraterm output
The board with it's LED blinking away
Custom PCB
I have a PCB that my brother has spun for an mbed project (programmable access controller). I have put down an LPC1768 and just enough passive to get it running. We'll now see the steps to go through to get the binary that developmed on the mbed prototype running on this LPC1768.
Programming the LPC1768 (theory)
There are two ways to get a binary into the LPC1768; JTAG and the In System Programming (ISP) over a UART using the LPC1768s built-in serial bootloader.
The JTAG method is what you will find on a lot of development boards. It offers many additional features (debug, semihosting, etc) as well as just the ability to load the binary image. Using the JTAG port requires a JTAG "wiggler" to drive the JTAG interface, and some software that knows how to communicate over JTAG and load the binary.
The other method is ISP using the LCP1768 bootlaoder, which relies on a simple strategy:
Pull nReset low to put the LPC1768 into reset
Pull the ISP pin (P0.14) low, to indicate the ISP is intended
Pull nReset high. The LPC1768 comes out of reset and samples the ISP pin. If it is low, the bootloader runs
The bootloader communicates over a serial connection on UART0: TXD0 = p0.2 = pin 98 ; RXD0 = p0.3 - pin 99
With a level shifter you can quite happily connect to it from your computers COM port and use teraterm to type commands to it and see the reply, or use some software to communicates and download binaries.
The bootloader software uses a series of commands to query the device status, erase, transfer and program binary data to the LPC1768's flash memory. The process is well documented :
Life is too short to craft your own way to transferring data by talking to the LPC1768's built in bootloader. Thankfully there are some great apps out there which will do it for you. For the purpose of this example I am using Flash Magic:
The first stop is to get the LPC1768 on the custom PCB into ISP mode, and communicate with it.
Communicating with the LPC1768
To bridge control the pins, and bridge the bootloader serial port to my PC, I will use my mbed as a serial passthrough and to drive the ISP and nReset pins. I'll refer to this arrangement as mbedISP.
Use GPIO pins (p29,p30) of my mbed to manipulate the nReset and ISP pins on the custom PCB
Use a serial port (p28,p27) to connect to the bootloader serial port on the LPC1768
Use the USB serial port to communicate with the PC, and simply pass characters back and forth between the LPC1768 and the PC via the mbed - Think of it as USB -> RS232+Levelshifter ... and then some..
As the nReset and ISP pins have pullups, they should be driven with an open collector. I will mimic this by using a DigitalInOut, driving as an output of value 0, or as an input with no pull-up.
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
Serial pc (USBTX,USBRX);
Serial target (p28,p27);
// We'll drive this low, and then set the as inputs
// this mimics an open collector style ouput
DigitalInOut reset (p29);
DigitalInOut isp (p30);
int main() {
pc.baud(19200);
target.baud(19200);
// ISP Input with pullup
isp.input();
isp.mode(PullUp);
// pulse reset low
reset.output();
reset = 0;
wait (0.01);
// reset input, with pullup
reset.input();
reset.mode(PullUp);
while (!pc.readable()) {}
// pull ISP and nReset low
reset.output();
isp.output();
reset = 0;
isp = 0;
wait (0.1);
// Bring target out of reset
reset.input();
reset.mode(PullUp);
wait (0.1);
while (1) {
if (pc.readable()) {
target.putc(pc.getc());
led1 = !led1;
}
if (target.readable()) {
pc.putc(target.getc());
led2 = !led2;
}
}
}
Below is a wiring table of the four pins to go from the mbed to the LPC1768. the two devices must also share a common ground.
I should be able to type in ISP commands from the LPC1768 manual listed above, and get the expected response. I'll start simple by sending the "?" character which is for autobaud detection - the LPC1768 should reply "Synchronized".
Connections to the Custom PCB - A header might be better!
Hooked up to mbedISP
First attempt, and it works better than I'd hoped for. I sent the "?", and immediately got "Synchronized"
I followed the manual, so sent back "Synchronized", recieved "OK", sent back "OK", and I was then free to play
I kept it simple, I run commands J (to get the part ID) and K (to get the booloader version.
Part ID 369162533
Bootloader v3.3
I'm happy with that!
Downloading a binary
I can now communicate with the LPC1768 in bootloader mode, so it is now time to see if I can use FlashMagic to do the comms for me.
I have flash magic installed, it is a nice looking tool, but the first thing I notice is that it only support .HEX files, whereas the mbed compiler only generates .BIN files.
One quick google later, and a rather useful page appears about a BIN2HEX utility
I download the zipfile, extract it into C:\prototype then copy the binary I made earlier "prototype.bin". The first thing I notice is that when I try to convert this, it says it can't open the file, even though I autocompleted the file name. I think this has something to dowith 8.3 files names, so I rename my binary to "ptype.bin" and it works a treat.
I now have "ptype.hex" to load into Flash Magic, so lets go back to Flash Magic...
Flash Magic loads and there are a few things to configure, namely :
Device : LPC1768
COM port : COM3 (my mbedISP)
Baud rate : This was set in the mbedISP code as 19200
Hex file : Load the one I just created.
Before I try and download the binary, I notice there are some options, like read Device ID, so as a test i'll try that first. Bingo. It works! :
The interesting thing here is that it reports the bootloader version I got earlier and the Device ID as a hex number (0x1600f925). before I got 369162533 as a decimal... which happen to match.
Great, I am clearly communicating happily with the LPC1768 from Flash Magic.
Nothing left but to download... Phut!
It is complaining that the device signature does not match the expected. On closer inspection, it looks like I have actually soldered down an LPC2368 not an LPC1768 - the danger of having two almost identical parts to hand. No worries though. I go back to the compiler, and rebuild "prototype.bin", this time selecting the LPC2368 target - You've got to love the way you can choose which architecture to build your binary for with a dropdown menu. Instead of saving it to my mbed, I put it in "c\prototype" saving it as "ptype.bin", go back to my Command Prompt ("DOS", for the over 25's), and re-run BIN2HEX.
I reset the mbedISP so that it again awaiting the first character, and go back to Flash Magic, select the target as LPC2368 and try again.
Hurrah! Flash Magic runs through cleanly with no reported problems. I insert the LED into the two adjacent holes that connect to LPC1768 pins 74,75 (DIP pins p24,p26)....
Picture of the setup
Just to prove it really is blinking
The next thing you'll have noticed is that when prototyping we relied on the USB serial port for printing "Hello world". On the mbed microcontroller, when you print to USB, what you are actually doing is printing to UART0; this connects to the "mbed Interface" which routes it over USB. Now we are on a custom PCB, we dont have the interface to do that, but what we now have is printf coming out on the UART we're using for bootload. This means that any printfs in your prototype code now come out of your LPC1768 UART0, into the mbed ISP and get routed over it's USB serial. In short, you still have printf debug over USB :-)
We're not quite there
So while playing with it, I have noticed a few things that are annoying, or could work better. The mbedISP controlling ISP and nReset seemed like a good idea, but it really isnt, for a few reasons;
the while(1) loop doesn't know download has stopped, so I have to reset manually. Could be solved with a timeout, but it still feels likeI don't have the control I want.
My program is doing "printf" out of the UART as the first thing. When the mbedISP, goes through some reset cycles half this this gets printed, which interferes with the ISP communication. This means I can't ISP program it again easily, which means I cant erase it to remove the problem. I had to do some manual ISP in Teraterm to recover :-(
Once I have reset, the only way to see output it to send a character first (the program is waiting for a "?" from the host before resetting) and going into ISP mode
The simplifications needed seem obvious. Make ISP and nReset manual with a couple of push buttons, and turn mbedISP into a simple serial passthrough. To put the LPC1768 in ISP mode, press and release nReset while ISP is held low.
This is the code and setup for mbedISP
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
Serial pc (USBTX,USBRX);
Serial target (p28,p27);
int main() {
pc.baud(9600);
target.baud(9600);
while (1) {
if (pc.readable()) {
target.putc(pc.getc());
led1 = !led1;
}
if (target.readable()) {
pc.putc(target.getc());
led2 = !led2;
}
}
}
The code
The new wiring
This is all working very nicely. Now if have access to the nReset and ISP, I can reset the LPC1768 as much as I want, and put it into ISP as I want.
The only think to look at now is the speed - it takes forever to download (45 seconds). So if I now chage my prototype program to set the serial port to say 115,200bps and set the mbedISP to do run both serial ports at this speed, we might be able to reduce theprogramming time, and make printf faster.
Lets try...
Wheesh... I can read the Device ID of the part at 115,200.. it is rather responsive :-)
Wheesh... Downloading in about 6 seconds
The prototype app is now printing "Hello world" pretty quickly too!
Lets see if it will go faster (230,400)... Phut... no.. looks like 115,200bps is as fast as we can go. Still, thats not too shabby.
Hardware convention
To connect to an LPC1768 on a custom PCB we need to connect to:
Gnd
ISP (P2.10)
nReset
TXD0
RXD0
I think we should assume that the target system must provide it's own power. This is a safe way to do it as then we dont have to make any assumptions about it's voltage or current consumption.
I have had a quick look around for a standard ISP pin header (I thought there was a 2x3 one at some point). If not I'd like to propose that anyone wishing to expose an ISP interface does so with a 1x5 0.1" header with the following pinout:
That way, it would be easy to make a little programming breakout board to post up on BatchPCB.
Conclusion
I think this experiment has proven that it is fairly stright forward to program an LPC1768 (or LPC2368, as it turns out) via ISP when it is on yout own PCB.
I hope this page will serve as a good reference of how to go about this, please leave comments and feedback, and i'll tweek this page up as needed.
In the mean time, there are some useful resources :
Yup, you are right mbed is now just a USB->Serial converter. I was hoping to make it control the reset and ISP lines, but as you saw, that turned out to be a bad idea.
The essence of this page is just to demonstrate the process, and give some confidence that there is a route to reuse the binary on a custom PCB.
I am working on the assumption that you'd prototype the hardware and software with the mbed module, and that when you come to program a custom PCB, you are in "production", so you dont need anything more than a mechanism to put the binary in the LPC. In this scenario JTAG doesnt give you anything more than ISP, other than a larger connector and a bunch more pullup resistors :-)
My assumption is also that if you needed to use all the extra features that JTAG gives, you'd be doing "product development" rather than "rapid prototyping" using a traditional Dev board, JTAG wiggler and offline compiler, rather than mbed.
They might not be valid assumptions, I'm happy to be told why :-) - afterall this is still a bit experimental.
So the intention that this is an experimental and educational tool?
If this is the case, could there be some merit in having a JTAG (even in a limited form) for educational purposes, for users using the mbed to learn Embedded Programming, using a JTAG can be a component of that education.
I have been struggling with this same general problem. I have several potential products but the thing they all have in common is that the user is not an expert. They are seniors and kids so any update must be fairly simple. I think Flashmagic is too compllicated. The bootloader approach on Sparkfun tutorial is great because all it required is a file on a sd card. I tried to implement that on a program that I developed under Crossworks for Arm but it turned out to be too complicated for me to debug. I was hoping to just use mbed but it no one has yet done that bootloader I just mentioned. It would be great if someone did. We all seem to be inching towards it. I am impressed at how much has been done already by you mbed people.
Unfortunately, I discovered that the BIN2HEX converter program does not run under 64 bit Windows. I found another utility that does run under 64-bit, but it's limited to 64k binary files. That utility can be found here: http://www.ht-lab.com/freeutils/bin2hex/bin2hex.html
On the same subject, the 10 pin mini JTAG/SW connector would be a welcome addition (or replacement) on the Prototype2Product schematic, for anyone wishing to re-create Jason's setup (http://mbed.org/users/tecnosys/notebook/lpc1768-programming-via-10pin-jtagsw/). The 20-pin JTAG header takes up a lot of space on a board - too much when you're trying to minimise the cost of a PCB production run!
I'm in the process of laying out a PCB which has an FTDI compatable ISP header. My goal is to make a cheap target board that can be used for simple "one off" projects. I'm targeting a price point around $20-25 each. To get there, I had to make some tradeoffs: the initial version does not have JTAG or the ethernet chip. It does however, bring all of the Ethernet control pins out to a header. So, its possible to add an external ethernet IC if needed. (mini-jtag could be added, but the routing is already pretty crazy on a 2-layer board; it would probably make the board bigger.)
I can envision creating a few different versions; offering options like mini-JTAG, built-in ethernet support, and multiple USB ports - one for Serial via FTDI, and one connected to the USB pins of the 1768.
Unfortunately, I'm traveling for the next 6 weeks for work. So in reality, a prototype PCB is at least a few months away. (I have the components for several already stocked though.)
For what it's worth, there is a standard ISP header (informal standard I guess) for the LPC chips here: http://www.open-research.org.uk/ARMuC/Standard_ISP_Header.html
The 8-pin IDC cable header seems hard to find though, a 6-pin 2x3 IDC would be better IMO and can be gotten here: http://www.pololu.com/catalog/product/854
I'm not sure I read over it somewhere or what I did read I didn't follow. Can someone make up a bare metal schematic with BOM using the LPC1768 chip ? The reference schematic to me doesn't make sense with this "IC2". When I look at the pictures of the custom PCB above I see the microcontroller, a few resistors and a frequency chip. But looking at the schematic I see the frequency chip connected to "IC2" but nothing connected to the LPC1768 ?
Hi Frank, the ref schematic is not the complete mbed schematic. The mbed interface chip (aka magic chip) is missing. In fact IC2 and LPC1768 are the same. The IF chip and the LPC1768 share the same 12 MHz clock on the mbed.
I would like to use a process like this that uses the bootloader. However, this discussion seems a lot about how NOT to do things! It seems for us novices that a simpler and more practical tutorial would be appropriate.
My thoughts started along the line of mounting a ISP jumper on my custom PCB and then a push button to initiate programming. The jumper would be used temporarilly to set the ISP pin low while programming. The pushbutton would set the reset low and when released set it back high. This would initiate the bootload from the PC using FlashMagic.
Am I correct in assuming that that the bootloader wont work across the USB on the LPC1768? This would cetainly simplify the cabling.
We could just use a FTDI chip on the custom board to access the PC via USB since they dont tend to have serial ports.
But this is reallly ugly because we need pushbuttons, jumpers and a FTDI chip -- lots of precious board real estate.
We should think this through and find the best solution without using JTAG. We may end up with JTAG being the easiest solution in terms of real estate and board-mounted parts.
Why can we get the exact functionality we have with the mbed with our custom board? We would add a USB connector that attaches to the PC. A button would perform the reset.
I am able to communicate with my LPC1768 (I can see the synchronized message) and I was able to programme it using a FTDI cable and Flashmagic. The programming works without errors of any kind. But I am missing something : my small hello world programme :
#include "mbed.h"
Serial pc(USBTX, USBRX); // tx, rx
int main() {
while(1) {
pc.printf("Hello World!\n");
}
}
does not work. I tried to reset the LPC1768 (put reset to ground) and still, I am unable to see the Hello World message. Am I missing a step? After programming?
I am able to communicate with my LPC1768 (I can see the synchronized message) and I was able to programme it using a FTDI cable and Flashmagic. The programming works without errors of any kind. But I am missing something : my small hello world programme :
#include "mbed.h"
Serial pc(USBTX, USBRX); // tx, rx
int main() {
while(1) {
pc.printf("Hello World!\n");
}
}
does not work. I tried to reset the LPC1768 (put reset to ground) and still, I am unable to see the Hello World message. Am I missing a step? After programming?
thanks.
H.
Hi,
I think your program is working but you either need to use the USB serial library or use a different UART (e.g. p9,p10) and an FTDI chip to convert to USB or use TTL serial.
I suggest you recompile your code and add in a flashing LED so you can see the program execute.
Considering you program using ISP that should mean it is running its clock fine, so your code should work. I do assume you actually connected your LED to p9.
One option is that your binary to hex conversion goes wrong, although generally that happens with larger files only afaik. To be sure, I just converted that program to hex, you can see if that is the same file as you got: http://mbed.org/media/uploads/Sissors/test.hex
Thanks for your code. I just programme it on my chip. Then, I verify teh memory content and it is the same as the code. So, no dougt, the chip was programmed succesfully. However, the led does not blink.
Now it works, I was connected on the wrong pin. That means that my problem is the bin2hex conversion. I was not able to install : http://www.hex2bin.com/bin2hex so I used this one : http://www.ht-lab.com/freeutils/bin2hex/bin2hex.html
When compiling with bin2hex and commparing with your file, I see they are not the same. In my case, each line starts with :2 and in your case it starts with :1. Also, my lines are longer. However, one can see that both code is somehow the same. I was using bin2hex. What are you using?
Advantage of avr-objcopy is that you have it automatically available if you happen to have AVR studio installed (at least for version 4, but I expect also the other versions). Command is: avr-objcopy -I binary file.bin -O ihex file.hex
I do use it on vista, but I expect it then also to work on 7.
When compiling with bin2hex and commparing with your file, I see they are not the same. In my case, each line starts with :2 and in your case it starts with :1. Also, my lines are longer. However, one can see that both code is somehow the same. I was using bin2hex. What are you using?
thanks.
The :10 means your lines will have 16 hex values. Lines starting with :20 will have 32 hex values. This the regular intel hex format. So the hex file looks ok, which is also confirmed by the fact that your code runs.
Ok, I made another board and it works fine. You are right, both HEX files works now.
The only difference between both boards is that I forgot to solder an inductor between the digital and analogical VDDS (the board that works does not have this inductor). I thought the inductor was meant to isolated both VDDS. I found the inductor in the schématic of lpcmini : https://mbed.org/users/chris/notebook/prototype-to-hardware/
One looks like the 32.xxxkHz oscillator used for the RTC, if you dont want to use the RTC you shouldnt need it. Other one is main clock source. AFAIK you can also run from internal oscillator, but for many functions you will need a more accurate clock.
One looks like the 32.xxxkHz oscillator used for the RTC, if you dont want to use the RTC you shouldnt need it. Other one is main clock source. AFAIK you can also run from internal oscillator, but for many functions you will need a more accurate clock.
Thank you. Does mbed module use external main clock? I looked at the schematics. It looks like a 50Mhz clock goes into the LPC1768, but that pin is for ethernet i think. The other one is 12Mhz clock for RTC.
12MHz is the main clock for the LPC1768 (and the magic chip). Internally a PLL brings it to the 96MHz the mbed runs at. There is indeed also a 50MHz oscillator I didnt realise there was, indeed for ethernet. And finally a 32kHz crystal for the RTC (page 3 of mbed schematic, left bottom. It is a bit hidden).
12MHz is the main clock for the LPC1768 (and the magic chip). Internally a PLL brings it to the 96MHz the mbed runs at. There is indeed also a 50MHz oscillator I didnt realise there was, indeed for ethernet. And finally a 32kHz crystal for the RTC (page 3 of mbed schematic, left bottom. It is a bit hidden).
Correct me if Im wrong, On page 3 of the mbed schematic, X1 is external clock source pin which is 12 Mhz, RTCx1 and RTCx2 is for the RTC clock, which is provided by a chip called FC-135.
Thanks for your help again, me and my team is doing senior design for college.
Thanks all for the posts. I'm working with the FRDM-KL25Z board, and was thinking that the "open SDA" components - the second USB port, K20 "magic chip" and other stuff from page 4 of the schematic would be usefull as a programming dongle, no? The inteface signal list between dongle and target is short at 5 and there's no reason to devote space to this stuff on a production target.
edit - should have read the manual because it looks like they have thought of this already. Section 5.2. of FRDM-KL25Z User's Manual shows how to use the FRDM board to program off-board MCUs.
I followed exactly what was mentioned in the HDK guide. I created my board and this is what I found:
1) The very first time when I connect the board, I press the switch 1 and I am able to dumb the lpc11u35_lpc1768_if_mbed.bin file into the 11U35.
2) I, then, power toggle it by removing and reattaching the USB cable. Now I can see the mBed drive in my device manager. I keep the switch 2 pressed, open this drive and load my compiled code in it. I keep the switch pressed until then.
3) Now I release the switch, the code starts running but the mBed drive and the COM port vanish from my device manager.
I was able to read the device signature but got the message "Unable to communicate (transmit/receive) when tried to download the HEX file to the target board (LPCExpresso) by Flash Magic. Please suggest!
Hello
I want to use mbed codes for USBHID in my own hardware (nxp lpc1768). When I use mbed board, computer recognizes the incoming usb and I can communicate with the board via usb, but when I use my own board, the computer returns an error indicating that the incomming usb is not recognized. What is the problem? Do I need to develop some drivers for it?
Thank you.
I would like to build a custom board with the FRDM-K64F (MK64FN1M0VLL12) with only a single MCU chip. Has anyone tried this and what pitfalls would I need to avoid in the hardware design?
In terms of software, the following library makes downloading a new program possible:
Bootloader_K64F
The first program with the bootloader code would need to be downloaded with JTAG or a second FRDM-K64F board. The K64F USB port does not support serial natively without mbed libraries (USBserial). This means the bootloader code needs to copy the program to intermediate Flash memory sectors as received over USB serial, and then write the program to the Flash memory boot sectors.
Chris,
This page is exactly what I was looking for. I now have an LPC1768 proto-typed and programming using FlashMagic. Took only a few hours. Thanks for taking the time to document this and help everyone get up and running! Now I can take the hardware design to the next level for my robotic arm controller.
Thanks!
Joe B
hi, I have a doubt. I just started with ARMmbed. There are 100s of boards provided, all have same type of programming, we just need to choose one specific board. I generated two codes one for teensy board other for lpc1768 board and exported to keil. Now all of the files are almost same. But the doubt is that what makes all the difference for example, if I write a code for tennsy board what changes at architecture level and/or in code are required/done that the same code starts working on some different board, say on lpc1768 board.
This site uses cookies to store information on your computer.
By continuing to use our site, you consent to our cookies.
If you are not happy with the use of these cookies, please review our
Cookie Policy
to learn how they can be disabled.
By disabling cookies, some features of the site will not work.
Access Warning
You do not have the correct permissions to perform this operation.
Liking this, but all the mBed itself is a USB->Serial TTL cable, useful all the same.
You can Hack a Nokia DKU-5 cable (~£3) to do the same thing.
Next we need to turn the mBed into a JTAG itself.