Skip navigation
1 2 3 4 Previous Next

LPC Microcontrollers

48 posts

LPC845 Breakout Board now has an SDK package available! We are working on updating our getting started information to show how to use this rather than starting from the LPC845 chip SDK. The board is called LPC845BREAKOUT in the SDK builder.

We used the board to teach a class on how to create a custom SDK for your own board. The class got several thumbs up at our recent Seattle Tech Day and Santa Clara Connects events. The materials are here:

https://community.nxp.com/docs/DOC-343310

Amazon Web Services has released a preconfigured FreeRTOS example for Armv8-M and the NXP LPCXpresso55S69 board. With the addition of board- and device-specific examples, it is even easier to start and use the Arm® TrustZone® features combined with MPU (Memory Protection Unit) on the NXP LPC55xx MCU.

 

LPCXpresso55S69 Board

 

The LPCXpresso55S69 is an ideal development board for evaluating the Arm Cortex®-M33 architecture and security features. The core platform features two Arm Cortex-M33 cores running up to 100 MHz.

 

  LPC55X6x Block Diagram

 

FreeRTOS is the de facto real time operating system for small and low-power devices. Since 2017, FreeRTOS has been an AWS open source project.  AWS has released a FreeRTOS port to support Arm Cortex-M33 devices: AWS Makes It Easier for Embedded Developers to Build IoT Applications with Additional Preconfigured Examples for FreeRTO… 

With the Arm TrustZone approach to divide into a 'secure/trusted' and 'unsecure/not-trusted' world, it is possible to effectively protect sensitive code and data, such as secure bootloaders, key and encryption management and trusted applications on the 'secure' side, with the ability to run other functionality (for example third-party applications or middleware) at a lesser security level.

 

FreeRTOS with NXP MCUXpresso IDE and SDK

 

FreeRTOS can be configured at compile time to run either on the secure side or on the non-secure side.  When FreeRTOS is run on the non-secure side the tasks (or threads) can call secure-side trusted functions that, in turn, can call back to non-secure functions, all without breaching the kernel’s prioritized scheduling policy. That flexibility makes it possible for application writers to create non-secure FreeRTOS tasks that interact with trusted secure-side firmware.

Setting up security adds some extra complexity and having these examples available in the FreeRTOS mainline release will help you to add security and TrustZone features to the next LPC55xx MCU design.

 

Happy Securing!

 

 

Links

The ARM TrustZone is an optional secu=rity feature for Cortex-M33 which shall improve the security for embedded applications running on microcontroller as the NXP LPC55S69 (dual-core M33) on the LPC55S69-EVK.

NXP LPC55S69-EVK Board

NXP LPC55S69-EVK Board

 

As with anything, using and learning the TrustZone feature takes some time. ARM provides documentation on TrustZone, but it is not easy to apply it for an actual board or toolchain. The NXP MCUXpresso SDK comes with three examples for TrustZone on the LPC55S69-EVK, so I have investigated these examples to find out how it works and how I can use it in my application.

Software and Tools

I’m using the same setup as in my earlier article (“First Steps with the LPC55S69-EVK (Dual-Core ARM Cortex-M33 with Trustzone)“):

  • Windows 10 with MCUXpresso IDE 10.3.1 (Eclipse based with GNU toolchain for ARM Embedded)
  • MCUXpresso SDK V2.51. for LPC55S69

Most of the things presented in this article are applicable to any other Cortex-M33 environment with TrustZone.

TrustZone on ARMv8-M

As on the in the ARMv7-M, there is two basic modes the processor can be in:

  • Thread Mode: this mode is entered by reset or the usual mode in which the application runs. Code in Thread Mode can be executed in privileged (full access) or non-privileged (no restrictions imposed e.g. by an MPU (Memory Protection Unit)).
  • Interrupt or Handler Mode: this mode is executed with privileged level and this is where the interrupts are running.

TrustZone keeps that model and extends it. The basic concept of TrustZone on ARMv8-M is to separate the ‘untrusted’ from the ‘trusted’ parts on a microcontroller. With this division IP inside the trusted side can be protected while still allowing ‘untrusted’ software to run on the ‘untrusted’ side of the world. Each trusted and untrusted part can have different privileges, such as some hardware (GPIO ports, etc) only could be accessible from the trusted side, but not from the untrusted one.

 I recommend to read the ARM document about TrustZone.

Secure and Non-Secure World

Secure and Non-Secure World

While without TrustZone it is already possible to restrict memory access with an MPU, the TrustZone concept with ‘secure world’ and ‘non-secure world’ extends the concept to ‘secure’ or ‘trusted’ hardware or peripheral access. A non-secure function only can access secure hardware through an API which verifies if it is allowed to access the hardware through the secure world. So there are ways that the secure and non-secure parts can work together.

Similar to using an MPU, it means that there are several things to consider:

  • Setting security permissions for memory areas and accessing peripherals
  • Using secure and non-secure API and transfer functions
  • Ability to protect the secure world from debugging or memory read-out (reverse engineering)

MPU

The other important change in the ARMv8-M architecture that the size of an MPU region has now a granularity of 32 bytes. In ARMv7-M the size had to be a 2^N which I never understood and makes it not usable at all in real world applications (this is probably the reason the MPU is rarely used?).

SAU and IDAU

Because this all cannot be only implemented in the core (provided by ARM), there are extra settings needed on the implementation side by the vendor implementing the ARM core.

  • Secure Attribution Unit (SAU): this is inside the core/processor
  • Implementation Defined Attribution Unit (IDAU): this one is outside the processor

The SAU and IDAU work together and are used to grant/deny access to the system (peripherals, memory). Using the SAU+IDAU, the memory space gets separated into three kind:

  • Secure: Code, stack, data, … of the secure world
  • Not-Secure: Code, stack, data, … of the non-secure world
  • Non-Secure Callable: Entry to secure code with a secure gateway vector table

The important (and somewhat confusing) thing is that the SAU settings are first, and IDAU is used to make things ‘unsecure’:

  • SAU(secure) + IDAU(not secure) => secure
  • SAU(not secure) + IDAU(not secure) => not secure
  • SAU(non-secure callable) + IDAU(not secure) ==>  non-secure callable

Or in other words: by default things are secure, and with the IDAU the security level is set to a lower one.

Projects

Time to have a look at an example! The NXP MCUXpresso SDK already comes with an example showing how to call the non-secure land from the secure one. From the ‘Import SDK example(s) I can select examples demonstrating the TrustZone.

TrustZone Examples

TrustZone Examples

The ‘hello_world’ TrustZone example executes some code on the secure side and finally passes control to the non-secure side to execute the non-secure application. The example follows the pattern of a secure bootloader then calling the non-secure application to start.

I have tweaked and replicated the projects discussed in this article, you can find them on GitHub: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/LPC55S69-EVK

The ‘ns’ (non-secure) and ‘s’ secure projects work together. Using secure and non-secure application parts do not make things simpler, and there seems not to be a lot of documentation about this topic. So I investigated that ‘hello world’ example to better understand how it works.

I have configured both to use the newlib (nano) semihost library:

Semihost settings

Semihost settings

For both project, set the SDK Debug Console to ‘Semihost console’:

Setting Semihost Console

Setting Semihost Console

I have both the secure and non-secure projects configured for using the semihost console, but a real UART could be used too.

Both projects are configured to use the Cortex-M33 (this is a setting in the compiler and Linker):

M33 Architecture

M33 Architecture setting

Non-Secure Side

The non-secure project is configured in the compiler and linker settings as ‘Non-Secure’:

TrustZone Project Settings

TrustZone Project Settings

There is a setting to prevent debugging:

Prevent Debugging

Prevent Debugging

The non-secure application links in an object file which is part of the secure application:

Linking CMSE Lib Object File

Linking CMSE Lib Object File

 This means that the ‘secure’ project has to be built first.

This is for the ‘secure gateway library’ which is built in the secure project using the –cmse-implib and –out-implib linker commands:

From https://sourceware.org/binutils/docs/ld/ARM.html:

The ‘–cmse-implib’ option requests that the import libraries specified by the ‘–out-implib’ and ‘–in-implib’ options are secure gateway import libraries, suitable for linking a non-secure executable against secure code as per ARMv8-M Security Extensions.

Secure gateway library linker command

Secure gateway library linker command

The ‘hello_world_ns’ program is linked to address 0x10000: the vector table and code gets placed at this address:

Non-Secure Memory Settings

Non-Secure Memory Settings

Secure Application

On the secure side the compiler and linker settings for TrustZone are set to ‘secure’:

Secure Linker and Compiler Settings

Secure Linker and Compiler Settings

The program and vector table is loaded at 0x1000’0000 with a ‘veneer’ table loaded at 0x1000’fe00. More about this later…

Secure Memory Allocation

Secure Memory Allocation

Debug

The non-secure application can be flashed to the device like this:

Program to Flash

Program to Flash

This basically is as if the new (non-secure) application has been programmed using a bootloader or similar way to update the application.

To be able to debug the second (non-secure) from the secure application, I have to load the symbols for it in the debugger. The secure one can now be debugged as usual:

Debug secure application

Debug secure application

In order to debug the non-secure application code when debugging the secure one, I have to add the symbols to the debugger. I can do this by editing the debug/launch configuration. Double-click on the .launch file or open the debug configuration with Run > Debug Configurations, then use the ‘Edit Scripts’ in the Debugger tab:

Edit Scripts

Edit Scripts

Add the following to load the symbols of the other project using the add-symbol-file gdb command. Adapt the path as needed, I have the other project at the same directory level.

add-symbol-file ../LPC55S69_hello_world_ns/Debug/LPC55S69_hello_world_ns.axf 0x10000

to tell the debugger that the symbols of that application are loaded at the address 0x10000. Insert that after the ${load} command:

Adding Symbols after Load

Running the application produces the following output:

Console Output

Console Output

Security State Transitions

The ARMv8-M architecture has added instructions to transition between the security states. For example the BLXNX instruction is used to call a non-secure function from the secure world:

Security State Transition

Security State Transition (Source: ARM, Trustzone technology for ARMv8-M Architecture)

Calling a Non-Secure Function from the Secure World

The main() of the secure application is like below. It could be the base of a bootloader which jumps to the non-secure loaded application at address 0x1’0000:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define NON_SECURE_START          0x00010000
 
/* typedef for non-secure callback functions */
typedef void (*funcptr_ns) (void) __attribute__((cmse_nonsecure_call));
 
int main(void)
{
    funcptr_ns ResetHandler_ns;
 
    /* Init board hardware. */
    /* attach main clock divide to FLEXCOMM0 (debug console) */
    CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
 
    BOARD_InitPins();
    BOARD_BootClockFROHF96M();
    BOARD_InitDebugConsole();
 
    PRINTF("Hello from secure world!\r\n");
  
    /* Set non-secure main stack (MSP_NS) */
    __TZ_set_MSP_NS(*((uint32_t *)(NON_SECURE_START)));
  
    /* Set non-secure vector table */
    SCB_NS->VTOR = NON_SECURE_START;
     
    /* Get non-secure reset handler */
    ResetHandler_ns = (funcptr_ns)(*((uint32_t *)((NON_SECURE_START) + 4U)));
      
    /* Call non-secure application */
    PRINTF("Entering normal world.\r\n");
    /* Jump to normal world */
    ResetHandler_ns();
    while (1)
    {
        /* This point should never be reached */
    }
}

The line with

__TZ_set_MSP_NS(*((uint32_t *)(NON_SECURE_START)));

loads the non-secure MSP (Main Stack Pointer). The debugger nicely shows both the secure and non-secure registers which are ‘banked’:

non-secure MSP

non-secure MSP

The following will call the non-secure world from the secure one:

ResetHandler_ns();

This a function pointer with the cmse_nonsecure_call attribute:

1
2
/* typedef for non-secure callback functions */
typedef void (*funcptr_ns) (void) __attribute__((cmse_nonsecure_call));

Non-Secure functions can only be called from the secure world using function pointers, as a result dividing the secure from t

Behind that function call there are several assembly instructions executed. It clears the LSB of the function address and clears the FPU Single Precision registers, or any registers which could contain ‘secret’ information. At the end it calls the library function __gnu_cmse_nonsecure_call:

non-secure call sequence

non-secure call sequence

The __gnu_cmse_nonsecure_call does push the registers and does more register cleaning and uses the BLXNS assembly instruction to finally enter the non-secure world:

__gnu_cmse_nonsecure_call

__gnu_cmse_nonsecure_call

So there are quite a few instructions to be executed to make that transition.

Calling the Secure World from the non-secure World

Calling a secure function from the non-secure side uses an intermediate step (Non-secure Callable):

armv8_m_architecture_trustzone_technology_100690_0101_00_en

Calling secure Function from non-secure side (Source: ARM, Trustzone technology for ARMv8-M Architecture)

In the example the non-secure world is calling a printf function (DbgConsole_Printf_NSE) which is located in the secure world:

Calling printf from the non-secure world

The secure functions which are callable from the non-secure world hae to be marked with the cmse_nonsecure_entry attribute:

 CMSE stands for Cortex-M (ARMv8-M) Security Extension

Function with cmse_nonsecure_entry attribute

Function with cmse_nonsecure_entry attribute

So how does the non-secure world know how to call this function? The answer is that the linker prepares everything to make it possible. For this the non-secure application has to link an object file (or ‘library’) with the ‘veneer’ functions:

Linking CMSE Lib Object File

Linking CMSE Lib Object File

This object file (or library) is created with the following linker setting on the secure side:

--cmse-implib --out-implib=hello_world_s_CMSE_lib.o
Secure gateway library linker command

Secure gateway library linker command

So let’s follow the code from the non-secure to the secure world: The assembly calls a ‘veneer’ function:

calling printf veneer

calling printf veneer

The veneer is a simply ‘trampoline’ function which loads the address for the ‘non-secure callable’ and does a BX to that address:

BX to non-secure callable

BX to non-secure callable

The ‘secure non-callable’ area is in the ‘secure world’ with a SG instruction as the first one to be executed, followed by a branch.

SG Instruction in non-secure callable region

SG Instruction in non-secure callable region

The SG (Secure Gateway) instruction switches to the secure state followed by the B (Branch) instruction to the secure function itself:

Executing Secure Function

Executing Secure Function

Compared to calling the unsecure side from the secure world this was rather fast. The clearing of all the registers because they can contain secret information is done just before the BXNS returns to the non-secure state:

Clearing registers on return to non-secure state

Clearing registers on return to non-secure state

SAU Setup

So how is the protection configured? For this the SAU (Secure Attribution Unit) is configured which only can be done on the secure side.

The example uses the following secure and non-secure code and data areas:

1
2
3
4
5
6
#define CODE_FLASH_START_NS         0x00010000 
#define CODE_FLASH_SIZE_NS          0x00062000
#define CODE_FLASH_START_NSC        0x1000FE00
#define CODE_FLASH_SIZE_NSC         0x200
#define DATA_RAM_START_NS           0x20008000
#define DATA_RAM_SIZE_NS            0x0002B000

In the example this is configured in BOARD_InitTrustZone(). The following setting configures a region for the non-secure FLASH execution:

1
2
3
4
5
6
7
8
9
10
11
/* Configure SAU region 0 - Non-secure FLASH for CODE execution*/
/* Set SAU region number */
SAU->RNR = 0;
/* Region base address */  
SAU->RBAR = (CODE_FLASH_START_NS & SAU_RBAR_BADDR_Msk);
/* Region end address */
SAU->RLAR = ((CODE_FLASH_START_NS + CODE_FLASH_SIZE_NS-1) & SAU_RLAR_LADDR_Msk) |
             /* Region memory attribute index */
             ((0U >> SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) |
             /* Enable region */
             ((1U >> SAU_RLAR_ENABLE_Pos) & SAU_RLAR_ENABLE_Msk);

The IDAU (Implementation Defined Attribution Unit) is optional and is intended to provide a default access memory map (secure, non-secure and non-secure-callable) which can be overwritten by the SAU.

Summary

It probably will take me some more time to understand the details of the ARMv8-M security extensions.There are more details to explore such as secure peripheral access or how to protect memory areas. In a nutshell, it allows to partition the device into ‘secure’/trusted and ‘unsecure’/not-trusted and divides the memory map into secure, non-secure and non-secure-callable with the addition of MPU and controlled access to peripherals. Plus there is the ability to control the level of debugging to prevent reverse engineering.

With the NXP MCUXpresso SDK and IDE plus the LPC55S69 board I have a working environment I can use for my experiments. I like the approach that basically the non-secure application does need to know about the fact that it is running in a secure environment, unless it wants to call functions of the secure world.

I have now FreeRTOS working on the LPC55xx with the FreeRTOS port for M33, but I’m using it in the ‘non-secure’ world. My goal is to get the RTOS running on the secure side. Not sure yet how exactly this will look like, but that’s a good use case I want to explore in the next week if time permits.

 

Happy Securing :-)

Links

- - -

Originally published on April 27, 2019 by Erich Styger

This article covers the NXP LPC55S69-EVK board: a dual ARM Cortex-M33 running at 100 MHz with ARM TrustZone:

LPC55S69 Microcontroller

LPC55S69 Microcontroller

 

The LPC55S69 is of special interest because it is one of the new ARM Cortex-M33 which implements new ARM Trustzone security features: with this feature it is possible to run ‘trusted’ and ‘untrusted’ code on the same microcontroller.

LPC88S6x Block Diagram

LPC55S6x Block Diagram

 

LPC55S6x Block Diagram

LPC55S6x Block Diagram (Source: NXP LPC55X6x Datasheet)

 

The following table from ARM (https://developer.arm.com/ip-products/processors/cortex-m/cortex-m33) gives an overview of the Cortex-M33 (Armv8-M) architeture:

Feature Cortex-M0Cortex-M0+Cortex-M1Cortex-M23Cortex-M3Cortex-M4 Cortex-M33Cortex-M35P Cortex-M7 
Instruction set architecture Armv6-MArmv6-MArmv6-MArmv8-M BaselineArmv7-MArmv7-MArmv8-M MainlineArmv8-M MainlineArmv7-M
Thumb, Thumb-2Thumb, Thumb-2Thumb, Thumb-2Thumb, Thumb-2Thumb, Thumb-2Thumb, Thumb-2Thumb,
Thumb-2
Thumb,
Thumb-2
Thumb,
Thumb-2
DMIPS/MHz range*0.87-1.270.95-1.360.80.991.25-1.891.25-1.951.51.52.14-3.23
CoreMark®/MHz**2.332.461.852.53.343.424.024.025.01
Pipeline stages323233336
Memory Protection Unit (MPU) NoYes (option)NoYes (option)
(2 x)
Yes (option)Yes (option)Yes (option)
(2 x)
Yes (option)
(2 x)
Yes (option)
Maximum MPU regions 0801688161616
Trace (ETM or MTB)NoMTB (option)NoMTB (option) or
ETMv3 (option)
ETMv3 (option)ETMv3 (option)MTB (option) and/or
ETMv4 (option)
MTB (option) and/or
ETMv4 (option)
ETMv4 (option)
DSP NoNoNoNoNoYesYes (option)Yes (option)Yes
Floating point hardware NoNoNoNoNoYes (option SP)Yes (option SP)Yes (option SP)Yes
(option SP + DP)
Systick TimerYes (option)Yes (option)Yes (option)Yes (2 x)YesYesYes (2 x)Yes (2 x)Yes
Built-in Caches NoNoNoNoNoNoNoYes (option 2- 16kBYes (option 4-64kB
 I-cacheI-cache, D -cache)
Tightly Coupled Memory NoNoYesNoNoNoNoNoYes
(option 0-16MB
I-TCM/D-TCM)
TrustZone for Armv8-MNoNoNoYes (option)NoNoYes (option)Yes (option)No
Co-processor interface NoNoNoNoNoNoYes (option)Yes (option)No
Bus protocolAHB LiteAHB Lite, Fast I/OAHB LiteAHB5, Fast I/OAHB Lite, APBAHB Lite, APBAHB5AHB5AXI4, AHB Lite, APB, TCM
Wake-up interrupt controller supportYesYesNoYesYesYesYesYesYes
Integrated interrupt controllerYesYesYesYesYesYesYesYesYes
Maximum # external interrupts
323232240240240480480240
Hardware divideNoNoNoYesYesYesYesYesYes
Single cycle multiplyYes (option)Yes (option)NoYesYesYesYesYesYes
CMSIS SupportYesYesYesYesYesYesYesYesYes

(ARM Cortex-M Comparison Table: Source ARM).

Unboxing

I ordered my board from Mouser for CHF 43. The board came in nice card box:

LPC55S69-EVK Box

LPC55S69-EVK Box

The content (apart of some stuffing material) is the board itself plus a small bag with 4 jumpers:

LPC55S69-EVK Board

LPC55S69-EVK Board (Top Side)

LPC55S69-EVK Board Bottom Side

LPC55S69-EVK Board Bottom Side

The board includes a LPC4322 (Link2) based debug probe:

LPC55S69-EVK Board Components

LPC55S69-EVK Board Components (Source: Board Manual)

Software and Tools

On https://mcuxpresso.nxp.com there is the MCUXpresso SDK for the board available for download:

MCUXpresso SDK for 55S69

MCUXpresso SDK for 55S69

I have downloaded the latest version 2.5.1 (released mid of April 2019):

SDK 2.5.1

SDK 2.5.1

As IDE I’m using the NXP MCUXpresso IDE 10.3.1. The SDK gets installed by Drag&Drop into the Installed SDK’s view:

Installed SDK in MCUXpresso IDE

With the SDK installed, I can quickly create a new project or import example projects:

Quickstart Panel

Quickstart Panel

SDK Wizard

SDK Wizard

FreeRTOS

The SDK V2.5.1 comes with a FreeRTOS V10.0.1 port which runs out of the box, using the M4 port.

Debugging FreeRTOS on LPC55S69

Debugging FreeRTOS on LPC55S69

In the McuOnEclipse FreeRTOS port I’m already using FreeRTOS 10.2.0, so this is something I have to soon too.

Configuration Tools

The IDE comes with the NXP MCUXpresso Configuration Tools integrated.

With the graphical configuration tools I can create pin muxing and clock configurations:

Pins Tool

Pins Tool

Clocks Tool

Clocks Tool

Secure and Non-Secure

The SDK comes with demos using secure + non-secure application parts. To make it easy, the projects have TrustZone settings for the compiler and linker:

TrustZone Project Settings

TrustZone Project Settings

 

I have started playing with TrustZone, but this is subject of a follow-up article.

Erase Flash

Dealing with a ARM Cortex-M33 multicore device for sure is a bit more complex than just using an old-fashioned single Core M0+. Because of the secure and non-secure features, it might be necessary to get things back into a clean state. So this is what worked best for me:

  1. Have a non-secure and simple project present in the workspace. I’m using the ‘led_blinky’ from the SDK examples.

     

    LED Blinky

    LED Blinky

  2. Power the Board with IP5 USB connector (P5: cable with the yellow dot) and debug it with the onboard LPC-Link2 connector (P6).

     

    LPC55S69 Power and Debug

    LPC55S69 Power and Debug

  3. With that project selected, erase the flash using the action in the Quickstart Panel.

     

    Erase Flash Using Linkserver

    Erase Flash Using Linkserver

  4. Select core 0 for the erase operation:

     

    Select core for Flash Erase

    Select core for Flash Erase

  5. This should work without problems.PressOK the dialog:

     

    Operation Successful

    Operation Successful

  6. At this point I recommend to disconnect and re-connect the P6 (Debug) cable.
  7. Now I can program the normal application again:

     

    Programming Blinky

    Programming Blinky

With this I have a working and known state for my experiments.

Summary

The Easter break is coming to an end and has been interesting at least to say. The NXP LPC55S69-EVK is very appealing: the board is reasonably priced and with all the connectors it is a good way to evaluate the microcontroller. The most interesting thing is that it has a dual-core ARM-Cortex M33 with the ARM TrustZone implementation. To be able to run ‘trusted’ and ‘untrusted’ (e.g. user code) on the same device could be one of the standard models of microcontroller going forward, especially in the ‘internet of things’ area. So I think I have to explore this device and board and its capabilities in at least one follow-up article?

 

Happy Trusting :-)

 

Links

- - -

Originally published on April 22, 2019 by Erich Styger

I really love tiny and bread board friendly boards, especially if they are very affordable and can be use with Eclipse based tools. So I was excited to see the NXP LPC845-BRK board to be available at Mouser, so I ended up ordering multiple boards right away. Why multiple? Because they only cost CHF 5.95 (around $6)!

NXP LPC845-BRK Board

NXP LPC845-BRK Board

 

The boards arrived yesterday, so it is a perfect timing to have them (and more of it) integrated into the next semester university course material. So you will probably see a few more tutorials for this board.

lpc845-brk boards

 

Unboxing

The kit comes in a solid card box with:

  • the LPC845-BRK board
  • two 10pin headers
  • Micro USB cable
  • a smalls screwdriver
  • two 2pin jumpers and headers
  • getting started reference card
lpc845-brk kit content

 

The board works out of the box and does not need any soldering, and the headers are provided in case I want to customize the board. I like the fact that the headers are supplied, plus I’m free what I want to solder to the board. Plus I can use different headers if I want to. I was puzzled by the screwdriver (what for?) until I realized that there is small potentiometer on the board :-).

LPC845-BRK Board

The main MCU on the board is the LPC845 in QFN48 package ( LPC845M301JBD4), an ARM Cortex-M0+, 30 MHz, 64 KB FLASH and 16 KB SRAM):

LPC84x Block Diagram

 

The board has a ‘break-apart’ touch area: if I don’t need it, I can make the board smaller. it includes a potentiometer, an RGB LED, three push buttons (Reset, user and ISP). Plus most important: the LPC11U35 acting as a debug probe:

LPC845-BRK Board Components

 

I can use the LPC845 with an external debug probe: for this I have to solder a jumper plus the 2×5 header. All the three buttons can be used as user buttons, so technically there are three of them. There is as well a jumper for an ammeter to measure the current used.

Software and Tools

There is no dedicated MCUXpresso SDK for that board (yet?), so I have downloaded the one for the device from http://mcuxpresso.nxp.com/:

SDK for LPC845

 

With drag&drop I added it to the NXP MCUXpresso IDE 10.3.0:

Installed SDK for LPC845

 

On the LPC845-BRK web site there is a zip file with examples which I have imported into the MCUXpresso IDE:

examples

 

When plugged in, the board enumerates with a virtual COM port which is a gateway to the LPC845 UART:

Virtual COM Port

 

I was able to debug the board out of the box, the board is recognized as CMSIS-DAP debug probe:

linkserver

 

And voilà: I’m debugging it 

Debugging with MCUXpresso IDE

 

Summary

I really like that board. It is of good quality with a lot of value. It has a on-board debugger and even the possibility to use it directly with a J-Link or P&E Multilink if I wish so. The board is small, can be hooked on a bread board and can be made even smaller with removing the touch pad. The Cortex-M0+ is not the fastest and biggest MCU on the planet, but provides enough processing power for many smaller applications. I plan to follow-up with more tutorials in the next days and weeks. Until then, see the tutorials listed in the Links section below.

List of articles about the LPC845-BRK board:

Happy BRKing  :-)

 

Links

 

- - -

Originally published on January 31, 2019 by Erich Styger

The LPC845-BRK is a great tiny sub-$6 breakout board featuring the LPC845M301JBD4 MCU:

  • ARM Cortex-M0+
  • 30 MHz, 64 KByte FLASH, 16 KByte SRAM
  • On-board CMSIS-DAP debug interface, works out-of-the-box with NXP MCUXpresso IDE or other 3rd party IDEs
  • 3 push buttons (user, RESET, ISP)
  • RGB LED
  • Potentiometer

NXP LPC845-BRK Board

Reference Material

 

Community Projects and Articles

Below you can find a lists of community post, blog and articles around this great board:

 

 

Post a comment if you have found another article or project to be added to this list!

 

Enjoy!

Erich

LPCScrypt v2.1 is now available. This release incorporates bug fixes and the latest versions of LPC-Link2 CMSIS-DAP firmware.

 

LPCScrypt is a command-line based, fast flash (internal and QSPI), EEPROM, OTP and security programming tool for LPC1800 and LPC4300 series microcontrollers. It is also the primary delivery mechanism for supplying and programming CMSIS-DAP firmware images for LPC-Link2 and LPCXpresso Boards.

 

Yours,

 

MCUXpresso IDE Support

We've been working on making the flagship member of the LPC800 series more accessible to more users than ever before, and are delighted to announce the LPC845 Breakout Board is now available from our distribution partners and also direct from nxp.com! Setting a new price point for a fully featured, debug enabled platform, this board includes CMSIS-DAP compatible debug and a VCOM port in a very compact yet flexible form factor. Of course it can be used with MCUXpresso IDE, Keil, IAR and other popular tools.

 

MCUXpresso SDK based examples are available now, and you will have seen some examples of interfacing to MEMS sensors, LDRs, SPI displays and a UART GPS module already on this site, all using commonly available from Adafruit and distributors.

 

Keen LPC user Kevin Townsend has been working on some other, more complex projects that he's posted on his github and on hackster.io ... an I2C co-processor for Raspberry Pi and today a fun smart Jenga block. He tells me he has another project one the way next week, so keep a look out for that!

 

We hope you enjoy this new board and, as always, we love to hear what you think and what you create!

Using SDK drivers for LPC845 Breakout Board, this project measures the ambient light intensity by using LDR (Light Dependent Resistor). The voltage values from LDR are read through an ADC. The new LPC845 Breakout board has an SDK support which makes it a lot easier to interface an LDR for measuring light intensity compared to the conventional coding style. I have used the MCUXpresso IDE for modifying the pins and clock configuration settings.
The project requires a resistor and LDR (Light Dependent Resistor)/Photoresistor in a resistor divider circuit as shown below:
ldr-circuit.jpg

The value of R1 here is 4.4Kohm. 

The output of this resistor divider circuit is connected to the assigned ADC channel. In this application, I have assigned it to the ADC0_8 channel which is the PIO0_18 (pin 3) and configured it accordingly in the software.
Components used: LPC845 Breakout Board, Light Dependent Resistor(LDR)/Photoresistor, 2.2Kohm resistor (Quantity:2)
LPC845 Breakout Board connections to the LDR are as shown:
LPC845LDR
Pin NameBoard LocationPin Name
ADC_8PIO0_18 (CN1-3)resistor divider o/p
VCCCN1-40LDR
GNDCN1-204.4k resistor
image.png
For this application, I have used ADC0_8 as the ADC channel which converts the LDR output analog voltage values to digital values. The values printed on the console window reflect the change in the light intensity.
(For testing purposes, the light intensity can be changed by covering the LDR or using a cellphone flash)
The LPC845 Breakout board has an SDK package support. I used the ADC SDK driver API in the software for interfacing the hardware components. The MCUXpresso SDK Builder has open source drivers, middleware, and reference example applications for software development. Customize and download the SDK specific to the processor and then import the zip file to the project in MCUXpresso IDE.
                                                                                                                                                                            
The LPC845 Breakout board also features function-configurable I/O ports through a switch matrix (SWM). This makes it easier to configure pin routing and other pin electrical features. The configuration tool which is integrated into the IDE is useful for making changes in the switch matrix. The source code is auto-generated when the pin configuration or peripherals are changed.
 
/* ADC_CHN8 connect to P0_18 */
SWM_SetFixedPinSelect(SWM0, kSWM_ADC_CHN8, true);
The source code for this application and board info for the LPC845 Breakout board can be found here.
int main(void)
{
/* Initialize board hardware. */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
/* Configure the converter and work mode. */
ADC_Configuration();
while(1)
{
/* Trigger the sequence's conversion by software */
ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);
/* Wait for the converter to be done. */
while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &adcResultInfoStruct))
{
}
/* Display the conversion result */
PRINTF("adcResult = %d\r\n", adcResultInfoStruct.result);
}
}

The new LPC845 breakout board has 3 onboard LEDs- Red, Green, and Blue. The brightness of these LEDs can be controlled using a PWM signal by changing the duty cycle values for each of them. As this board has an SDK support, I have used the SDK drivers to implement this application. 

The SCTimer0 generates the PWM pulse at pins which are assigned as the SCT output pins. I have assigned the PWM output to the Green LED (PIO1_0) in my source code. You can assign the PWM output to be on any other LED by using the inbuilt configuration tool which is explained later. 

 

The source code below shows how to set the duty cycle percentage to increase or decrease the brightness of the assigned LED (here I have set it to 60%) 

 

pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = 60;

Writing the source code for this application was easy as the LPC845 Breakout board has an SDK package support. I used the SCT (Sctimer) SDK driver API in the software. The MCUXpresso SDK Builder has open source drivers, middleware, and reference example applications for software development. Customize and download the SDK specific to the processor and then import the zip file to the project in MCUXpresso IDE.
                                                                                                                                                                                               
The LPC845 Breakout board also features function-configurable I/O ports through a switch matrix (SWM). This makes it easier to configure pin routing and other pin electrical features. The configuration tool which is integrated into the IDE is useful for making changes in the switch matrix. The source code is auto-generated when the pin configuration or peripherals are changed.
/* SCT_OUT2 connect to P1_0 */
SWM_SetMovablePinSelect(SWM0, kSWM_SCT_OUT2, kSWM_PortPin_P1_0);
 
The source code for this application and board info for the LPC845 Breakout board can be found here.
I have built an application to interface an accelerometer with the new LPC845 Breakout board using the I2C SDK driver.
The accelerometer acts as an I2C slave device to the LPC845 master device. Colors on the on-board RGB LED change according to the accelerometer position.
 
The accelerometer is a slave device in this application with slave address: 0x1D. The position of the board is determined by the x,y,z-axis values obtained from this slave device. The change in these x,y,z values detects the movement of the LPC845 Breakout board. I have assigned various patterns to the RGB LEDs for each movement along the y-axis. 

 

Refer to the table for the hardware Connections for this application:
The NXP MMA8652 3-axis accelerometer on the breakout board can be connected using I2C protocol. SCL, SDA lines and can be powered via VDD, VDDIO and GND pins.

Connect pins of I2C master and slave as below:
MasterSlave
Pin NameBoard LocationPin NameBoard Location
SCL CN1-23SCL J2-3
SDACN1-22SDAJ2-4
VCCCN1-40VDD/VDDIOJ1-3/4
GND CN1-20GND J1-5

The LPC845 Breakout board has an SDK package support. I used the I2C SDK driver API in the software for interfacing the hardware components. The MCUXpresso SDK Builder has open source drivers, middleware, and reference example applications for software development. Customize and download the SDK specific to the processor and then import the zip file to the project in MCUXpresso IDE.
                                                                                                                                                                                               
The LPC845 Breakout board also features function-configurable I/O ports through a switch matrix (SWM). This makes it easier to configure pin routing and other pin electrical features. The configuration tool which is integrated into the IDE is useful for making changes in the switch matrix. The source code is auto-generated when the pin configuration or peripherals are changed.
/* I2C0_SDA connect to P0_11 */
SWM_SetFixedPinSelect(SWM0, kSWM_I2C0_SDA, true);

 

/* I2C0_SCL connect to P0_10 */
SWM_SetFixedPinSelect(SWM0, kSWM_I2C0_SCL, true);
 
The source code for this application and board info for the LPC845 Breakout board can be found here.

The LPC546xx IAP EEPROM Write page API  does not enable the EEPROM clock for the write operation. This causes  EEPROM write operation to fail when using the IAP API.  This problem does not occur for IAP Read EEPROM page command.

 

The workaround is to enable the EEPROM clock  ( set bit 9) in AHBCLKCTRL0 register of SYSCON before calling the IAP EEPROM write function.

 

SYSCON->AHBCLKCTRL[0] |= 0x200;


Hi folks,


Attached is a sample source code for OTP programming in NXP LPC54018 MCU.


Brief about the example:

The example programs 4 words of data each into OTP bank 1 and OTP bank 2. The example uses LPC54018 SDK drivers. The complete SDK for LPC54018 can be downloaded from Welcome | MCUXpresso SDK Builder .


Hope this is helpful !


Best Regards,

 

NXP lpc54018

If you are searching for a high-performance, power efficient, yet cost sensitive MCU for your designs, then here is the exciting news: NXP recently introduced the LPC51U68 MCU.

 

Power efficient solution for future IoT designs

Based on the Arm® Cortex®-M0+ core, the LPC51U68 MCU pushes the performance of the core to 100MHz, which is more than two times faster than current Cortex-M0+-based products. The LPC51U68 MCU also provides expanded memory resources of up to 96KB on-chip SRAM and 256 KB on-chip flash programming memory with flash accelerator. It also features unparalleled design flexibility and integration including a USB 2.0 full-speed device controller supporting crystal-less operations, eight flexible serial communication peripherals, each of which can be enabled as UART, SPIs or I2C and up to two I2S interfaces. The LPC51U68 MCU integrates a variety of timers including three general purpose timers, one versatile timer with PWM (SCTimer/PWM), one RTC/alarm timer, a multi-rate timer and watchdog timers. On the analog side, an on-chip 12-channel ADC with a 12-bit resolution and conversion rates at up to 5Msps and temperature sensors are provided. With all the features integrated, the LPC51U68 MCU brings unparalleled design flexibility, computing performance and integration into today’s demanding IoT and industrial applications.

 

LPC51U68 Block Diagram

 

Extraordinary compatibility

While considering the LPC51U68 MCU as an upgrade of the LPC11U68 MCU family, it provides pin-function compatibility with Arm® Cortex®-M4 based LPC5410x and LPC5411x MCU families in the same packages and pinout versions enabling a smooth transition to the power-efficient MCUs based on Arm® Cortex®-M4 core.

 

Low power design for energy efficiency

While providing excellent computing power with the Arm Cortex-M0+ core, the LPC51U68 MCU displays ultra-low-power consumption and a unique low-power design. The microcontroller supports four low-power modes and API-driven power profiles, providing developers with easy-to-use dynamic current management at runtime and fast wake-up times from the microcontroller’s reduced power modes.

 

LPC51U68 Run Currents and Extended Power Modes

 

Make your design easier with tools supported

LPC51U68 MCUs are fully supported by NXP’s MCUXpresso software and tools which brings together the best of NXP’s software enablement into one enablement platform for a shared software experience across a broader set of Arm® Cortex®-M MCUs. In addition, this new MCU is supported by the LPCXpresso51U68 development board, designed to enable evaluation and prototyping with the LPC51U68 MCU. The board features an on-board, CMSIS-DAP / SEGGER J-Link compatible debug probe, expansion options based on Arduino UNO and PMod, plus additional expansion port pins and more

 

LPCXpresso51U68 Development Board

 OM40005: LPC51U68 Development Board

To learn more about LPC51U68 MCU, visit http://www.nxp.com/LPC51U68http://www.nxp.com/LPC51U68

 

Live at Computex 2018 this week is: The High Performance Gaming Mouse Controlling Hundreds of Full Color LEDs Powered by LPC51U68

  • A 100MHz Arm® Cortex®-M0+ delivering real-time response for game player
  • 96K SRAM for LED pattern allows for a smooth transition 
  • Built-in USB drivers in ROM and supports 1K report rate
  • 8 Flexcomm serial channels to drive up to 800 LEDs with full color control at the same time

 

 

@jennymplunkett from the Arm mbed team just posted a great tutorial using the LPCXpresso54608 touch screen on her blog... check it out at https://os.mbed.com/blog/entry/How-to-LPCXpresso54608-touch-panel/

Same code shown will also run on LPCXpresso54628.

 

Thanks Jenny!