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.
NXP emWin Touch & Draw demo on an LPCXpresso54608.
Pre-requisites
You will need to have the following software and equipment for this tutorial:
- Mbed CLI
- GCC ARM toolchain
- A serial terminal viewer (i.e.
screen
, Tera Term, PuTTY, etc.) - LPCXpresso54608 board
Get NXP's example
First you will need to download NXP's example program:
- Navigate to NXP's example projects page
- Create an NXP account and sign in
- Select "GCC ARM Embedded" from the Toolchain dropdown
- Select "emwin_examples"
- Select "emwin_touch_and_draw"
- Click Download Example (then save the
emwin_touch_and_draw.zip
file to your computer) - Extract the
emwin_touch_and_draw.zip
file to a location on your computer.
Create a new Mbed OS project
- Create a new folder on your computer
- Open the folder's directory in your command-line
- 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.
- Navigate to NXP's emWin Graphics Library Downloads page
- Under "Libraries" click on the Download button next to "emwin 5.30c Pre-Compiled Libraries for NXP ARM MCUs"
- Click "I Accept" then save the
NXP_emWin530c_libraries.exe
to your computer - 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:
- Within the
NXP_emWin530c_libraries
folder, copy the file from the following location:NXP_emWin530c_libraries/emWin_library/LPCXpresso/libemWin_M4F.a
- With the file copied, navigate to the following folder within your Mbed OS Project:
/emwin/emWin_library/ARMGCC/
- 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.
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