How to use emWin with Mbed OS


As a follow-up to my previous blog post, this tutorial will show you how to utilize the emWin graphics library for use with Mbed OS by utilizing NXP's emWin demo applications on an LPCXpresso54608 board.

/media/uploads/jplunkett/emwin-image.jpg NXP emWin Touch & Draw demo on an LPCXpresso54608.

Pre-requisites

You will need to have the following software and equipment for this tutorial:

  1. Mbed CLI
  2. GCC ARM toolchain
  3. A serial terminal viewer (i.e. screen, Tera Term, PuTTY, etc.)
  4. LPCXpresso54608 board

Get NXP's example

First you will need to download NXP's example program:

  1. Navigate to NXP's example projects page
  2. Create an NXP account and sign in
  3. Select "GCC ARM Embedded" from the Toolchain dropdown
  4. Select "emwin_examples"
  5. Select "emwin_touch_and_draw"
  6. Click Download Example (then save the emwin_touch_and_draw.zip file to your computer)
  7. Extract the emwin_touch_and_draw.zip file to a location on your computer.

Create a new Mbed OS project

  1. Create a new folder on your computer
  2. Open the folder's directory in your command-line
  3. Run mbed new .

Then with your favorite text-editor, create a main.cpp file in the root of your new Mbed OS project.

Porting NXP's example to Mbed OS

In order to successfully compile and flash the touch cursor demo app to the LPCXpresso54608 board using Mbed CLI, we will need to make a few changes to the example code.

Copying the files

Within your extracted emwin_touch_and_draw example folder, open the the file emwin_touch_and_draw/source/emwin_touch_and_draw.c. Copy the contents of this file into your Mbed OS project's main.cpp file.

We will also need to copy the following files to our Mbed OS project, copy and paste these files as-is from the emwin_touch_and_draw directory to your Mbed OS project root folder:

  • emwin_touch_and_draw/board/board.h
  • emwin_touch_and_draw/board/emwin_support.c
  • emwin_touch_and_draw/board/emwin_support.h
  • emwin_touch_and_draw/board/pin_mux.c
  • emwin_touch_and_draw/board/pin_mux.h
  • emwin_touch_and_draw/touchpanel/fsl_ft5406.c
  • emwin_touch_and_draw/touchpanel/fsl_ft5406.h
  • emwin_touch_and_draw/emwin/ - Copy the entire folder to the root of your Mbed OS project.

In order to compile these files as part of an Mbed OS project successfully, we will also need to change the extensions of all of the .c files above to .cpp.

Your Mbed OS project's root directory should now look like the following:

emwin/
mbed-os/
board.h
emwin_support.cpp
emwin_support.h
fsl_ft5406.cpp
fsl_ft5406.h
main.cpp
mbed_settings.py
mbed-os.lib
pin_mux.cpp
pin_mux.h

Get the correct emWin library

The emWin library (libemWin_M4F.a) that we copied from the emwin_touch_and_draw example folder was pre-compiled using a compiler that is incompatible with the GCC_ARM toolchain we are using in this tutorial. So in order to successfully compile the emWin demo application with Mbed CLI and GCC_ARM we will need to swap out the emWin library with a different one.

  1. Navigate to NXP's emWin Graphics Library Downloads page
  2. Under "Libraries" click on the Download button next to "emwin 5.30c Pre-Compiled Libraries for NXP ARM MCUs"
  3. Click "I Accept" then save the NXP_emWin530c_libraries.exe to your computer
  4. Install the libraries to a location on your computer

Now that we have downloaded the emWin 5.30c pre-compiled libraries, we will need to replace the existing emWin library with the correct one in our Mbed OS project:

  1. Within the NXP_emWin530c_libraries folder, copy the file from the following location: NXP_emWin530c_libraries/emWin_library/LPCXpresso/libemWin_M4F.a
  2. With the file copied, navigate to the following folder within your Mbed OS Project: /emwin/emWin_library/ARMGCC/
  3. Paste/replace the copied file over the existing libemWin_M4F.a file

Creating a safe printf

Because the NXP examples use a special "debug console", we will also need to create the following files within our Mbed OS project:

Create a new file stdio_thread.cpp with the following contents:

#include <stdarg.h>
#include <stdio.h>
#include "mbed.h"

#include "stdio_thread.h"

Mutex printf_mutex;

int safe_printf(const char *format, ...) {

    printf_mutex.lock();

    va_list args;
    va_start(args, format);
    int num_bytes = vprintf(format, args);

    va_end(args);
    printf_mutex.unlock();

    return num_bytes;
}

Also create a new header file stdio_thread.h with the following contents:

#ifndef __STDIO_THREAD_H__
#define __STDIO_THREAD_H__

int safe_printf(const char *format, ...);

#endif // __STDIO_THREAD_H__

This stdio_thread class allows for the safe usage of printf during the touch panel's touch event interrupts (i.e. to be able to print without overwriting the other simultaneous calls to printf).

Because we are no longer using NXP's fsl_debug_console.h, you will need to remove the #include statement for this header file at the top of the following files (i.e. delete the line: #include "fsl_debug_console.h"):

  • fsl_ft5406.cpp
  • emwin_support.h
  • main.cpp

In addition to removing this #include statement, we will also need to add the following #include at the top of fsl_ft5406.cpp: #include "fsl_i2c.h" (this is so the touch panel code knows that we are going to use the I2C driver code present in the board's mbed-os/ directory).

Modifying main.cpp for Mbed OS

First we will need to update the included files at the top of our Mbed OS Project's main.cpp file. Change the #include statements to the following:

#include "mbed.h"
#include <stdio.h>
#include <string.h>
#include "board.h"
#include "emwin_support.h"

#include "GUI.h"
#include "GUIDRV_Lin.h"
#include "BUTTON.h"

#include "pin_mux.h"
#include "fsl_sctimer.h"

Next, use find/replace to remove the following lines of code:

  • BOARD_InitDebugConsole();
  • CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

Because we will be disabling the APP LCD IRQ handler in the next section, in order for the GUI to properly update and display the user's touchscreen drawings on the LCD screen we need to remove the calls to the GUI's multi-buffering functions. Use find/replace to remove the following lines of code:

  • GUI_MULTIBUF_Begin();
  • GUI_MULTIBUF_End();

Modifying emwin_support.cpp for Mbed OS

First, add an #include statement to the top of the emwin_support.cpp file so the code can successfully use our new safe_printf function: #include "stdio_thread.h"

Your #include statements should now look like the following:

#include "GUI.h"
#include "WM.h"
#include "GUIDRV_Lin.h"
#include "emwin_support.h"
#include "stdio_thread.h"

#include "fsl_gpio.h"
#include "fsl_lcdc.h"
#include "fsl_i2c.h"
#include "fsl_ft5406.h"

Next, use find/replace to remove the following line of code: NVIC_EnableIRQ(APP_LCD_IRQn);

We will also need to redirect all PRINTF statements to our new safe_printf method. Use find/replace to change all calls to PRINTF with safe_printf. For example: change PRINTF("LCD init failed\n"); to safe_printf("LCD init failed\n");.

Building the example

Within your command-line, navigate to your Mbed OS project directory. Make sure your LPCXpresso54608 is plugged into the computer. Compile and flash the program to your board with the following command: mbed compile -t GCC_ARM -m LPC546XX -f. Once the program has successfully flashed to the board, "reset" your board by pressing it's reset button or by unplugging it from your computer and plugging it back in.

Viewing the serial output

To view the output of the safe_printf() calls we added to the emwin_support.cpp file, you will need to open your board's serial port in a serial terminal viewer.

With your board plugged into your computer, open your command-line and run the following command within your Mbed OS project directory: mbed detect. This command will show you what serial port your board is connected to on your computer. Open up your serial terminal viewer to this port (I am using MacOS's screen on the command-line) to view the safe_printf() output.

/media/uploads/jplunkett/emwin-fun.jpg An emWin drawing on the LPCXpresso54608 board.

The demo application should now be running, and you're done!

You need to log in to post a discussion