Go Back

LPC1347/LPC11U37 Update

Sunday, January 20, 2013
LPC 1347/LPC11U37 Wireless Test Boards

I finally found a few minutes to test the latest PCBs for the LPC11U37/LPC1347 and I'm pretty happy with both the test HW and the code base itself.  I think it's a significant improvement over any of the previous code bases posted here, and I think it should be a good starting point for projects moving forward.

Overall, I'm extremely happy with the flexibility offered by the (essentially) pin and register compatible LPC11U24, LPC11U37 and LPC1347.  This trio leaves a lot of room to maneuver optimizing for flash size, performance, price or package size with almost no extra SW development effort.  Making a code base that makes that as painless as possible took a bit of effort, but at least it's a one time expenditure.

I don't want to post many details until the code base is ready to go live, but I think it's all come together pretty well so far, and I hope it will be a decent starting point for a lot of people.  It'll definitely make things easier here to get prototypes off the ground in days or weeks rather than weeks or months.

Full story  | Comments (7)

LPC1347/LPC11U37 Board and CodeBase Update

Thursday, September 13, 2012

I was surprised by the interest in the RF board I posted about earlier, so I figured I'd post a small update on the progress. I've been dividing my time between the 1347 and 11U37, trying to spend equal amounts of time with both to make sure that the codebase easily works with either chip out of the box.

Initial Opinions

While the migration from the 1114 and 1343 has been generally pretty smooth, I did have to pull out the UM to understand the new (and more flexible) GPIO blocks, the 12-bit ADC (1347 only), get the EEPROM working, etc., but nothing too dramatic so far. SSP, I2C, etc., are the same as always since they're basically just licensed IP blocks from ARM.

Overall, I'm exceptionally happy with both chips and the 1347 is everything I wish the 1343 would have been ... though I'd be happier if the distributor pricing was a bit lower.

There were some hiccups creating a common LPC11U37 + LPC1347 codebase because of a few regrettable naming differences in the CMSIS libraries from NXP. The UART IRQ handler is defined as "USART_IRQHandler" for the 1347, for example, but "UART_IRQHandler" for the 11U37, so to have a single codebase for either chip I end up with horribly ugly cludges like this:

#if defined CFG_MCU_LPC11U37FBD48_401
void UART_IRQHandler(void)
#elif defined CFG_MCU_LPC1347FBD48
void USART_IRQHandler(void)
#else
  #error "uart.c: No MCU defined"
#endif
{
  ...
}

Similar situation for "FLEX_INT0_IRQHandler" (11U37) versus "PIN_INT0_IRQHandler" (LPC1347), and in a number of other places, but these are relatively easy to locate and fix. The worst so far was with GPIO, though, where some of the register names in the core header file were different, as seen below (used to set up a GPIO interrupt):

        case CHANNEL1:
          if ( portNum )
          {
            #if defined CFG_MCU_LPC11U37FBD48_401
                LPC_SYSCON->PINTSEL[1] = bitPosi + 24;
            #elif defined CFG_MCU_LPC1347FBD48
                LPC_SYSCON->PINSEL[1] = bitPosi + 24;
            #endif
          }
          else
          {
            #if defined CFG_MCU_LPC11U37FBD48_401
                LPC_SYSCON->PINTSEL[1] = bitPosi;
            #elif defined CFG_MCU_LPC1347FBD48
                LPC_SYSCON->PINSEL[1] = bitPosi;
            #endif
          }
          #if defined CFG_MCU_LPC11U37FBD48_401
            NVIC_EnableIRQ(FLEX_INT1_IRQn);
          #elif defined CFG_MCU_LPC1347FBD48
            NVIC_EnableIRQ(PIN_INT1_IRQn);
          #endif
        break;

LPC_SYSCON->PINTSEL (LPC11U37) is probably the better name because it better represents what this register is doing (GPIO Pin Interrupt Select), but curiously the LPC1347 user manual also lists this value as PINTSEL (not PINSEL), so it's likely just an unfortunate typo that people are stuck with now since they can't really change it. It's also a rather misleading name if you've ever done any ARM7 development with the older LPC2000 series since 'PINSEL' performed a very different and common function. But hey ... such is life, and at least they give you something to start with these days, and mistakes happen. It just struck me as unfortunate that for chips that are almost identical on a peripheral level, and that can be dropped in with 99% SW and HW compatability that the major obstacle would be something as trivial as inconsistent naming across families.

Low Power

The power numbers were higher in the sleep modes than I expected, and I'm still working on this and certain it's my fault. I trust the numbers in the datasheet, and I'm pretty confident in my HW after two revisions for power, but I just need to find the secret sauce in the firmware. This also took quite a while with the 1114. I'm currently at 30µA in power down running at 2.2V which is identical to what I got on some similar LPC1114 wireless boards ... but I should be able to go much lower than that (ideally under 10µA total). There were a lot of gotchas trying to isolate those microamps, though, including on less than obvious one.

The 1347 and 11U37 families now include a (welcome) QFP64 package option with more IO pins (great for large LCDs, etc.). Inside, though, all of these chips almost certainly use the same die, and they just selectively bond out the required pins for the package -- QFN33, QFP48, QFP64, etc. The 'gotcha' was that on a QFN33 or QFN48 package, those extra GPIO pins still exist on the die, and if you go into a low power/sleep mode without taking them into consideration you'll be drawing several hundred µA more than you should be due to the pullups and default pin state. You need to explicitly setup the unbonded pins to output and GND as well, and put the pullups in an appropriate state AND be sure to disable the analog mode on unbonded pins with an ADC option. I didn't think of that at first, but it got me from 400µA to around 30µA, using code similar to the following (I explicitly set every pin on startup now):

I caught that thanks to Embedded Artist's excellent Oryx board (thanks for the inadvertent heads-up Anders!).

CodeBase Improvements

Since I'm starting a new code base I took the opportunity to try to improve on previous efforts, and I think the current version has a better organisation, and I've improved some things I really didn't like in the previous 1343 and 1114 libraries.

  1. I've improved the CLI a bit (better organisation, etc.)
  2. I added a very preliminary mechanism to localise/translate text so that you can support multiple languages in one application (though this really needs more attention and testing), which is a must outside the US but not something I see done a lot in open source embedded projects
  3. I've start working on a global error handling mechanism, though at the moment it's just shared error codes and better error handling and checking in I2C
  4. I also added a board-specific init sequence and file in addition to the shared systemInit() function so that board specific code can be better seperated, though this still needs some thought.

 

Overall, I'm happier with this that the 1343 code base, but it still needs some thought and effort and isn't ready for the real world yet. The biggest change is that I've decided not to swim against the current and just use CMSIS from the start. When I start with the 1343 and 1114 codebase CMSIS was brand new, and nothing existed for these chips anyway, so I just did what I always did and pulled out the UM and started making my own flat header file. I still prefer this approach, but I just don't have the time to dedicate to doing this well these days -- there are weeks and weeks of effort in that approach -- so I'm using the default NXP peripheral drivers and CMSIS 3 code, making changes where appropriate so that the code works with both the 11U37 and 1347 just changing a single define in projectconfig.h. This isn't an ideal solution for me, and I may go back and rewrite all those peripheral drivers myself ... but for now this lets me get started quickly and developping the HW, etc.

When Will it be Available?

Not sure, and no promises. I don't want to publish it before it's in reasonably good shape and I'm happy with the basic organisation, and since this is just an unpaid weekend project I can't work on it much during the week ... but hopefully in a month or so I'll publish an initial version along with the HW files for a first wireless board and maybe put together a simple MCU-only board for people no interested in RF but who want to use the codebase.

The ToDo list is still pretty big. I haven't touched USB yet, the antenna on the current boards desperately needs to be properly measured and either revised or tuned, and I have to add in ADC support and a few key peripherals I haven't gotten to yet like the timers. I think the worst is done, though, and things are coming together nicely ... just never enough hours in the week to really wrap it up.

I'll definitely be moving to the 1347 and 11U37 combination in the future, though, and they're great little chips that should be much more flexible than the earlier 1343 and 1114. I'll probably move away from the 1343 entirely, but will maintain the 1114 code since it's still ridiculously cheap, there's a DIP version of it, and the new 1115 with 64KB flash breathes some extra life into it.

Full story  | Comments (2)

LPC11U24/LPC11U37/LPC1347 RF Board

Wednesday, July 25, 2012

I've been looking for an excuse to do something with the LPC1347 for a while, and I ended up recycling a lot of previous work, combining a number of lessons learned into a single four-layer board that should let me test a number of power supply and project scenarios.  I kept the board fairly basic, just a microSD card for datalogging, USB, and SWD connector, and reset/ISP buttons.  There's on on-board user-selectable 3.3V/2.2V linear regulator (TPS780), but it can be bypassed and you can power the board from another source for flexible power input and current control.  It's designed to fit in these inexpensive weather-proof cases with a transparent top for a small solar cell, but should be easy to adapt to another enclosure.

I kept the RF section completely seperate as well so that I can change to another chip if required.  The current board uses an AT86RF212 (868/915MHz 802.15.4), and I can drop in an AT86RF230/231 (2.4GHz) with a simple adjustment to the transmission line width for impedance matching ... but I also whipped up a schematic for the nRF8001 for Bluetooth LE that I might test down the road.  The way the board is now I can make seperate 2-layer add-on PCBs for various power and sensor inputs, sticking to one common footprint and header to evaluate things more quickly.

One benefit of the ARM Cortex M3 based LPC1347 is that it's pin compatible with the Cortex M0 LPC11U24 and Cortex M0 LPC11U37.  This gives me a decent selection of options between price/performance/flash size on a single PCB, with minimal SW changes, all of which have excellent power numbers:

  1. the LPC11U24 is dirt-cheap - 50MHz M0, 32kB flash, 8kB SRAM
  2. the LPC11U37 has lots of flash for complex stacks - 50MHz M0, 128kB Flash, 8+2+2kB SRAM
  3. the LPC1347 is a high-performance chip with a decent amount of flash - 72MHz M3, 64kB Flash, 8+2+2kB SRAM and 12-bit ADC

It's just a personal, weekend project, but I'll blog some more about this board when I get the PCBs in later this week since it was a big (if expensive) learning experience.  Here's some photos of the PCB being manufactured, though, if you've never seen the different steps of the process (courtesy PCB Pool):











Full story  | Comments (17)

LPC1347 to LPC1343 Comparison

Wednesday, March 28, 2012

NXP recently unveiled its new LPC1345/6/7 processors. It’s a welcome addition to the 1300 family, since they’ve been keeping busy steadily adding new members to the LPC1100 family, but it’s M3 twin-brother felt somewhat neglected by comparison despite being a fairly popular chip for them. The new LPC1347 seems to do a good job of addressing this imbalance, though, and introduces almost everything I found myself wanting in the 1343, without having to move up to the LPC1700 family.

While the migration process from the 1343 to the 1347 will be a bit bumpier than I would have liked, the effort seems worthwhile. The main issues are that the 1347 uses an updated and reorganized GPIO block, as well as a newer USB block. The LPC1347 feels like it gives you a lot more room to breathe, though, adding space for feature creep, and pushing the ceiling a bit higher than the 1343. I sometimes found myself struggling with 32KB flash, and missing a second SSP block on the USB-enabled parts, both of which are addressed on the new chips.

Key Improvements

 

LPC1347

LPC1343

Core

ARM Cortex-M3 2p1

ARM Cortex-M3 r2p0

ADC

12-bit, 500 kSamples/s

10-bit, 400 kSamples/s

Flash

64 kB

32kB

SRAM [1]

8+2+2 kB

8 kB

GPIO Blocks

2*32 pins

4*12 pins

EEPROM

4 kB

--

SSP Blocks

2

1

USB ROM-based drivers [2]

HID, MSC, CDC, DFU

HID, MSC

Wakeup from Deep-Sleep/Power-Down

GPIO, WDT, USB

GPIO, WDT Oscillator

Packages

QFP64, QFP48, QFN33

QFP48, QFN32

 

[1] The LPC137 has three separate blocks of SRAM, with 8kB general purpose SRAM similar to the LPC1343, but now also adds 2kB of SRAM for USB and another separate 2kB general-purpose block. The separate USB memory is a helpful addition since the 1343 had to share this memory, and if you were using the ROM-based USB drivers, you had to modify your linker script to avoid using the first bit of SRAM on the LPC1343.

[2] The ROM-based USB drivers on the LPC1347 can also be made to work with custom classes

Pin Configuration Comparison

The images below show a comparison of the QFN33 and QFP48 packages and pin configuration to give you an idea of what has changed between the two chipsets.  QFP64 isn't shown here since it only exists for the LPC1347.

QFN33 Comparison of LPC1343 and LPC1347

QFN48 Comparison of LPC1343 and LPC1347

A Note on Packages and GPIO Pins

The new GPIO block is the same one used in the similar ARM Cortex M0-based LPC11U24, which makes it easy to optimize for cost later and switch between the two devices, but it’s also unfortunately a breaking change compared to the 1343. All pins are now based on two GPIO block – PIO0[0..31] and PIO1[0..31] – rather than the previous four GPIO blocks on the LPC1343. This is potentially the biggest change from a SW migration point of view.

In terms of packages, I’ve always been happy with the QFN33 and QFP48 options – that seems to be the right physical size for chips like this – but there were one or two moments where I found myself wishing for just a couple more GPIO pins. This was particulary the case with larger TFT LCDs that used 16-bit only interfaces, or could have performed much better with a 16-bit interface on a single GPIO block rather than an 8-bit interface sending the data/commands in two separate chunks. Even if the LCD works with 8-bits, using 16-bit allows you to more than double the screen update rate, giving you the option to use larger LCDs with acceptable frame rates, or just freeing up resources for other tasks like improving the UI.

While the reorganized GPIO blocks pose a problem for SW migration, they are also clearly an improvement in the sense that you now at least have the option to use 16-pins on the same GPIO block for a large data bus, using bit-banding for fast single-cycle writes to that bus. With only 12-pins per GPIO block on the LPC1343 this was physically impossible to do.

If you are really short on GPIO pins you also have the option with the LPC1347 to move up to the larger QFP64 package without, having to do an entire rewrite and switch to the larger LPC1700 family. I was never able to find a pin arrangement for 16-bit LCDs that fit on the LPC1343, but this looks perfectly doable now with the LPC1347 in QFP64.

USB ROM Drivers and Bootloader

The ROM-based USB drivers were by far my favorite part of the LPC1343, along with the USB bootloader that relied upon them.  This brilliant little addition allowed you to save a couple KB of flash space by not having to include your own USB stack, and also made it more or less impossible to brick your device since you could update it with no external HW or SW requirements.  Just boot into USB bootloader mode, and drop the updated firmware onto the flash drive that appears, and reset.

That said ... the 1343 had a number of limitations.  It only worked with MSC and HID classes, and the HID, while useful, was limited to a single report size.  If you wanted or needed multiple reports, you still had to implement your own USB stack.  It also seemed unfortunate that USB CDC was't implement since many an engineer still loves their command-prompt.

The LPC1347 addresses almost all of these concerns, and more.  It now includes ROM-based support for CDC and DFU, as well as the functionality to implement custom classes, though I haven't had time to look into the latter yet.  The HID support is also improved, and the bootloader is of course still intact.

Apparently, these ROM-based drivers will also be the same ones used on newer LPC1000 members with USB-ROM support, so it should be relatively easy to switch to other devices, such as the LPC11U24, etc.  NXP's nxpUSBLib currently includes support for using both traditional SW-based and ROM-based drivers, which is likely the best path to choose if you want to ensure compatibility across a variety of LPC1100 and LPC1300 chips.

Overall Opinion

Overall, this is exactly the chip I found myself wishing the LPC1343 was these past couple years of working with it. It addresses most of the issues I had with the LPC1343, and bridges the gap between the LPC1343 and the low-end LPC1700 devices, giving some more headroom in the LPC1300 before you really have to throw in the towel and move up the food chain to the larger chips. The different IP blocks in the LPC1347 pose a problem for SW migration, and I think I’ll end up prematurely bald, gray and single if I try to make an LPC1347 version of the LPC1343 Code Base from scratch again, but I’m definitely interested in migrating new projects to the chip, and selectively updating certain drivers.

I can see myself using this chip a lot with project requiring a large TFT LCD or OLED display and a decent user interface, since the extra 32KB flash allows you to include more fonts, and improved UI elements. I’ve recently been working on adding simple 2 and 4-bit anti-aliased fonts to the LPC1343 library, for example, and while 2-bit fonts are only 2x the size of 1-bit fonts but are visually much more appealing (especially in Italics), it’s hard to fit more than one font in 32kB with all the other drawing code and plumbing that you need in the firmware. Having an extra 32kB will allow me to add an entire family of fonts to projects (regular, bold and italic) using much higher-quality anti-aliased versions, and maybe offer some improved UI elements like more complex dialogue boxes, etc.

That said … don’t expect to see a completely updated library in a few weeks time. It’ll definitely take some time to start putting together anything nearly as complete as the current LPC1343 Code Base, which I’ll definitely continue working with simply because there’s so many thousands of man hours put into it already.

Updated 30 March 2012 to include more information on USB ROM-based drivers, and added DFU to the supported class list.

Full story  | Comments (15)

  1. 1
  2. 2
  3. 3
  4. 4
  5. Next page