NXP LPC1114FN28/102 - Page 1
Forum section: electronics / general

author: olsenn
author_rank: Frequent Contributor
timestamp: February 04, 2013, 04:08:10 pm
content: After deciding to switch from my usual PIC/AVR 8-bit microcontrollers to a 32-bit ARM Cortex-M0 for my next project, I have come to the conclusion that this goddamn chip is ridiculous to program! I just spent a whole day figuring out how to configure the internal crystal to feed a PLL whose output is configured to be the main clock (this should be selectable from fuses in my opinion) I am not unable to get a damn IO pin to output a voltage.I have set the GPIO1DIR to 1 (output) and I set GPIO1DATA to 4095 so that all pins should be logic 1 (I tried again with 0 since I figured it may be active low) but nothing. I am actually getting a (very) dim light out of my LED in both cases which means the thing must be leaking current somehow. Is anyone here familiar with this chip? I managed to track down a blinking LED project online but it won't compile under IAR and the source code is so cryptic it's driving me nuts! It actually provides pointers to address locations in the CPU which store the LED states, but those values aren't even in the datasheet or user guide... just a block diagram of how blocks of memory addresses are broken up.I'll be looking at it more tonight, but in the meantime, does anyone here have any pointers for me (pun intended)?

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 04, 2013, 04:47:11 pm
content: IAR usually have several examples (in the install dir) which are a good starting point to get _something_ working

author: nctnico
author_rank: Super Contributor
timestamp: February 04, 2013, 07:58:47 pm
content: You can download a bundle of examples from NXP's website. That should get you started. The most simple example is called 'blinky' (IIRC).

author: TheDirty
author_rank: Frequent Contributor
timestamp: February 04, 2013, 08:45:00 pm
content: You should have tried out the bigger ARM7's, now that was crazy.I assume you aren't turning on the GPIO clock.Code:LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); //Enable AHB clock for GPIOLPC_GPIO0->DIR |= PIN; // PORT ? pin ? set to outputwhile( 1){delay_ms( 100);LPC_GPIO0->DATA |= PIN;delay_ms( 100);LPC_GPIO0->DATA &= ~(PIN);}

author: andyturk
author_rank: Frequent Contributor
timestamp: February 05, 2013, 03:38:02 am
content: LPC11xx is one of the architectures supported out-of-the-box by an open-source RTOS calledChibiOS. It's really well done, and the kernel compiles down to about 5K of code. The distribution includes examples for IAR, Keil and (usually) GCC.Here's ablinkyexample (see main.c) for the LPC1114. You won't find much low-level code in there, since kernel takes care of that. If you really want to see how to flip hardware bits, you can look at how the ChibiOS kernel implements things.Have you put a scope probe on your dim LED? If it's a constant voltage, then maybe your program mostly works but perhaps the IO pins are configured to source enough current. If there's some wacky on/off action, then you probably have some other issue.

author: Harvs
author_rank: Super Contributor
timestamp: February 05, 2013, 09:57:47 am
content: Quote from: TheDirty on February 04, 2013, 08:45:00 pmYep check that, peripheral clocks are always the catch of the ARM beginner.But, I think this is just another example of why the folks that put together the example programs for uC's need to be shot.I've once again been digging through some "example" code for another micro. But it's always the same. They call some cryptic function that does some magical setup. You go try to find that function, and what do you know. Its actually just a #define where they've relabeled another function with some stupid name (e.g. #define myDemoGPIOConfig), so you go digging in a third file to find that. And well, this time it's another #define (e.g. #define GPIOPORTCONF) where they've called yet another function, yet they've passed in two out of 5 parameters through the define from another cryptic struct in yet another file. Then when you actually find the "primitive" function, it's nothing more than one or two lines of code setting a variable. WTF? Why can't they just put these basic examples in a pretty much flat file?So at the end of the day, you'll find it's actually a lot easier to program than you think once you find the calls you need to make. It's just a pity they have to obscure it for some reason.

author: Bored@Work
author_rank: Super Contributor
timestamp: February 05, 2013, 03:47:12 pm
content: The reason you now find these mess of defines and functions is that there is now a generation of programmers at work who can't live withoutdrivers. They feel insecure if they have no operating system at all, if they do not have at least one framework on top of it, and they compensate this by asking at least for drivers. These days you find embedded programmers who don't even get basic binary operations like AND or OR. They don't manage to turn a pin on or off without a driver.

author: andyturk
author_rank: Frequent Contributor
timestamp: February 06, 2013, 02:29:37 am
content: http://www.downtowndougbrown.com/2012/06/microcontrollers-gpiotimersinterrupts-example-and-lpcxpresso-lpc1114-review/

author: poorchava
author_rank: Super Contributor
timestamp: February 06, 2013, 11:52:24 am
content: I also don't like that trend in code examples. Mircochip for example loves to cram parameter settings for every possible target you may want to compile particular example for. Which means that their examples are literally stuffed with code like #ifdef PIC32XXXXXX [set set something to zero] elseif [set that to other value].I think that for the sole purpose of easier code readability they should put all the code in one simple file, or even few files, but not in multi-level structure. Of course they could put a comment in there like: "this code is normally in library xxx. You have to include xxx.h to use that function". How hard can that be?

author: amyk
author_rank: Super Contributor
timestamp: February 06, 2013, 01:17:00 pm
content: Quote from: andyturk on February 06, 2013, 02:29:37 amDespite not having used the LPC1114 before, that tutorial put me off learning, because it's going through an excessively convoluted route just to do something simple. To achieve the same end result in AVR or PICassembly languagewould've probably taken less lines of code...

author: Harvs
author_rank: Super Contributor
timestamp: February 06, 2013, 02:23:39 pm
content: Quote from: amyk on February 06, 2013, 01:17:00 pmProbably, if all you ever wanted to do was implement a timer system. But that's not the reality of what you do with these ARM devices.Another thing that I find regularly trips up people coming over from 8-bit uCs is the significant use of structs and pointers (including function pointers.) They're actually not a bad thing at all, helps to keep important data together in a sort of object-oriented way. But most 8-bit programming doesn't make use of them anywhere near as much, so it can be completely overwhelming to new comers to see an example like this with de-referencing of struct components and passing pointers to callback routines in a function call.My suggestion there is to put down the new microcontroller for a bit, and go find a good book on the C language.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 06, 2013, 02:27:25 pm
content: Quote from: poorchava on February 06, 2013, 11:52:24 amThis is something I also hate.....For the case of supporting multiple processors it would be nice if there was some sort of preprocessor that would look at all the #define options and create new source files with all the unused bits stripped out to make it easier to read.I've just been hacking some examples for the NXP LPC1800 and there are all sorts of macros and trivially short procedures that just seem to be about making things "more friendly", but actually it means you need to know ot only the chip but also all the "friendly" names and APIs. And I've already found some bugs in them...They even go as far as having some quite complex procedures for setting up peripherals, with huge run-time tables, meaning that a simple LED blinky takes 5K. At least IAR's linker is smart enough not to include unused procedures, unlike Microchip's C30 (this may have changed recently).Another pet peeve of mine is examples which are split up into zillions of files buried in a heirarchy of folders. IMO this is a practice dating back to the days when editing larger files was hard and compilers were slow. It makes it a total nightmare to follow to figure out what's going on.One feature I really like in IAR is that it will automatically add any included file it finds while compiling into the project, so you can quickly go to things like processor header files to look up names of registers, bits etc.

author: andersm
author_rank: Super Contributor
timestamp: February 06, 2013, 02:55:04 pm
content: Quote from: amyk on February 06, 2013, 01:17:00 pmThat's got nothing to do with the hardware. There's literally 7 lines of code that are hardware-dependent (setting up the hardware timer, IO pins, disabling and enabling interrupts). The rest is handling the software timers which would look the same on any platform.

author: nctnico
author_rank: Super Contributor
timestamp: February 06, 2013, 03:43:43 pm
content: Quote from: amyk on February 06, 2013, 01:17:00 pmThat depends whether you know AVR or PIC assembly. I know the NXP ARM controllers inside out so for me writing assembly for an AVR or PIC would be an extremely convoluted route.@Mike: did you ever look into the header files of MPLab for PIC? If you want to learn about obfustigated C header files start there and everything else looks simpleI don't know about the IAR IDE but Eclipse does miracles when having to sort through header files and large C projects (like the Linux kernel). Anything that isn't enabled gets greyed so it is really easy to see what parts of the code are active or not.

author: olsenn
author_rank: Frequent Contributor
timestamp: February 06, 2013, 03:59:10 pm
content: I haven't had too much time to work on this, but I did spend a bit more time looking at the datasheet and user manual for this IC, and still I am unable to control the voltage on an IO pin. Actually, there is one way I was able to do it, but that involved switching from a pull-down resistor to a pull-up resistor on the pin, so obviously that isn't the ideal way of sending data accross.To dispel some of the theories I've seen on here, I have indeed enabled the GPIO and I/O clocks, and I have configured the I/O port I am using with the IOCON register to act as a regular GPIO pin. I think the problem is that the user manual seems to have been tranlated from Manderin, and improperly at that. It claims somewhere that the GPIOnDATA register only takes affect once some other crytic bit is set in a register that doesn't exist.As the tree said to the lumberjack, "I'm stumped".

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 06, 2013, 06:19:23 pm
content: Quote from: nctnico on February 06, 2013, 03:43:43 pmI know some of them pretty well, but looking at the LPC1800 now and fighting through tons of seemingly pointless abstraction macros and procedures that are just getting in the way of me bashing hardware...!And the stuff they can't do with macros they are wasting run-time code on, with big, inefficiently written lookup tables. The Led Blinky example is about 5K of code to set up the clocks etc.- ridiculous.I'm not sure to what extent this is to do with CMSIS or just coincidental but it's just a PITA - just let me at the hardware! All I want to do is read data off a SD card quickly and blow it out of about twenty soft UARTs at 250kbaud - how hard can it be...!Now in the process of just tearing all the crap out of the way so I can see WTF is actually going on....

author: nctnico
author_rank: Super Contributor
timestamp: February 06, 2013, 06:40:02 pm
content: I always use the defines from the Keil code bundle which is available from NXP's website. Unfortunately the newer header files use structs and pointers to get to the peripheral registers. That method is quite prone to errors (especially if you set the compiler alignment different) and doesn't make it more clear. The first thing I did was creating a set with 'old style' defines for the peripheral registers.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 06, 2013, 08:18:49 pm
content: Quote from: nctnico on February 06, 2013, 06:40:02 pmCreating processor header files has to be one of the most soul-destroying jobs in the industry....Whenever I've come up against what appears to be a silicon issue, it's almost always turned out to be an error in a definition in a header file.

author: TheDirty
author_rank: Frequent Contributor
timestamp: February 06, 2013, 08:23:13 pm
content: Quote from: olsenn on February 06, 2013, 03:59:10 pmPost your code.This is the entire LED blinky example I use for testing boards that I've reflowed. This is using Rowley Crossworks, which is a GCC front end. The delay functions do not actual match real times. They are just junk delays I threw in for a simple test program.I usually use the hardware timers rather than CMSIS functions. The LPC11xx and LPC13xx timer hardware blocks are not very complicated and pretty well thought out.Code:#include "LPC11xx.h" /* LPC11xx definitions */void delay_us( int);void delay_ms( int);#define PIN (0x01 << 7)void main( void){volatile unsigned int x, y;LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); //Enable AHB clock for GPIOLPC_GPIO0->DIR |= PIN; // PORT ? pin ? set to outputwhile( 1){delay_ms( 100);LPC_GPIO0->DATA |= PIN;delay_ms( 100);LPC_GPIO0->DATA &= ~(PIN);}}void delay_us(int delay){while(delay--){__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");__asm volatile (" NOP");}}void delay_ms(int delay){char i;while(delay--){for(i=0; i<4; i++){delay_us(250);}}}

author: andyturk
author_rank: Frequent Contributor
timestamp: February 07, 2013, 03:35:14 am
content: Quote from: mikeselectricstuff on February 06, 2013, 08:18:49 pmI've found it useful to go back to the datasheets and build my own structs for hardware/peripheral registers on occasion. For debugging, it's nice to be able to simply dump the entire thing out in one shot without having to dance around the API.

author: amyk
author_rank: Super Contributor
timestamp: February 07, 2013, 10:33:41 am
content: Quote from: mikeselectricstuff on February 06, 2013, 02:27:25 pmThe C compiler should have an option to run only the preprocessor; for gcc that's the -E option.

author: Harvs
author_rank: Super Contributor
timestamp: February 08, 2013, 03:55:48 am
content: Maybe the uC manufacturers programmers have been competing over here, and so practicing during work time...http://www.ioccc.org/