emWin User Guide & Reference Manual
Graphic Library with Graphic User Interface
Document: UM03001
Software Version: 6.50
Document revision: 0
Introduction to emWin
This introduction gives some information about this document. It also gives an overview of what features
emWin consists of and what it requires.
Purpose of this document
This guide describes how to install, configure and use the emWin graphical user
interface for embedded applications. It also explains the internal structure of the
software and all the functions which are offered by emWin and intended for direct
use (API, Application Programming Interface). Before actually using emWin, you
should read or at least glance through this manual in order to become familiar with
the software. The following steps are recommended:
- Copy the emWin files to your computer.
- Go through the chapter Getting Started
- Use the simulator in order to become more familiar with what the software can do (refer to the chapter Simulation).
- Expand your program using the rest of the manual for reference.
Requirements
A target system is not required in order to develop software with emWin; most of the
software can be developed using the simulator. However, the final purpose is usually
to be able to run the software on a target system.
Target system (hardware)
Your target system must:
- Have a CPU (16/32 bits)
- Have a CPU with 64 bits (LP64 and LLP64 data model)
- Have a minimum of RAM and ROM
- Have a full graphic display (any type and any resolution)
The RAM needs to be 8-, 16- and 32-bit accessible. Memory requirements vary
depending on which parts of the software are used and how efficient your target
compiler is. It is therefore not possible to specify precise values, but the following
applies to typical systems.
Small systems (no Window Manager)
- RAM: 2 KBytes *
- Stack: 600 Bytes *
- ROM: 10-25 KBytes *
Big systems (including Window Manager and widgets)
- RAM: 20 KBytes *
- Stack: 1200 Bytes *
- ROM: 30-120 KBytes *
* Depending on the functionality used.
The numbers above are only a rough estimation and can not reflect the exact requirements of an application.
RAM requirement can be increased significantly when using large memory devices or when drawing PNG images.
ROM requirements increase according to the number of fonts and/or images used in the application.
All values are rough estimates and cannot be guaranteed.
More details can be found in the chapter Performance and Resource Usage.
Note
emWin can also be compiled for 64 bit architectures using a LP64 or LLP64 data model. Within the source code of emWin 64 bit data types are defined to ensure memory is accessed properly. Depending on which compiler is used to compile emWin it can be necessary to adapt the definition of PTR_ADDR to access addresses beyond the 32 bit range.
The definition of the 64 bit data models can be found in the file Global.h which is located in the GUI\Core directory of the emWin source code. If your architecture is not covered by the defines in Global.h please make sure to define PTR_ADDR in GUIConf.h according to your architecture.
Development environment (compiler)
The CPU used is of no importance; only an ANSI-compliant C compiler complying with
at least one of the following international standard is required:
- ISO/IEC/ANSI 9899:1990 (C90) with support for C++ style comments (//)
- ISO/IEC 9899:1999 (C99)
- ISO/IEC 14882:1998 (C++)
If your compiler has some limitations, let us know and we will inform you if these will
be a problem when compiling the software. Any compiler for 16/32-bit CPUs or DSPs
that we know of can be used. A C++ compiler is not required, but can be used. The
application program can therefore also be programmed in C++ if desired.
Limitation
The code of emWin requires a ’char’ type of 8 bits. If a ’char’ is 16 bits the code of
emWin does not work right.
Features
emWin is designed to provide an efficient, processor- and display controller-independent
graphical user interface for any application that operates with a graphical
display. It is compatible with single-task and multi-task environments, with a proprietary
operating system or with any commercial RTOS. emWin is shipped as C source code.
It may be adapted to any size physical and virtual display with any display controller
and CPU. Its features include the following:
General
- Any (monochrome, grayscale or color) display with any controller supported (if the right driver is available).
- Any interface supported using configuration macros.
- May work without display controller on smaller displays.
- Display-size configurable.
- Characters and bitmaps may be written at any point on the display, not just on even-numbered byte addresses.
- Routines are optimized for both size and speed.
- Compile time switches allow for different optimizations.
- For slower display controllers, display can be cached in memory, reducing access to a minimum and resulting in very high speed.
- Virtual display support; the virtual display can be larger than the actual display.
Graphic library
- Bitmaps of different color depths supported.
- Bitmap Converter available.
- Fast line/point drawing (without floating-point usage).
- Very fast drawing of rectangles, circles, polygons and many more shapes.
- Anti-aliased drawing of shapes in different qualities.
- Sub-pixel anti-aliased rendering.
- Different drawing modes.
Fonts
- A variety of different fonts are shipped with the basic software: 4×6, 6×8, 6×9,
8×8, 8×9, 8×16, 8×17, 8×18, 24×32, and proportional fonts with pixel-heights of
8, 10, 13, 16. For more information, see chapter Fonts.
- New fonts can be defined and simply linked in.
- Only the fonts used by the application are actually linked to the resulting executable,
resulting in minimum ROM usage.
- Using the Font Converter, any font available on the host system can be converted for use in emWin.
- Scalable iType and TTF fonts are supported.
String/value output routines
- Routines to show values in decimal, binary, hexadecimal, any font.
- Routines to edit values in decimal, binary, hexadecimal, any font.
Window Manager (WM)
- Complete window management including clipping. Overwriting of areas outside a window’s client area is impossible.
- Windows can be moved and resized.
- Callback routines supported (usage optional).
- WM uses minimum RAM (approx. 50 bytes per window).
Widgets for PC-like or smartphone-like look and feel
- Widgets (window objects, also known as controls) are available. They manage their appearance and their user input themselves
and are easy to use through their API.
Touch-screen & mouse support
- For window objects such as the button widget, emWin offers touch-screen and
mouse support.
PC tools
- AppWizard for building complete applications in a WYSIWYG editor without having to write C code.
- Simulation library for Win32 environments. The source code may be purchased additionally.
- emWinView, tool for viewing the framebuffer content while debugging with the simulation.
- Bitmap Converter, for converting common image formats into formats that are optimized for emWin.
- Font Converter, for converting common font formats into formats that are optimized for emWin.
- emWinSPY, tool for viewing runtime information about an emWin application (memory status, widgets, etc).
- emWin4Web, command line tool for building emWin applications to WebAssembly which can be run in any web browser.
Complete emWin system
The diagram below shows the individual components of a complete emWin system.
Note
The touch controller components are marked as optional since they are not necessary for running emWin.
Examples and demos
To give you a better idea of what emWin can do, we have different demos available
as “ready-to-use” simulation executables that you can find here.
The source of the sample applications is located in the folder Sample.
The folder Sample\Application\GUIDemo contains an application program showing many
features of emWin. All examples are also available at www.segger.com.
Example code in this documentation is provided as code snippet, which might require further modifications.
Listed below are some of the provided demos:
Demo name | Screenshot |
Temperature Control | |
Washing Machine | |
Weather Forecast | |
AppWizard
With emWin’s tool AppWizard, users are able to create complete and ready-to-run emWin applications.
It incorporates many of emWin’s core features such as widgets, animations, language management
and motion support to be able to create stunning applications without writing any line of code.
Therefore, no knowledge of the C language is required.
More information about AppWizard can be read under AppWizard or on
our website.
Screen and coordinates
The screen consists of many dots that can be controlled individually. These dots are
called pixels. Most of the text and drawing functions that emWin offers in its API to the
user program can write or draw on any specified pixel.
The horizontal scale is called the X-axis, whereas the vertical scale is called the
Y-axis. Coordinates are denoted as a pair consisting of an X- and a Y-value (X, Y).
The X-coordinate is always first in routines that require X and Y coordinates. The upper
left corner of the display (or a window) has per default the coordinates (0,0). Positive
X-values are always to the right; positive Y-values are always down. The above graph
illustrates the coordinate system and directions of the X- and Y- axes. All coordinates
passed to an API function are always specified in pixels.
How to connect the display to the microcontroller
emWin handles all access to the display. Virtually any display controller can be supported,
independently of how it is accessed. For details, refer to the chapter Configuration.
Also, get in contact with us if your display controller is not
supported. We are currently writing drivers for all display controllers available on the
market and may already have a proven driver for the display controller that you
intend to use. It is usually very simple to write the routines (or macros) used to
access the display in your application SEGGER Microcontroller GmbH offers
the service of making these customizations for you, if necessary with your target hardware.
It does not really matter how the display is connected to the system as long as it is
somehow accessible by software, which may be accomplished in a variety of ways.
Most of these interfaces are supported by a driver which is supplied in source code
form. This driver does not normally require modifications, but is configured for your
hardware by making changes in the file LCDConf.h. Details about how to customize a
driver to your hardware as necessary are provided in the chapter Display drivers.
The most common ways to access the display are described as follows. If
you simply want to understand how to use emWin, you may skip this section.
Display with memory-mapped display controller
The display controller is connected directly to the data bus of the system, which
means the controller can be accessed just like a RAM. This is a very efficient way of
accessing the display controller and is most recommended. The display addresses are
defined to the segment LCDSEG, and in order to be able to access the display the
linker/locator simply needs to be told where to locate this segment. The location
must be identical to the access address in physical address space. Drivers are available
for this type of interface and for different display controllers.
Display with display controller connected to port / buffer
For slower display controllers used on fast processors, the use of port-lines may be
the only solution. This method of accessing the display has the disadvantage of being
somewhat slower than direct bus-interface but, particularly with a cache that minimizes
the accesses to the display, the display update is not slowed down significantly.
All that needs to be done is to define routines or macros which set or read the hardware
ports/buffers that the display is connected to. This type of interface is also supported
by different drivers for the different display controllers.
Proprietary solutions: display without display controller
The display can also be connected without an display controller. In this case, the display
data is usually supplied directly by the controller via a 4- or 8-bit shift register.
These proprietary hardware solutions have the advantage of being inexpensive, but
the disadvantage of using up much of the available computation time. Depending on
the CPU, this can be anything between 20 and almost 100 percent; with slower CPUs,
it is really not possible at all. This type of interface does not require a specific display
driver because emWin simply places all the display data into the display cache. You
yourself must write the hardware-dependent portion that periodically transfers the
data in the cache memory to your display.
Data types
Since C does not provide data types of fixed lengths which are identical on all platforms,
emWin uses, in most cases, its own data types as shown in the table below:
Data type | Definition | Description |
I8 | signed char | 8-bit signed value |
U8 | unsigned char | 8-bit unsigned value |
I16 | signed short | 16-bit signed value |
U16 | unsigned short | 16-bit unsigned value |
I32 | signed long | 32-bit signed value |
U32 | unsigned long | 32-bit unsigned value |
I16P | signed short | 16-bit (or more) signed value |
U16P | unsigned short | 16-bit (or more) unsigned value |
For most 16/32-bit controllers, the settings will work fine. However, if you have similar
defines in other sections of your program, you might want to change or relocate
them. A recommended place is in the file Global.h.
Getting Started
The following chapter provides an overview of the basic procedures for setting up and
configuring emWin on your target system. It also includes a simple program example.
If you find yourself unsure about certain areas, keep in mind that most topics are
treated in greater detail in later chapters. You will most likely need to refer to other
parts of the manual before you begin more complicated programming.
Recommended project structure
We recommend keeping emWin separate from your application
files. It is good practice to keep all the program files (including the
header files) together in the GUI subdirectories of your project’s
root directory. The directory structure should be similar to the one
seen in the picture. This practice has the advantage of being very
easy to update to newer versions of emWin by simply replacing the
GUI\ directories. Your application files can be stored anywhere.
Note
When updating to a newer emWin version:
Since files may have been added, moved or deleted, the project directories may need to be updated accordingly.
Subdirectories
The following table shows the contents of all GUI subdirectories.
Directory | Contents |
Config | Configuration files |
GUI\AppWizard | AppWizard-related files |
GUI\ConvertColor | Color conversion routines used for color displays |
GUI\ConvertMono | Color conversion routines used for grayscale displays |
GUI\Core | emWin core files |
GUI\DisplayDriver | Display driver files |
GUI\Font | Font files |
GUI\AntiAlias | Anti-aliasing support |
GUI\MemDev | Memory Device support |
GUI\MT | MultiTouch support |
GUI\VNC | VNC support |
GUI\Widget | Widget library |
GUI\WM | Window Manager |
GUI\PNG | PNG support with libpng library. |
GUI\TrueType | TTF and BDF font support with FreeType library. |
Additional modules
These modules are sold separately from emWin BASE packages and can be optionally purchased
with a shipment.
The emWin PRO package contains the following modules by default: AntiAlias, MemDev, Widget and WM.
Third-party modules
These modules are not included in the commercially sold emWin shipments for legal reasons.
All modules containing third-party software can be downloaded for free from our website.
You can find the download links in the corresponding sub-chapters.
Include directories
You should make sure that the include path contains the following directories (the
order of inclusion is of no importance):
- Config
- GUI\AppWizard
- GUI\Core
- GUI\DisplayDriver
- GUI\Widget (if using the widget library)
- GUI\WM (if using Window Manager)
Note
Always make sure that you have only one version of each file!
It is frequently a major problem when updating to a new version of emWin if you
have old files included and therefore mix different versions. If you keep emWin in the
directories as suggested (and only in these), this type of problem cannot occur. When
updating to a newer version, you should be able to keep your configuration files and
leave them unchanged. For safety reasons, we recommend backing up (or at least
renaming) the GUI\ directories prior to updating.
Adding emWin to the target program
You basically have a choice between including only the source files that you are actually
going to use in your project, which will then be compiled and linked, or creating
a library and linking the library file. If your tool chain supports “smart” linking (linking
in only the modules that are referenced and not those that are not referenced),
there is no real need to create a library at all, since only the functions and data structures
which are required will be linked. If your tool chain does not support “smart”
linking, a library makes sense, because otherwise everything will be linked in and the
program size will be excessively large. For some CPUs, we have example projects
available to help you get started.
Creating a library
Building a library from the sources is a simple procedure. The
first step is to copy the batch files (located under Sample\Makelib)
into your project’s root directory. That means the
parent directory containing the Config and the GUI folder.
Then, make any necessary changes. There are a total of four
batch files which need to be copied, described in the table
below. The main file, Makelib.bat, will be the same for all systems
and requires no changes. To build a library for your target
system, you will normally need to make slight modifications to
the other three smaller files. Finally, start the file Makelib.bat
to create the library. The batch files assume that your GUI and
Config subdirectories are set up as recommended.
The procedure for creating a library is illustrated in the flow
chart below. The Makelib.bat file first calls Prep.bat to
prepare the environment for the tool chain. Then it calls CC.bat
for every file to be included in the library. It does this as many
times as necessary. CC.bat adds each object file to a list that
will be used by lib.bat. When all files to be added to the library
have been listed, Makelib.bat then calls lib.bat, which uses a
librarian to put the listed object files into the actual library. Of
course you are free to create libraries in another way.

It is not recommended to create an emWin library including a compile-time configurable
display driver. Detailed information about the configurability of emWin display
drivers can be found in the section Available display drivers.
File | Description |
Makelib.bat | Main batch file. No modification required. |
Prep.bat | Called by Makelib.bat to prepare environment for the tool chain to be used. |
CC.bat | Called by Makelib.bat for every file to be added to the library; creates a list of these
object files which will then be used in the next step by the librarian in the lib.bat file. |
Lib.bat | Called by Makelib.bat to put the object files listed by CC.bat into a library. |
The files as shipped assume that a Microsoft compiler is installed in its default location.
If all batch files are copied to the root directory (directly above GUI) and no
changes are made at all, a simulation library will be generated for the emWin simulation.
In order to create a target library, however, it will be necessary to modify
Prep.bat, CC.bat and lib.bat.
Adapting the library batch files to a different system
The following will show how to adapt the files by an example adaptation for the ARM Cortex-M4 CPU.
Adapting Prep.bat
Prep.bat is called at the beginning of Makelib.bat. As described above its job is to set
the environment variables for the used tools and the environment variable PATH, so
that the batch files can call the tools without specifying an absolute path. Assuming
the compiler is installed in the folder C:\MTOOL the file Prep.bat could look as follows:
@ECHO OFF
GOTO START
******************************************************************************
*
* File : Prep.bat
* Parameters: None
* Purpose : Sets path and other environment variables as required by tool chain
*
* This file is written for the CM4 GCC toolchain
*
* It needs to be modified if the compiler is installed in a different location.
*
******************************************************************************
:START
ECHO PREP.BAT: Preparing environment for CM4 GCC
if "%_PREP_CM4_GCC_%" == "_PREP_CM4_GCC_" goto cont
set _PREP_CM4_GCC_=_PREP_CM4_GCC_
SET TOOLPATH=c:\Tool\C\Segger\SES_V452\
set PATH=%TOOLPATH%\gcc\arm-none-eabi\bin\;%PATH%
SET GNU_C_INCLUDE=%TOOLPATH%\include
:cont
Adapting CC.bat
The job of CC.bat is to compile the passed source file and adding the file name of the
object file to a link list. When starting MakeLib.bat it creates the following subdirectories
relative to its position:
Directory | Contents |
Lib | This folder should contain the library file after the build process. |
Temp\Output | Should contain all the compiler output and the link list file. Will be deleted
after the build process. |
Temp\Source | MakeLib.bat uses this folder to copy all source and header files used for the
build process. Will be deleted after the build process. |
The object file should be created (or moved) to Temp\Output. This makes sure all the
output will be deleted after the build process. Also the link list should be located in
the output folder. The following shows an example for the GCC compiler:
@ECHO OFF
GOTO START
******************************************************************************
*
* File : CC.bat
* Parameters: %1 Name of file to compile (without extension; .c is added)
* Purpose : Compile one file and add it to the list of files to put in
* Library
*
* This file as is uses the GCC Compiler
*
******************************************************************************
:START
ECHO CC.BAT: Compiling %1.c with GCC compiler
if "%COMPILER_TEST_SAMPLES%"=="1" (
cc1 -mthumb -mcpu=cortex-m4 -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -DDEBUG=1 -DSKIP_TEST -O3 -mfpu=vfp -mfloat-abi=soft -fomit-frame-pointer -quiet -Wall -Wno-missing-field-initializers -Wextra -nostdinc "-I%GNU_C_INCLUDE%" -D__CROSSWORKS_ARM -fno-builtin -o temp/Output/%1.l temp/Source/%1.c
) else (
cc1 -mthumb -mcpu=cortex-m4 -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -DDEBUG=1 -DSKIP_TEST -O3 -mfpu=vfp -mfloat-abi=soft -fomit-frame-pointer -quiet -Wall -Wextra -Wlogical-op -Wfloat-equal -pedantic -nostdinc "-I%GNU_C_INCLUDE%" -D__CROSSWORKS_ARM -fno-builtin -o temp/Output/%1.l temp/Source/%1.c
)
IF ERRORLEVEL 1 PAUSE
as -mthumb -mcpu=cortex-m4 -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mfpu=vfp -mfloat-abi=soft --traditional-format -EL "temp/Output/%1.l" -o "temp/Output/%1.o"
IF ERRORLEVEL 1 PAUSE
IF NOT EXIST temp\Lib.dat @ECHO create lib/libGUI.a>temp\Lib.dat
@ECHO addmod temp\output/%1.o>>temp/lib.dat
Adapting Lib.bat
After all source files have been compiled Lib.bat will be called from MakeLib.bat.
The job is to create a library file using the link list created by CC.bat. The destination
folder of the library file should be the Lib folder created by MakeLib.bat. The following
shows an example for the GCC toolchain:
@ECHO OFF
GOTO START
******************************************************************************
*
* File : Lib.bat
* Parameters: None
* Purpose : Put all (object) files in linklist into the library
*
* This file is written for the GCC toolchain
*
******************************************************************************
:START
ECHO MAKELIB.BAT: Creating GUI target library using GCC tool-chain
REM ****************************************
REM Create library
REM ****************************************
IF EXIST Lib\GUI_GNU.LIB DEL Lib\GUI_GNU.LIB
@ECHO save>>temp\lib.dat
@ECHO end>>temp\lib.dat
ar -M<temp/lib.dat
IF ERRORLEVEL 1 PAUSE
C files to include in the project
Generally speaking, you need to include the core C files of emWin, the display driver,
all font files you plan to use and any optional modules you have ordered with emWin:
- All C files of the folder Config
- All C files of the folder GUI\Core
- The fonts you plan to use (located in GUI\Font)
- Display driver: All C files of the folder GUI\DisplayDriver.
Additional software packages
If you plan to use additional, optional modules you must also include their C files:
- Gray scale converting functions: all C files located in GUI\ConvertMono
- Color conversion functions: all C files located in GUI\ConvertColor
- Antialiasing: all C files located in GUI\AntiAlias
- AppWizard: all C files located in GUI\AppWizard
- Memory Devices: all C files located in GUI\MemDev
- VNC support: all C files located in GUI\VNC
- Widget library: all C files located in GUI\Widget
- Window Manager: all C files located in GUI\WM
Target specifics
For displays with indirect interface hardware routines must be included. Examples for
several kinds of indirect interface routines are available under Sample\LCD_X_Port.
RTOS specifics
- If emWin is intended to be used with an RTOS, some RTOS dependent functions
need to be implemented. emWin comes with several sample files including implementations
for common RTOS packages (called GUI_X_<RTOS>.c), as well as the
file GUI_X_Ex.c which just contains place holders of the required functions and
might be used to make emWin work with any RTOS.
- If multitasking is not required (access of the display by one task only) the file
GUI_X.c may be used as a starting point for a custom implementation.
The sample files can be found in the folder Sample\GUI_X which is contained in the
emWin package.
Additional information
Be sure to include GUI.h in all emWin accessing source files.
CMake support
Since V6.46, emWin now also comes with CMake scripts. The CMake support makes it possible
to include emWin in other CMake scripts or compile a library.
CMake options
To setup emWin and configure the CMake build, there are a few variables that can be set.
CMake option | Default value | Description |
GUI_CM_CONFIG_DIR | none | The emWin configuration directory containing these files: LCDConf.c/.h, PIDConf.c/.h and GUIConf.c/.h. |
GUI_CM_DISPLAY_DRIVERS | “all” | Semicolon-separated list of display drivers to be built. The default is that all display drivers in the directory
will be built. An example list would be: “GUIDRV_Lin;GUIDRV_FlexColor” |
GUI_CM_BUILD_APPWIZARD | OFF | Build with AppWizard subdirectory. |
GUI_CM_BUILD_CORE | ON | Build with Core subdirectory. |
GUI_CM_BUILD_CONVERTMONO | ON | Build with ConvertMono subdirectory. |
GUI_CM_BUILD_CONVERTCOLOR | ON | Build with ConvertColor subdirectory. |
GUI_CM_BUILD_DISPLAYDRIVER | ON | Build with DisplayDrivers subdirectory. |
GUI_CM_BUILD_TOUCHDRIVER | ON | Build with TouchDrivers subdirectory. |
GUI_CM_BUILD_FONT | ON | Build with Fonts subdirectory. |
GUI_CM_BUILD_ANTIALIAS | ON | Build with AntiAliasing subdirectory. |
GUI_CM_BUILD_WM | ON | Build with Window Manager subdirectory. |
GUI_CM_BUILD_WIDGET | ON | Build with Widgets subdirectory. |
GUI_CM_BUILD_MEMDEV | ON | Build with Memory Devices subdirectory. |
GUI_CM_BUILD_PNG | OFF | Build with PNG subdirectory. |
GUI_CM_BUILD_TRUETYPE | OFF | Build with TrueType subdirectory. |
GUI_CM_BUILD_VNC | OFF | Build with VNC subdirectory. |
GUI_CM_BUILD_MT | OFF | Build with MultiTouch subdirectory. |
CMake integration
The main CMake script that has to be executed or included is in the main GUI directory,
GUI\CMakeLists.txt
Example
An excerpt of a CMake script that includes emWin in its build could look like this:
#
# Include all sub-directories
#
set(GUI_CM_BUILD_APPWIZARD ON)
set(GUI_CM_BUILD_CORE ON)
set(GUI_CM_BUILD_CONVERTMONO ON)
set(GUI_CM_BUILD_CONVERTCOLOR ON)
set(GUI_CM_BUILD_DISPLAYDRIVER ON)
set(GUI_CM_BUILD_TOUCHDRIVER ON)
set(GUI_CM_BUILD_FONT ON)
set(GUI_CM_BUILD_ANTIALIAS ON)
set(GUI_CM_BUILD_WM ON)
set(GUI_CM_BUILD_WIDGET ON)
set(GUI_CM_BUILD_MEMDEV ON)
set(GUI_CM_BUILD_PNG ON)
set(GUI_CM_BUILD_TRUETYPE ON)
set(GUI_CM_BUILD_VNC ON)
set(GUI_CM_BUILD_MT ON)
#
# Configure config dir and display drivers
#
set(GUI_CM_DISPLAY_DRIVERS "GUIDRV_Lin;")
set(GUI_CM_CONFIG_DIR "${CMAKE_CURRENT_LIST_DIR}/Config")
#
# Add emWin
#
add_subdirectory(GUI)
Configuring emWin
The Config folder should contain all configuration files. The chapter Configuration
explains in detail how emWin should be configured.
Configuration macros
The following types of configuration macros are available:
Binary switch "B"
Switches can have a value of either 0 or 1, where 0 means deactivated and 1 means
activated (actually anything other than 0 would work, but using 1 makes it easier to
read a config file). These switches can enable or disable a certain functionality or
behavior. Switches are the simplest form of configuration macro.
Numerical value "N"
Numerical values are used somewhere in the code in place of a numerical constant.
Typical examples are in the configuration of the resolution of a display.
Selection switch "S"
Selection switches are used to select one out of multiple options where only one of
those options can be selected. A typical example might be the selection of the type of
display controller used, where the number selected denotes which source code (in
which display driver) is used to generate object code.
Alias "A"
A macro which operates like a simple text substitute. An example is U8, which is
replaced by the preprocessor with unsigned char.
Function replacement "F"
Macros can basically be treated like regular functions although certain limitations
apply, as a macro is still put into the code as simple text replacement. Function
replacements are mainly used to add specific functionality to a module (such as the
access to a display) which is highly hardware-dependent. This type of macro is
always declared using brackets (and optional parameters).
Type replacement "T"
Type replacement macros allow changing the types of certain values.
Initializing emWin
The following functions should be used to initialize and ’de-initialize’ emWin in order
to start the configuration process (see chapter Configuration) or
clear internal data from memory again.
Routine | Description |
GUI_Init() | Initializes emWin internal data structures and variables. |
GUI_IsInitialized() | Returns the initialization state of emWin. |
GUI_Exit() | Clears emWin internal data from memory to make further calls of GUI_Init() possible. |
Code example
The section The Hello world example program offers a code example that shows how emWin is initialized.
GUI_Init()
Description
Initializes emWin internal data structures and variables.
Prototype
int GUI_Init(void);
Return value
= 0 | if successful. |
≠ 0 | if the initialization of the display driver fails. |
Additional information
Executing this function is mandatory before using any emWin functions. The only
exception is setting create flags for windows (see WM_SetCreateFlags()).
If the Window Manager is used, the background window is created from
within GUI_Init(). So if create flags are set up before GUI_Init() is called, the background
window is created according to them.
GUI_IsInitialized()
Description
Returns the initialization state of emWin.
Prototype
int GUI_IsInitialized(void);
Return value
1 | if emWin is already initialized |
0 | if not. |
GUI_Exit()
Description
Clears emWin internal data from memory to make further calls of GUI_Init() possible.
Prototype
void GUI_Exit(void);
Additional information
This function should be used if emWin represents a part of the application which
is not used continuously and therefore has to be able to be turned on and off again.
Please note that after GUI_Exit() was called emWin will not work properly until GUI_Init()
is called again.
Using emWin with target hardware
The following is just a basic outline of the general steps that should be taken when
starting to program with emWin. All steps are explained further in subsequent chapters.
Step 1: Configuring emWin
The first step is usually to customize emWin. For details about the configuration,
refer to the chapter Configuration.
Step 2: Defining access addresses or access routines
For memory-mapped display controllers, the access addresses of the display simply
need to be defined in the configuration file of the display controller. For
port/buffer-accessed display controllers, interface routines must be
defined. Examples of the required routines are available under Sample\LCD_X_Port.
Step 3: Compiling, linking and testing the example code
emWin comes with example code for both single- and multitask environments. Compile,
link and test these little example programs until you feel comfortable doing so.
Step 4: Modifying the example program
Make simple modifications to the example programs. Add additional commands such
as displaying text in different sizes on the display, showing lines and so on.
Step 5: In multitask applications: adapt to your OS (if necessary)
If multiple tasks should be able to access the display simultaneously, the macros
GUI_MAXTASK and GUI_OS come into play, as well as the file GUITask.c. For details
and example adaptations, refer to the chapter Configuration.
Step 6: Write your own application using emWin
By now you should have a clearer understanding of how to use emWin. Think about
how to structure the program your application requires and use emWin by calling the
appropriate routines. Consult the reference chapters later in this manual, as they discuss
the specific emWin functions and configuration macros that are available.
The "Hello world" example program
In the following we will show the “Hello world” example program. If you like to see a
wide range of emWin based sample applications as well as further simple tutorial
applications, please have a look in the Sample folder of your emWin shipment or visit
the “emWin Samples” section on www.segger.com.
A “Hello world” program has been used as a starting point for C programming since
the early days, because it is essentially the smallest program that can be written. An
emWin “Hello world” program is shown below and is available as
BASIC_HelloWorld.c in the Sample\Tutorial folder shipped with emWin.
The whole purpose of the program is to write “Hello world” in the upper left corner of
the display. In order to be able to do this, the hardware of the application, the display
controller and the GUI must be initialized first. emWin is initialized by a simple
call of GUI_Init() in the beginning of the program. In this example, we assume that
the hardware of your application is already initialized.
The “Hello world” program looks as follows:
#include "GUI.h"
void MainTask(void) {
GUI_Init();
GUI_DispString("Hello world!");
while(1);
}
Adding functionality to the "Hello world" program
Our little program has not been doing too much so far. We can now extend the functionality
a bit: after displaying “Hello world”, we would like the program to start
counting on the display in order to be able to estimate how fast outputs to the display
can be made. We can simply add a bit of code to the loop at the end of the main
program, which is essentially a call to the function that displays a value in decimal form.
The example is available as BASIC_Hello1.c in the Sample folder.
#include "GUI.h"
void MainTask(void) {
int i = 0;
GUI_Init();
GUI_DispString("Hello world!");
while(1) {
GUI_DispDecAt( i++, 20,20,4);
if (i > 9999) {
i = 0;
}
}
}
Configuration
Before emWin can be used on a target system, the software needs to be configured.
Configuring means modifying the configuration files which usually reside in the
(sub)directory Config. We try to keep the configuration as simple as possible, but
there are some configuration routines which need to be modified in order for the
system to work properly.
The following items need to be configured:
- Memory area to be used by emWin
- Display driver to be used for drawing operations
- Color conversion routines to be used
- Display controller initialization
- Framebuffer cache
- Hardware acceleration
- Hardware JPEG decoding
The following chapter explains the configuration of emWin in detail.
The configuration is basically divided into two parts: GUI-configuration and
LCD-configuration. GUI-configuration means configuration of available features, default
colors and -fonts and the configuration of available memory. The LCD-configuration is
more hardware dependent and has to define the physical size of the display, the
display driver and the color conversion routines to be used. For details about color
conversion routines, refer to the chapter Colors.
If a hardware is used which offers acceleration features as for example available with
the ChromeART accelerator of some of the STM32 devices, the chapter
Hardware acceleration contains more information.
A further part is configuring the simulation. But this is not required for the target
hardware and not part of this chapter. For details about configuring the simulation,
refer to the chapter Simulation.
Run-time- and compile-time configuration
There are C and include files to be configured. The configuration in the header files is
fixed at compile time and can not be changed whereas the configuration done in the
C files can be changed at run-time. This makes it possible to create a library which is
largely configuration independent and can be used with any display and any driver.
This requires that the configuration routines described in this chapter are not part of
the library but of the application.
Initialization process of emWin
The illustration shows the process of initialization. To initialize emWin, the application
only has to call GUI_Init(). The configuration routines explained below are called during
the internal initialization process.
GUI_X_Config()
It is called at the very first beginning of the initialization process to make sure that
memory is assigned to emWin. Within this routine GUI_ALLOC_AssignMemory() must
be called to assign a memory block to emWin. The functions are explained later in this chapter.
LCD_X_Config()
This function is called immediately after GUI_X_Config(). The main purpose of this
routine is creating a display driver device and selecting the color conversion routines.
Further it is responsible for setting the display size. If a touch screen is used it
should also be configured here.
LCD_X_DisplayDriver()
At a later point of the initialization process the function LCD_X_DisplayDriver() is
called. It is called directly by the display driver. During the initialization process the
task of this routine is putting the display controller into operation. A detailed
description of the routine follows later in this chapter.
Run-time configuration
The following table shows the available run-time configuration files located in the
subfolder Config:
Configuration file | Purpose |
GUIConf.c | Configuration of available memory. |
LCDConf.c | Configuration of the display size, the display driver and the color conversion routines. |
SIMConf.c | Configuration of the simulation (not part of this chapter). |
GUI_X.c | Configuration of timing routines. |
Customizing GUIConf.c
The purpose of this module is to provide emWin with the function GUI_X_Config()
which is responsible for assigning a memory block to the memory management
system. This requires knowledge about the memory requirement of the used
components. The separate chapter Performance and Resource Usage contains a detailed
description of the memory requirements (RAM and ROM) of the individual emWin
modules.
Per default GUIConf.c is located in the (sub)directory and contains the
routine GUI_X_Config() which is responsible to assign a memory block to emWin. It is
not cogently required to leave it in the file GUIConf.c. The routine GUI_X_Config()
can be located anywhere in the application.
Calling this function is the very first thing done during the process of initialization. It
is responsible to assign a memory block to emWin. This block is managed by the
internal memory management system. Please also refer to GUI_ALLOC_AssignMemory().
API functions to be used in GUI_X_Config()
The following table shows the API functions which must be called within
GUI_X_Config():
GUI_ALLOC_AssignMemory()
Description
The function assigns the one and only memory block to emWin which is used by the
internal memory management system. This function should be called typically from
GUI_X_Config().
Prototype
void GUI_ALLOC_AssignMemory(void * p,
U32 NumBytes);
Parameters
Parameter | Description |
p | Pointer to the memory block which should be used by emWin. |
NumBytes | Size of the memory block in bytes. |
Additional information
Note that not the complete memory block can be used by the application, because a
small overhead is used by the management system itself. Each memory block
requires approximately 12 additional bytes for management purpose. The assigned
memory block needs to be accessible 8, 16 and 32 bit wise. It is used by emWin
internally for memory allocation. Instead of using malloc() and free() the internal
memory management uses that block for memory allocation. It is not used as frame buffer.
GUI_RegisterAfterInitHook()
Description
Registers a hook function which gets called after the GUI has been initialized.
Prototype
void GUI_RegisterAfterInitHook(void ( *pFunc)(),
GUI_REGISTER_INIT * pRegisterInit);
Parameters
Parameter | Description |
pFunc | Pointer to a function to be called. |
pRegisterInit | Pointer to a GUI_REGISTER_INIT structure. |
Additional information
It is possible to set multiple function to be called after the GUI has been initialized.
This requires a dedicated GUI_REGISTER_INIT structure for each function.
static void _Init0(void) {
}
static void _Init1(void) {
}
void GUI_X_Config(void) {
static GUI_REGISTER_INIT RegisterInit0;
static GUI_REGISTER_INIT RegisterInit1;
static U32 aMemory[GUI_NUMBYTES / 4];
GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
GUI_SetDefaultFont(&GUI_Font6x8);
GUI_RegisterAfterInitHook(_Init0, &RegisterInit0);
GUI_RegisterAfterInitHook(_Init1, &RegisterInit1);
}
GUI_SetOnErrorFunc()
Description
Sets the hook function which is called from GUI_ErrorOut().
Prototype
void GUI_SetOnErrorFunc(void ( *pFunc)(const char * s ));
Parameters
Parameter | Description |
pFunc | Pointer to the function which should be called by GUI_ErrorOut(). |
Additional information
The hook function gets a short error description in the string passed to the routine. It
should contain the module and the function where the error occurred and a short
description.
See also the description of GUI_ErrorOut().
GUI_SetOnLogFunc()
Description
Sets the hook function which is called from GUI_Log().
Prototype
void GUI_SetOnLogFunc(void ( *pFunc)(const char * s ));
Parameters
Parameter | Description |
pFunc | Pointer to the function which should be called by GUI_Log(). |
Additional information
The hook function gets a log message in the string passed to the routine.
The string contains the module and the function from where the log was
sent.
See also the description of GUI_Log().
GUI_SetOnWarnFunc()
Description
Sets the hook function which is called from GUI_Warn().
Prototype
void GUI_SetOnWarnFunc(void ( *pFunc)(const char * s ));
Parameters
Parameter | Description |
pFunc | Pointer to the function which should be called by GUI_Warn(). |
Additional information
The hook function gets a warning in the string passed to the routine.
The string contains the module and the function where the error occurred
and a short description.
See also the description of GUI_Warn().
GUITASK_GetMaxTask()
Description
Returns the maximum number of possible tasks when multitasking is enabled.
Prototype
int GUITASK_GetMaxTask(void);
Return value
Maximum number of possible tasks.
GUITASK_SetMaxTask()
Description
Sets the maximum number of tasks from which emWin can be accessed when
multitasking is enabled.
Prototype
void GUITASK_SetMaxTask(int MaxTask);
Parameters
Parameter | Description |
MaxTask | Number of tasks from which emWin is used at most. |
Additional information
This function is intended to be called from GUI_X_Config(). It is necessary to use
this function when working with a pre-compiled library. Otherwise GUI_MAXTASK can
be defined. Further information can be found under GUI_MAXTASK.
Customizing LCDConf.c
The purpose of this module is to provide emWin with the required display
configuration routine and the callback function for the display driver. These are the following functions:
Routine | Description |
LCD_X_Config() | Configuration routine for creating the display driver device, setting the color conversion routines and the display size. |
LCD_X_DisplayDriver() | Callback routine called by the display driver for putting the display controller into operation. |
LCD_X_Config()
Description
As described in the table above this routine is responsible to create a display driver
device, set the right color conversion routines and for configuring the physical display size.
Prototype
void LCD_X_Config(void);
Additional information
Depending on the used display driver it could also be required to set the video RAM
address, initialize a custom palette or some else. For information about any
additional requirements, refer to Detailed display driver descriptions. The
functions available for configuration purpose in this routine are listed and explained
later in this chapter.
Example
The following shows a typical example implementation:
//
// Set display driver and color conversion for 1st layer
//
GUI_DEVICE_CreateAndLink(GUIDRV_LIN_16, GUICC_565, 0, 0);
//
// Display driver configuration
//
LCD_SetSizeEx (0, 320, 240);
LCD_SetVSizeEx (0, 320, 240);
LCD_SetVRAMAddrEx(0, (void *)0x200000);
LCD_X_DisplayDriver()
Description
This is the callback function of the display driver. It is called by the display driver for
several jobs. It passes a command and a pointer to a data structure to the callback
routine. The command tells the callback function what should be done. If the command
requires parameters they are passed through the data pointer pData. It points
to a structure whose format depends on the command.
Prototype
int LCD_X_DisplayDriver(unsigned LayerIndex,
unsigned Cmd,
void * pData);
Parameters
Parameter | Description |
LayerIndex | Zero based layer index. |
Cmd | Command to be executed. Detailed descriptions below. |
pData | Pointer to a data structure. |
Elements of structure LCD_X_SETVRAMADDR_INFO
Data type | Element | Description |
void * | pVRAM | Pointer to the start address of the video RAM. |
Return value
0 | Command has been successfully executed. |
-1 | Command is not handled by the function. |
-2 | Error occured. |
Additional information
For more information about the commands passed to the routine by the display
driver, refer to Display drivers.
Examples
The folder Sample\LCDConf contains a lot of example implementations of this routine
which can be used as starting point.
API functions to be used in LCD_X_Config()
The following table shows the API functions which are available for configuration
purpose within LCD_X_Config():
Aside from the function LCD_SetLUTEx() the descriptions of the LCD_…() functions
can be found in the chapter Display drivers.
The descriptions of the GUI_TOUCH_…() functions can be found in the chapter
Touch screen driver.
GUI_DEVICE_CreateAndLink()
Description
This routine creates the display driver device, sets the color conversion routines to
be used for accessing the display and it links the driver device into the device list of
the given layer. LCD_X_Config() is called immediately after GUI_X_Config(). This
makes sure that the memory configuration already has been done and the driver is
able to allocate memory.
The required memory for a display driver device is approx. 50 bytes + the driver specific
memory. For details about the memory requirements of the individual display drivers,
refer to the chapter Display drivers.
Prototype
GUI_DEVICE *GUI_DEVICE_CreateAndLink(const GUI_DEVICE_API * pDeviceAPI,
const LCD_API_COLOR_CONV * pColorConvAPI,
U16 Flags,
int LayerIndex);
Parameters
Parameter | Description |
pDeviceAPI | Pointer to the display driver to be used. The chapter Display drivers contains a table of the available display drivers. |
pColorConvAPI | Pointer to the color conversion routines to be used. The chapter Colors contains a table with the available color conversion routines. |
Flags | Should be zero. |
LayerIndex | Layer which should be managed by the driver. |
Return value
On success the function returns a pointer to the created device object, otherwise it
returns NULL.
Additional information
Note that the used driver also determines the display orientation in some cases. This
differs from driver to driver. For details about the display orientation, refer to the
chapter Display drivers.
Customizing GUI_X.c
This file is the location of the timing routines, the debugging routines and the kernel
interface routines:
Init routines
GUI_X_Init()
Description
This function is being called on initialization of emWin.
Prototype
void GUI_X_Init(void);
Additional information
Typically used to initialize a hardware timer to provide a time
base used by the timing related GUI_X functions.
This is not required when using an underlaying RTOS.
Timing routines
GUI_X_Delay()
Description
Returns after a specified time period in milliseconds.
Prototype
void GUI_X_Delay(int Period);
Parameters
Parameter | Description |
Period | Period in milliseconds. |
GUI_X_ExecIdle()
Description
Called only from non-blocking functions of the Window Manager.
Prototype
void GUI_X_ExecIdle(void);
Additional information
Called when there are no longer any messages which require processing. In this case
the GUI is up to date.
GUI_X_GetTime()
Description
Used by GUI_GetTime() to return the current system time in milliseconds.
Prototype
GUI_TIMER_TIME GUI_X_GetTime(void);
Return value
The current system time in milliseconds, of type integer.
Debug routines
GUI_X_ErrorOut()
GUI_X_Warn()
GUI_X_Log()
Description
These routines are called by emWin with debug information in higher debug levels in
case a problem (Error) or potential problem is discovered. The routines can be blank;
they are not required for the functionality of emWin. In a target system, they are
typically not required in a release (production) build, since a production build
typically uses a lower debug level.
- Fatal errors are output using GUI_X_ErrorOut() if (GUI_DEBUG_LEVEL ≥ 3)
- Warnings are output using GUI_X_Warn() if (GUI_DEBUG_LEVEL ≥ 4)
- Messages are output using GUI_X_Log() if (GUI_DEBUG_LEVEL ≥ 5)
Prototypes
void GUI_X_ErrorOut(const char * s);
void GUI_X_Warn(const char * s);
void GUI_X_Log(const char * s);
Parameters
Parameter | Description |
s | Pointer to the string to be sent. |
Additional information
This routine is called by emWin to transmit error messages or warnings, and is
required if logging is enabled. The GUI calls this function depending on the
configuration macro GUI_DEBUG_LEVEL. The following table lists the permitted values for
GUI_DEBUG_LEVEL:
Value | Symbolic name | Description |
0 | GUI_DEBUG_LEVEL_NOCHECK | No run-time checks are performed. |
1 | GUI_DEBUG_LEVEL_CHECK_PARA | Parameter checks are performed to avoid crashes.
(Default for target system) |
2 | GUI_DEBUG_LEVEL_CHECK_ALL | Parameter checks and consistency checks are performed. |
3 | GUI_DEBUG_LEVEL_LOG_ERRORS | Errors are recorded. |
4 | GUI_DEBUG_LEVEL_LOG_WARNINGS | Errors and warnings are recorded. (Default for PC-simulation) |
5 | GUI_DEBUG_LEVEL_LOG_ALL | Errors, warnings and messages are recorded. |
Kernel interface routines
Detailed descriptions for these routines may be found in Execution Model: Single Task / Multitask.
Function replacement
The following table shows the API functions which are available for setting up custom
defined functions for common purpose:
GUI_SetpfMemcpy()
Description
Sets a custom function for memcpy operations.
Prototype
void GUI_SetpfMemcpy
(void * ( *pFunc)(void * pDest , const void * pSrc , size_t Cnt ));
Parameters
Parameter | Description |
pFunc | Function to be used |
GUI_SetpfMemset()
Description
Sets a custom function for memset operations.
Prototype
void GUI_SetpfMemset(void * ( *pFunc)(void * pDest , int c , size_t Cnt ));
Parameters
Parameter | Description |
pFunc | Function to be used |
GUI_SetpfStrcmp()
Description
Sets a custom function for string compare operations.
Prototype
void GUI_SetpfStrcmp(int ( *pFunc)(const char * , const char * ));
Parameters
Parameter | Description |
pFunc | Function to be used |
GUI_SetpfStrcpy()
Description
Sets a custom function for string copy operations.
Prototype
void GUI_SetpfStrcpy(char * ( *pFunc)(char * , const char * ));
Parameters
Parameter | Description |
pFunc | Function to be used |
GUI_SetpfStrlen()
Description
Sets a custom function for getting the length of a string.
Prototype
void GUI_SetpfStrlen(size_t ( *pFunc)(const char * ));
Parameters
Parameter | Description |
pFunc | Function to be used |
Compile-time configuration
The following table shows the available compile time configuration files located in the
subfolder Config:
Configuration file | Purpose |
GUIConf.h | Configuration of possible number of used layers, default fonts and colors and
available features (e.g. Widgets). |
LCDConf.h | Configuration of the used display driver(s). |
In case a precompiled emWin library is used, changing the configuration files will not
have any effect until the library is compiled again with the required settings. This
applies to all of the defines explained in the following sections.
Customizing GUIConf.h
As described above the file should contain the configuration of available features and
the configuration of the default font. Each emWin shipment comes with a GUIConf.h
file which includes a basic configuration which can be used as a starting point.
Configuring the available features of emWin
The following table shows the available configuration macros:
Type | Macro | Default | Description |
B | GUI_OS | 0 | Activate to enable multitasking support with multiple tasks calling
emWin (see the chapter Execution Model: Single Task / Multitask). |
B | GUI_SUPPORT_AA | 1 | Enables support of anti-aliased drawing routines. |
B | GUI_SUPPORT_CURSOR | (see expl.) | Per default cursors are enabled if either GUI_SUPPORT_TOUCH or
GUI_SUPPORT_MOUSE has been enabled. If cursors should be shown without
enabling one of these options it should be set to 1. |
B | GUI_SUPPORT_MEMDEV | 0 | Enables optional Memory Device support. |
B | GUI_SUPPORT_MOUSE | 0 | Enables the optional mouse support. |
B | GUI_SUPPORT_ROTATION | 1 | Enables text rotation support. |
B | GUI_SUPPORT_SPY | 0 | Enables support for emWinSPY. |
B | GUI_SUPPORT_TOUCH | 0 | Enables optional touch-screen support. |
T | GUI_TIMER_TIME | int | Defines the type which is used for time values by the emWin
Timer functionality. |
B | GUI_WINSUPPORT | 0 | Enables optional Window Manager support. |
B | GUI_SUPPORT_BIDI | 1 | Enables BiDi support for emWin. Set to 0 if not required and to save some ROM. |
Default font and default color configuration
The following table shows the available configuration macros:
Type | Macro | Default | Description |
N | GUI_DEFAULT_BKCOLOR | GUI_BLACK | Define the default background color. |
N | GUI_DEFAULT_COLOR | GUI_WHITE | Define the default foreground color. |
S | GUI_DEFAULT_FONT | &GUI_Font6x8 | Defines which font is used per default after GUI_Init().
If you do not use the default font, it makes sense to change
to a different default, as the default font is referenced by
the code and will therefore always be linked.
Please also refer to GUI_SetDefaultFont() which can be used for
runtime configuration of the default font. |
The default colors and fonts of the widgets which are part of the optional Window
Manager can also be configured. For details, refer to the chapter Widgets (window objects).
Advanced GUI configuration options
The following table shows the available configuration macros:
Type | Macro | Default | Description |
S | GUI_DEBUG_LEVEL | 1 (target)
4 (simulation) | Defines the debug level, which determines how many checks
(assertions) are performed by emWin and if debug errors,
warnings and messages are output. Higher debug levels generate
bigger code. |
N | GUI_MAXTASK | 4 | Define the maximum number of tasks from which emWin is called to
access the display when multitasking support is enabled (see
the chapter Execution Model: Single Task / Multitask. |
F | GUI_MEMCPY | memcpy | This macro allows replacement of the memcpy function. |
F | GUI_MEMSET | memset | This macro allows replacement of the memset function |
N | GUI_NUM_LAYERS | 1 | Defines the maximum of available layers/displays. |
F | GUI_POST_INIT | - | Defines a function to be called at the end of GUI_Init(). |
B | GUI_TRIAL_VERSION | 0 | Marks the compiler output as evaluation version. |
B | GUI_WINSUPPORT | 0 | Enables optional Window Manager support. |
N | GUI_PID_BUFFER_SIZE | 5 | Maximum number of PID events managed by the input buffer. |
N | GUI_KEY_BUFFER_SIZE | 10 | Maximum number of key events managed by the input buffer. |
GUI_MEMCPY (obsolete)
This macro allows replacement of the memcpy function of the GUI. On a lot of systems,
memcpy takes up a considerable amount of time because it is not optimized by
the compiler manufacturer. emWin contains an alternative memcpy routine, which
has been optimized for 32 bit CPUs. On a lot of systems this routine should generate
faster code than the default memcpy routine. However, this is still a generic C routine,
which in a lot of systems can be replaced by faster code, typically using either a
different C routine, which is better optimized for the particular CPU or by writing a
routine in Assembly language.
To use the optimized emWin routine add the following define to the file GUIConf.h:
#define GUI_MEMCPY GUI__memcpy
GUI_MEMSET (obsolete)
This macro allows replacement of the memset function of the GUI. On a lot of
systems, memset takes up a considerable amount of time because it is not optimized by
the compiler manufacturer. We have tried to address this by using our own memset()
Routine GUI__memset. However, this is still a generic C routine, which in a lot of
systems can be replaced by faster code, typically using either a different C routine,
which is better optimized for the particular CPU, by writing a routine in Assembly
language or using the DMA.
If you want to use your own memset replacement routine, add the define to the
GUIConf.h file.
GUI_POST_INIT
It could make sense to have a function which is called after the GUI has been
completely initialized. To be able to have that the macro could be defined as follows:
Example
#define GUI_POST_INIT CustomFunction();
GUI_TRIAL_VERSION
This macro can be used to mark the compiler output as an evaluation build. It should
be defined if the software is given to a third party for evaluation purpose (typically
with evaluation boards).
Note that a special license is required to do this; the most common licenses do not
permit redistribution of emWin in source or object code (relinkable) form. Contact
if you would like to do this.
If GUI_TRIAL_VERSION is defined, the following message is shown when calling
GUI_Init():
This message is always shown in the upper left corner of the display and is normally
visible for 1 second. The timing is implemented by a call of GUI_X_Delay(1000). The
functionality of emWin is in no way limited if this switch is active.
Example
#define GUI_TRIAL_VERSION 1
Customizing LCDConf.h
This file contains general configuration options required for compiling the display
driver(s) which need not to be changed at run-time. The available configuration
options depend on the used display driver. For details about the available configuration
options, refer to the chapter Display drivers. The detailed driver
description shows the available configuration options for each display driver.
Framebuffer cache
For any other display driver than GUIDRV_Lin, it is possible to use a framebuffer cache
to prevent flickering while emWin is drawing a new frame. Another important use case for
caching is when it is not possible to read back pixel data from an indirect display controller.
emWin offers two possible ways to use a framebuffer cache, both of which are explained below.
- Embedded caching: Cache integrated into a display driver
- GUI_GCACHE: Global, driver-independent caching module.
Embedded caching: Cache integrated into a display driver
Some display drivers have framebuffer caches directly embedded into its driver module.
The advantage of this caching stragety is that the cache is better adapted to the
specific needs of the display controller(s) supported by the driver.
Another advantage is less overhead, because only one display driver device is present
in the device chain, instead of two devices (one driver and one cache).
Below listed are display drivers that offer an embedded cache. The corresponding
chapters go into more detail for which bit depths an embedded cache is supported.
GUI_GCACHE: Global cache with optional color reducer
The GUI_GCACHE module is a global caching module that is completely independent
of any display driver.
When to use
Due to its versatility, there are a lot of cases where it makes sense to use this
caching module.
The following are example cases when it makes sense to use GUI_GCACHE:
- The display driver itself offers no embedded cache.
- The memory block for the cache should be used-allocated.
- There is not enough RAM to hold a cache with the bit depth of the controller,
the bit depth needs to be reduced.
Example usage
To enable this cache, only a call of one of the creation functions is necessary after
GUI_Init(). The line below enables a 4bpp GGACHE with 16 colors. The actual display driver created
beforehand may have a different color depth.
GUI_GCACHE_Create(GUI_GCACHE_4, GUICC_16);
Reducing memory footprint with the optional color reducer
The GUI_GCACHE optionally allows to run the cache with a reduced bit depth.
For example, a display runs in 16bpp but the RAM is limited that only a 4bpp cache would
fit into the RAM. In this case, create the GUI_GCACHE for 4bpp with the desired 4bpp color
conversion. When the 4bpp cache frame is sent to the display,
the color indices are expanded to the actual color depth of the display.
User allocated buffers
Through the routine GUI_GCACHE_CreateUserEx(), it is possible to pass a pointer to a
pre-allocated buffer area which will be used to hold the cache data.
static U16 _aCache[LCD_XSIZE * LCD_YSIZE];
GUI_GCACHE_CreateUserEx(GUI_GCACHE_16, GUICC_M565, 0, &_aCache[0]);
Limitations
There are some limitations around the bit depths of the GUI_GCACHE and the underlying LCD driver.
- The GUI_GCACHE cannot be used in 16bpp mode with LCDs that have a bigger bit depth than 16bpp themselves.
- The bit depth of the LCD must not be smaller than the bit depth of the GUI_GCACHE.
GUI_GCACHE API
Functions
Routine | Description |
GUI_GCACHE_Create() | Enables a global display cache that works with the given color depth and color conversion. |
GUI_GCACHE_CreateEx() | Enables a global display cache that works with the given color depth and color conversion for the given layer. |
GUI_GCACHE_CreateUserEx() | Enables a global display cache which works with the selected color depth for the given layer with a user-supplied pointer to the cache memory block. |
Defines
Group of defines | Description |
GUI_GCACHE modes | Available color depths for GUI_GCACHE. |
GUI_GCACHE_Create()
Description
Enables a global display cache that works with the given color
depth and color conversion.
Prototype
int GUI_GCACHE_Create( int ( *pfMode)(GUI_DEVICE * ),
const LCD_API_COLOR_CONV * pColorConvAPI);
Parameters
Parameter | Description |
pfMode | in One of the modes listed under GUI_GCACHE modes. |
pColorConvAPI | in Color conversion to be used for the cache. |
Return value
Additional information
For additional information see GUI_GCACHE_CreateUserEx().
GUI_GCACHE_CreateEx()
Description
Enables a global display cache that works with the given color
depth and color conversion for the given layer.
Prototype
int GUI_GCACHE_CreateEx( int ( *pfMode)(GUI_DEVICE * ),
const LCD_API_COLOR_CONV * pColorConvAPI,
int LayerIndex);
Parameters
Parameter | Description |
pfMode | in One of the modes listed under GUI_GCACHE modes. |
pColorConvAPI | in Color conversion to be used for the cache. |
LayerIndex | Layer index to be used. |
Return value
Additional information
For additional information see GUI_GCACHE_CreateUserEx().
GUI_GCACHE_CreateUserEx()
Description
Enables a global display cache which works with the selected color depth
for the given layer with a user-supplied pointer to the cache memory block.
Prototype
int GUI_GCACHE_CreateUserEx( int ( *pfMode)(GUI_DEVICE * ),
const LCD_API_COLOR_CONV * pColorConvAPI,
int LayerIndex,
void * pUserBuffer);
Parameters
Parameter | Description |
pfMode | in One of the modes listed under GUI_GCACHE modes. |
pColorConvAPI | in Color conversion to be used for the cache. Can be NULL to use the same color conversion as the display driver. |
LayerIndex | Layer index to be used. |
pUserBuffer | in Pointer to user-allocated buffer for the cache. |
Return value
Additional information
Once enabled only the colors of the given color conversion can be used.
Reading operations or XOR-operations will use the content of the cache.
Note that the bits per pixel specified with pfMode need to match the
bits per pixel of the given color conversion pColorConvAPI.
The pointer passed to pUserBuffer has to be large enough to support the
dimensions of the LCD:
LCD xSize * LCD ySize * bits per pixel of pColorConvAPI
GUI_GCACHE modes
Description
GUI_GCACHE bit depths to be used for GUI_GCACHE_Create() and the
other creation functions.
Definition
#define GUI_GCACHE_1 (&GUI_GCACHE_SetMode1bpp)
#define GUI_GCACHE_4 (&GUI_GCACHE_SetMode4bpp)
#define GUI_GCACHE_16 (&GUI_GCACHE_SetMode16bpp)
Symbols
Definition | Description |
GUI_GCACHE_1 | Use global cache with 1bpp color depth. |
GUI_GCACHE_4 | Use global cache with 4bpp color depth. |
GUI_GCACHE_16 | Use global cache with 16bpp color depth. |
Framebuffer located in data cache area of CPU
If available it makes sense to enable a data cache on CPU side.
That normally speeds up RAM access performance a lot. When
using a direct addressable frame buffer (normally managed by
GUIDRV_Lin) and if the frame buffer of the LCD-controller is
located within a cached data memory area, it could happen, that
the display shows some disturbance like shown on the
screenshot to the right. Please note that this is not a malfunction of
emWin. It is caused by the data cache of the CPU. The display
driver (normally GUIDRV_Lin) writes into memory which is
managed by the CPUs data cache. But unfortunately not all data is written directly into
the RAM area of the frame buffer, but only into the data cache. In that case the
LCD-controller does not have the correct data for generating the display signals. The
following explains how to avoid that disturbance.
Requirements
To be able to use a data cache, it is required that either the cache could be
configured to work in ’write-through’ mode (please also refer to GUIDRV_Lin)
or multiple buffers should be used (please also refer to Multiple Buffering).
If a ’write-through’ mode is available, nothing else needs to be considered.
Using multiple buffers and a data cache
If the cache is not configurable, multiple buffering must be enabled and a cache
clearance function should be set with GUI_DCACHE_SetClearCacheHook().
How it works
To be able to see always a screen without cache disturbance, it is required that
emWin makes sure, the cache is cleared before the frame buffer becomes visible.
That is done by calling the cache clearance function immediately before the back
buffer becomes visible. In detail it is called immediately before the display driver
callback function gets the command LCD_X_SHOWBUFFER.
When using the Window Manager
To make sure that all drawing operations are done automatically within the back
buffer, the application should not draw anything outside the WM_PAINT event of the
window manager.
Animations and multiple buffering
The most recommended way to use animation functions is animating window content
and invalidating the according windows within the animations. That makes sure,
multi buffering is used automatically after enabled by WM_MULTIBUF_Enable(). If the
window manager is not available or when drawing with animations besides the Window
Manager, a slice callback function using GUI_MULTIBUF_Begin() and
GUI_MULTIBUF_End() should be used to make sure the DCache gets cleared. Please
also refer to Using a slice callback function.
Memory device animation functions
Note
The following applies to functions listed in the following chapters:
Normally those functions do not use multiple buffering. But in case of using a data
cache, multiple buffering is required because all drawing operations need to be done
within the back buffer before the cache is cleared and the back buffer becomes
visible. For that case the function GUI_MEMDEV_MULTIBUF_Enable() should be used to
enable that feature.
Available API functions
The following functions are available:
GUI_DCACHE_Clear()
Description
Calls the hook function set with GUI_DCACHE_SetClearCacheHook(). Normally this
function does not need to be called. It should be called automatically by emWin.
Prototype
void GUI_DCACHE_Clear(U32 LayerMask);
Parameters
Parameter | Description |
LayerMask | Bit mask of layers to be cleared. |
Additional information
Please refer to GUI_DCACHE_SetClearCacheHook().
GUI_DCACHE_SetClearCacheHook()
Description
Sets up a function for clearing the cache of the given layer. That function is
called immediately before a back buffer should become visible. That makes sure, no cache
disturbance will be visible on the screen.
Prototype
void GUI_DCACHE_SetClearCacheHook(void ( *pFunc)(U32 LayerMask ));
Parameters
Parameter | Description |
pFunc | Pointer to the function to be used. |
Additional information
Parameter LayerMask passed to the hook function contains a bit mask of the layer(s)
to be managed. The number of the bit represents the number of the layer. If for
example the data cache of layer 2 should be cleared, bit 2 of the layer mask is set.
Example
The following shows a sample implementation of a clear cache function:
static void _ClearCacheHook(U32 LayerMask) {
int i;
for (i = 0; i < GUI_NUM_LAYERS; i++) {
if (LayerMask & (1 << i)) {
_CleanRange(_apVRAM[i], WIDTH * HEIGHT * NUM_BUFFERS * sizeof(U32));
}
}
}
Hardware acceleration
If a CPU or an LCD-controller offers hardware acceleration features some or even most of
them could be used by emWin for accelerating the process of drawing operations. To
be able to achieve that, different mechanisms need to be used dependent on the kind
of hardware acceleration which should be used.
The following table shows a rough classification of the features which can be accelerated:
Group | Purpose |
Color conversion | Some hardware like ChromART offers the possibility of converting
colors from one format to a different format. For that many of the
color conversion routines offers the possibility to set a hardware
function for the process of color conversion. |
Drawing of primitives | Hardware accelerated drawing of primitives (also anti-aliased) could
be achieved by calling primitive specific setters for passing
custom defined functions to be used for drawing. |
Filling, copy operations and bitmap drawing | Those operations could be accelerated by setting custom drawing
functions using LCD_SetDevFunc(). |
Alpha blending | A custom function could be used to mix up the given foreground and
background colors in accordance to the alpha values of the colors. |
Mixing colors | A custom function could be used to mix up the given foreground and
background colors with the given intensity. |
Alpha text drawing | Drawing of anti-aliased text could be achieved by setting a custom
function. |
Palette conversion | Conversion of bitmap palettes could be done by a custom function. |
Drawing bitmaps within memory devices | Some internal memory device operations could be accelerated by
setting a custom function. |
Memory device manipulation | Manipulation of the contents of a memory device such as rotating, scaling or blending. |
Drawing of SVGs | The hardware accelerator is based on 2D vector operations which allows
the rendering of vector paths which are crucial to the SVG file format. |
Ready to use configurations
The following table shows some of the hardware accelerators which can be used with ready-to-use sample configurations that come with emWin.
These sample configurations set up emWin to use most of the features of the hardware accelerators.
They can be used on appropriate hardware with little or no modification:
Hardware | Supported features |
Renesas D/AVE 2D hardware IP core |
- Drawing of anti-aliased primitives
- Drawing of bitmaps (8-, 16- and 32 bpp)
- Rectangle filling with alpha blending
- Drawing of anti-aliased text
|
STM32 ChromART Accelerator |
- Drawing of bitmaps (8-, 16- and 32bpp)
- Rectangle filling with alpha blending (only supported by some devices, for example by STM32L4R9I)
- Drawing of anti-aliased text
- Rectangular copy operations
|
NXP Pixel Pipeline |
- Drawing of 16 bpp and 32 bpp bitmaps and memory devices
- Rectangle filling with alpha blending
- Rectangular copy operations
- Color blending of memory devices
- Scaling and flipping of bitmaps (opaque bitmaps only)
|
Vivante VGLite | - Drawing of anti-aliased and non-anti-aliased primitives
- Filling of anti-aliased and non-anti-aliased primitives
- Scaling and rotation of memory devices
- Scaling and flipping of bitmaps (with or without transparency)
|
ThinkSilicon NemaVG / NemaGFX
STM32 NeoChrom Accelerator | - Drawing of anti-aliased and non-anti-aliased primitives
- Filling of anti-aliased and non-anti-aliased primitives
% - Scaling and rotation of memory devices
- Scaling of bitmaps (with or without transparency)
|
Please note that the absence of an accelerator in the above table does not mean that it is not supported by emWin.
It does only mean that we do not have ready to use configuration files for it.
Using D/AVE 2D hardware IP core
A useful feature of D/AVE 2D hardware IP core is the ability to support a clipping rectangle.
Furthermore, it offers a dedicated hardware module for performing anti-aliased drawing operations for anti-aliased shapes.
Performing these operations by software requires a lot of CPU time.
emWin offers an interface to route these operations to the D/AVE 2D hardware.
That makes it ideal for very fast drawing of complex screens with anti-aliased shapes.
Also, it is able to fill rectangular areas with a semi-transparent color which can be used for e.g. dimming screen areas.
Configuration files can be found under Sample\LCDConf\GUIDRV_Lin\RX65N and Sample\LCDConf\GUIDRV_Lin\EK_RA6M3G.
Using ChromART accelerator
Nearly all functions provided by the ChromART accelerator can be used with emWin.
Once configured correctly, it speeds up many drawing operations drastically.
The sample folder of emWin contains configuration files which use almost all features of ChromART accelerator
which can be found under Sample\LCDConf\GUIDRV_Lin\STM32xxx.
Please note that the samples are only available if the driver GUIDRV_Lin is licensed.
The ChromART accelerators on ST devices are not all identical, e.g. the STM32L4R9I is able to fill rectangular areas
with semitransparent colors, but this function is not provided by ChromART on some other ST devices.
To take these differences into account, a separate configuration can be found under Sample\LCDConf\GUIDRV_Lin\STM32L4R9I.
Using NXP Pixel Pipeline
The main feature of the Pixel Pipeline which is alpha composition offers a versatile way of speeding up
many intensive operations in emWin. Some of these operations are alpha blending, color mixing and the drawing of
bitmaps and memory devices with any opacity.
Filling opaque and semi-transparent rectangles is also supported by the PXP.
Additionally, the PXP offers a scaling and flipping feature which is utilized for speeding up these operations with GUI_DrawBitmapEx().
Using Vivante VGLite
The VGLite API is a vector-based hardware drawing API. Through the use of vector paths, virtually any 2D primitive can be drawn.
Primitives may be drawn anti-aliased or non-anti-aliased. Since vector paths support floating point coordinates, the use
of high-resolution anti-aliasing coordinates is also supported. Furthermore, a clipping rectangle is supported as well.
VGLite also provides blitting API functions that can be used in conjunction with matrix transformations. This allows
efficient rotation and scaling of memory devices or raster images. The advantage here over e.g. the PXP accelerator is that the rotation angle
is not limited to 90° increments and the bitmap or memory device content may also be semi-transparent.
Byte alignments for blitting operations
Note: Blitting operations using the VGLite API always require a specific byte alignment of the bitmap data,
depending on the format. For example, 32bpp bitmaps require an alignment of 64 bytes.
As for emWin operations delegated to VGLite, currently this only affects the functionality of rotating and scaling memory devices.
This means to utilize hardware acceleration for this operation, the horizontal and vertical dimensions of the memory
device have to be divisible by 16, to account for the 64-byte alignment.
Obvious workarounds for this limitation would be to crop the memory device content to a size that is divisible by 16.
Or alternatively, increase the size so that is it divisible by 16 and fill the padding area with a background color or
transparency.
Requirement of an operating system
VGLite requires high-level features of an embedded operating system, such as mutexes, semaphores, tasks and queues.
This makes it mandatory to provide an interface to an operating system.
An interface to SEGGER embOS is implemented in the file vg_lite_os_embOS.c. We encourage to use it, but
it may also be taken as a reference point to adapt the interface to another operating system.
Available API functions
The following table shows the available routines:
Color conversion
As explained in detail in Colors, color conversion in emWin is required
for converting a color value into an index value and vice versa. That is done by the
routines pointed by the fixed palette mode structures. These structures have pointers
for converting single items and also for bulk conversion of multiple items. The most
important color conversions offers the possibility for setting custom defined routines
for bulk conversion.
GUICC_M1555I_SetCustColorConv()
GUICC_M565_SetCustColorConv()
GUICC_M4444I_SetCustColorConv()
GUICC_M888_SetCustColorConv()
GUICC_M8888I_SetCustColorConv()
Description
These routines can be used to set custom routines for bulk color conversion for the
according color conversion.
Prototype
void GUICC_XXX_SetCustColorConv(tLCDDEV_Color2IndexBulk * pfColor2IndexBulk,
tLCDDEV_Index2ColorBulk * pfIndex2ColorBulk);
Parameters
Parameter | Description |
pfColor2IndexBulk | Routine to be used for converting multiple colors into index values. |
pfIndex2ColorBulk | Routine to be used for converting multiple index values into colors. |
Additional information
The definition of tLCDDEV_Color2IndexBulk is as follows:
typedef void tLCDDEV_Color2IndexBulk(LCD_COLOR * pColor,
void * pIndex,
U32 NumItems,
U8 SizeOfIndex);
The definition of tLCDDEV_Index2ColorBulk is as follows:
typedef void tLCDDEV_Index2ColorBulk(void * pIndex,
LCD_COLOR * pColor,
U32 NumItems,
U8 SizeOfIndex);
Filling, copy operations and bitmap drawing
As already explained before the function LCD_SetDevFunc can be used for a couple of cases.
Further the following function(s) exist:
GUI_SetFuncDrawM565()
Description
Sets two custom routines for drawing M565 images. One for drawing into memory devices
and a second one for drawing into the frame buffer.
Prototype
int GUI_SetFuncDrawM565(GUI_DRAWMEMDEV_FUNC * pfDrawMemdevFunc,
GUI_DRAWBITMAP_FUNC * pfDrawBitmapFunc);
Parameters
Parameter | Description |
pfDrawMemdevFunc | Pointer to a function for drawing M565 images into memory devices. |
pfDrawBitmapFunc | Pointer to a function for drawing M565 images into the frame buffer. |
Additional information
The prototype of the function used for memory devices is:
void GUI_DRAWMEMDEV_FUNC ( void * pDst,
const void * pSrc,
int xSize,
int ySize,
int BytesPerLineDst,
int BytesPerLineSrc);
The prototype of the function used for bitmaps is:
void GUI_DRAWBITMAP_FUNC (int LayerIndex,
int x,
int y,
U32 const * p,
int xSize,
int ySize,
int BytesPerLine);
This hardware accelleration functions are used for drawing high color bitmaps in M565 format.
Alpha blending
GUI_AlphaEnableFillRectHW()
Description
Enables filling a rectangle with a semi-transparent color.
Prototype
void GUI_AlphaEnableFillRectHW(int OnOff);
Parameters
Parameter | Description |
OnOff | Turns filling a rectangle with a semi-transparent color on or off. |
Additional information
This function requires a function for filling a rectangle by the hardware. Please refer
to LCD_SetDevFunc().
GUI_SetFuncAlphaBlending()
Description
Sets a custom defined routine for alpha blending operations. That routine is called by
emWin if multiple foreground colors should be mixed up with the background.
Prototype
void ( * GUI_SetFuncAlphaBlending(void ( * pFunc)
(LCD_COLOR * pColorFG,
LCD_COLOR * pColorBG,
LCD_COLOR * pColorDst,
U32 NumItems))) (LCD_COLOR * pColorFG,
LCD_COLOR * pColorBG,
LCD_COLOR * pColorDst,
U32 NumItems);
Parameters
Parameter | Description |
pFunc | Pointer to the function to be used. |
Return value
Pointer to the previous used function.
Parameters of pFunc()
Data type | Parameter | Description |
LCD_COLOR * | pColorFG | Pointer to the foreground color array. |
LCD_COLOR * | pColorBG | Pointer to the background color array. |
LCD_COLOR * | pColorDest | Pointer to a buffer for the result. |
U32 | NumItems | Number of colors to be mixed up. |
GUI_SetFuncDrawAlpha()
Description
Sets two custom routines for drawing memory devices with alpha value into another
memory device and for drawing a bitmap with alpha value.
Prototype
int GUI_SetFuncDrawAlpha(GUI_DRAWMEMDEV_FUNC * pfDrawAlphaMemdevFunc,
GUI_DRAWBITMAP_FUNC * pfDrawAlphaBitmapFunc);
Parameters
Parameter | Description |
pfDrawAlphaMemdevFunc | Pointer to a function for drawing bitmaps in memory devices. |
pfDrawAlphaBitmapFunc | Pointer to a function for drawing bitmaps in frame buffer. |
Additional information
The prototype of the function used for memory devices is:
void GUI_DRAWMEMDEV_FUNC ( void * pDst,
const void * pSrc,
int xSize,
int ySize,
int BytesPerLineDst,
int BytesPerLineSrc);
The prototype of the function used for bitmaps is:
void GUI_DRAWBITMAP32_FUNC (int LayerIndex,
int x,
int y,
U32 const * p,
int xSize,
int ySize,
int BytesPerLine);
This hardware accelleration functions are used for drawing 32 bpp alpha bitmaps.
GUI_SetFuncDrawA8()
Description
Sets two custom routines for drawing A8 images. One for drawing into memory devices
and a second one for drawing into the frame buffer.
Prototype
int GUI_SetFuncDrawA8(GUI_DRAWMEMDEV_FUNC * pfDrawMemdevFunc,
GUI_DRAWBITMAP_FUNC * pfDrawBitmapFunc);
Parameters
Parameter | Description |
pfDrawMemdevFunc | Pointer to a function for drawing A8 images into memory devices. |
pfDrawBitmapFunc | Pointer to a function for drawing A8 images into the frame buffer. |
Additional information
The prototype of the function used for memory devices is:
void GUI_DRAWMEMDEV_FUNC ( void * pDst,
const void * pSrc,
int xSize,
int ySize,
int BytesPerLineDst,
int BytesPerLineSrc);
The prototype of the function used for bitmaps is:
void GUI_DRAWBITMAP_FUNC (int LayerIndex,
int x,
int y,
U32 const * p,
int xSize,
int ySize,
int BytesPerLine);
This hardware accelleration functions are used for drawing antialiased TTF-fonts and non compressed 8 bit alpha bitmaps containing alpha channel only.
Mixing colors
Mixing up colors here means mixing up the given background with the given
foreground using the given intensity.
GUI_SetFuncMixColors()
Description
Sets a custom defined routine for mixing up single colors.
Prototype
LCD_COLOR ( * GUI_SetFuncMixColors(LCD_COLOR ( * pFunc)
(LCD_COLOR Color,
LCD_COLOR BkColor,
U8 Intens))) (LCD_COLOR Color,
LCD_COLOR BkColor,
U8 Intens);
Parameters
Parameter | Description |
pFunc | Pointer to the function to be used. |
Parameters of pFunc()
Data type | Parameter | Description |
LCD_COLOR | Color | Color to be blended with the given intensity. |
LCD_COLOR | BkColor | Color of background. |
U8 | Intens | Intensity to be used for the blending operation. |
GUI_SetFuncMixColorsBulk()
Description
Sets up a custom defined function for bulk mixing operations. That is mainly used for
fading memory devices. It mixes up the given background area with the given
foreground area using the desired intensity.
Prototype
void ( * GUI_SetFuncMixColorsBulk(void ( * pFunc)(U32 * pFG,
U32 * pBG,
U32 * pDst,
unsigned OffFG,
unsigned OffBG,
unsigned OffDest,
unsigned xSize,
unsigned ySize,
U8 Intens))) (U32 * pFG,
U32 * pBG,
U32 * pDst,
unsigned OffFG,
unsigned OffBG,
unsigned OffDest,
unsigned xSize,
unsigned ySize,
U8 Intens);
Parameters
Parameter | Description |
pFunc | Pointer to the function to be used. |
Parameters of pFunc()
Data type | Parameter | Description |
U32 * | pFG | Pointer to the foreground color array. |
U32 * | pBG | Pointer to the background color array. |
U32 * | pDst | Pointer to the destination buffer for the result. |
unsigned | OffFG | Currently not used. |
unsigned | OffBG | Additional offset in pixels (xSizeBG - xSizeFG) to be added for incrementing the background pointer at the end of a line. |
unsigned | OffDest | Currently not used. |
unsigned | xSize | X-size of area to be converted. |
unsigned | ySize | Y-size of area to be converted. |
U8 | Intens | Intensity to be used when blending the foreground over the background. |
Return value
Pointer to the previous used function.
Alpha text drawing
If transparent mode is active, no memory device is selected and no clipping is
required a custom function could be used for drawing anti-aliased characters. In all
other cases automatically the default function is used by emWin. Alpha text drawing
means that the given character image consists of intensity values which need to be
used to mix up the current background with the current foreground color.
GUI_AA_SetpfDrawCharAA4()
Description
Sets up a custom defined function for drawing alpha blending characters with 4
bits per pixel. The intensities to be used are stored in a byte array passed to the function.
Each pixel is stored in one nibble. The leftmost pixel is stored in the uppermost nibble.
Prototype
void GUI_AA_SetpfDrawCharAA4
(int ( *pfDrawChar)(int LayerIndex , int x , int y , U8 const * p , int xSize , int ySize , int BytesPerLine ));
Parameters
Parameter | Description |
pfDrawChar | Pointer to the function to be used. |
Parameters of pfDrawChar()
Data type | Parameter | Description |
int | LayerIndex | Destination layer of drawing operation. |
int | xPos | X-Position in screen coordinates to be used. |
int | yPos | Y-Position in screen coordinates to be used. |
const U8 * | p | Pointer to an array of bytes containing the intensity values to be used. |
int | xSize | X-size of character to be drawn. |
int | ySize | Y-size of character to be drawn. |
int | BytesPerLine | Bytes per line of the intensity array. |
Palette conversion
Palettes need to be converted when drawing device independent bitmaps with a color
depth of 8 bits per pixel or less. The conversion routine converts the colors of
the bitmap palette into index values to be used for drawing into the frame buffer. For
that conversion process, normally done by emWin, a custom function can be set.
GUI_SetFuncGetpPalConvTable()
Description
Sets a function pointer to a custom function, which converts an array of colors into
an array of index values. It should return a pointer to the first entry of the index table.
Prototype
void GUI_SetFuncGetpPalConvTable
(LCD_PIXELINDEX * ( *pFunc)(const LCD_LOGPALETTE * pLogPal , const GUI_BITMAP * pBitmap , int LayerIndex ));
Parameters
Parameter | Description |
pFunc | Pointer to the function to be used. |
Parameters of pfFunc()
Data type | Parameter | Description |
const LCD_LOGPALETTE * | pLogPal | Pointer to the array of colors to be converted. |
const GUI_BITMAP * | pBitmap | Pointer to the bitmap to be drawn. |
int | LayerIndex | Layer index of drawing operation. |
Elements of structure LCD_LOGPALETTE
Data type | Element | Description |
int | NumEntries | Number of color values located in the palette. |
char | HasTrans | 0 - No transparency should be used.
1 - Pixels with index 0 are treated as transparent. |
const LCD_COLOR * | pPalEntries | Pointer to the array of color values. |
Return value
A pointer to the array of index values of type LCD_PIXELINDEX.
Additional information
The process of drawing a bitmap within emWin and the mechanism of color
conversion should be well known when using that function.
Drawing bitmaps within memory devices
A custom function for drawing bitmaps with a color depth of 16bpp into memory
devices with a color depth of 16bpp can be used. The task of that function is copying
the data of the bitmap to be drawn into the destination memory device.
GUI_MEMDEV_SetDrawMemdev16bppFunc()
Description
Sets a custom function for drawing 16bpp bitmaps within 16bpp
memory devices.
Prototype
void GUI_MEMDEV_SetDrawMemdev16bppFunc
(GUI_DRAWMEMDEV_16BPP_FUNC * pfDrawMemdev16bppFunc);
Parameters
Parameter | Description |
pfDrawMemdev16bppFunc | Pointer to the function to be used. |
Additional information
The definition of GUI_DRAWMEMDEV_16BPP_FUNC is as follows:
typedef void GUI_DRAWMEMDEV_16BPP_FUNC ( void * pDst,
const void * pSrc,
int xSize,
int ySize,
int BytesPerLineDst,
int BytesPerLineSrc);
Parameters of GUI_DRAWMEMDEV_16BPP_FUNC
Data type | Parameter | Description |
void * | pDst | Destination pointer for upper left pixel to be drawn. |
const void * | pSrc | Source pointer for upper left pixel to be drawn. |
int | xSize | X-size in pixels of area to be drawn. |
int | ySize | Y-size in pixels of area to be drawn. |
int | BytesPerLineDst | Stride value in bytes of destination area. |
int | BytesPerLineSrc | Stride value in bytes of source bitmap. |
Drawing shapes
GUI_SetFuncFillCircle()
Description
This function sets a function pointer which gets called to fill a circle.
Prototype
void GUI_SetFuncFillCircle(int ( *pfFillCircle)(int x0 , int y0 , int r ));
Parameters
Parameter | Description |
pfFillCircle | Function pointer to a function for filling a circle. |
Parameters of pfFillCircle()
Data type | Parameter | Description |
int | x0 | x position of the center of the circle. |
int | y0 | y position of the center of the circle. |
int | r | Radius of the circle. |
GUI_SetFuncDrawCircle()
Description
This function sets a function pointer which gets called to draw a circle.
Prototype
void GUI_SetFuncDrawCircle(int ( *pfDrawCircle)(int x0 , int y0 , int r ));
Parameters
Parameter | Description |
pfDrawCircle | Function pointer to a function for drawing a circle. |
Parameters of pfDrawCircle()
Data type | Parameter | Description |
int | x0 | x position of the center of the circle. |
int | y0 | y position of the center of the circle. |
int | r | Radius of the circle. |
GUI_SetFuncFillRoundedRect()
Description
Sets a function pointer to fill a rounded rectangle by hardware.
Prototype
void GUI_SetFuncFillRoundedRect
(int ( *pfFillRoundedRect)(int x0 , int y0 , int x1 , int y1 , int r ));
Parameters
Parameter | Description |
pfFillRoundedRect | Pointer to the function to be called. |
Parameters of pfFillRoundedRect()
Data type | Parameter | Description |
int | x0 | Upper left X-position. |
int | y0 | Upper left Y-position. |
int | x1 | Lower right X-position. |
int | y1 | Lower right Y-position. |
int | r | Radius in pixels to be used. |
GUI_SetFuncDrawRoundedRect()
Description
Sets a function pointer to draw a rounded rectangle by hardware.
Prototype
void GUI_SetFuncDrawRoundedRect
(int ( *pfDrawRoundedRect)(int x0 , int y0 , int x1 , int y1 , int r ));
Parameters
Parameter | Description |
pfDrawRoundedRect | Pointer to the function to be called. |
Parameters of pfDrawRoundedRect()
Data type | Parameter | Description |
int | x0 | Upper left X-position. |
int | y0 | Upper left Y-position. |
int | x1 | Lower right X-position. |
int | y1 | Lower right Y-position. |
int | r | Radius in pixels to be used. |
GUI_SetFuncDrawLine()
Description
This function sets a function pointer which gets called to draw a line.
Prototype
void GUI_SetFuncDrawLine(int ( *pfDrawLine)(int x0 , int y0 , int x1 , int y1 ));
Parameters
Parameter | Description |
pfDrawLine | Function pointer to a function for drawing a line. |
Parameters of pfDrawLine()
Data type | Parameter | Description |
int | x0 | Start x position of the line. |
int | y0 | Start y position of the line. |
int | x1 | End x position of the line. |
int | y1 | End y position of the line. |
Drawing anti-aliased shapes
GUI_AA_SetFuncFillCircle()
Description
This function sets a function pointer which gets called to fill an anti aliased circle.
Prototype
void GUI_AA_SetFuncFillCircle(int ( *pfFillCircle)(int x0 , int y0 , int r ));
Parameters
Parameter | Description |
pfFillCircle | Function pointer to a function for filling a circle. |
Parameters of pfFillCircle()
Data type | Parameter | Description |
int | x0 | x position of the center of the circle. |
int | y0 | y position of the center of the circle. |
int | r | Radius of the circle. |
GUI_AA_SetFuncFillPolygon()
Description
This function sets a function pointer which gets called to fill an anti aliased polygon.
Prototype
void GUI_AA_SetFuncFillPolygon
(int ( *pfFillPolygon)(const GUI_POINT * pPoints , int NumPoints , int x0 , int y0 ));
Parameters
Parameter | Description |
pfFillPolygon | Function pointer to a function for filling a polygon. |
Parameters of pfFillPolygon()
Data type | Parameter | Description |
GUI_POINT * | pPoints | Pointer to a list of points. |
int | NumPoints | Number of elements of pPoints. |
int | x0 | x position of the start of the polygon. |
int | y0 | y position of the start of the polygon. |
GUI_AA_SetFuncDrawCircle()
Description
This function sets a function pointer which gets called to draw an anti aliased circle.
Prototype
void GUI_AA_SetFuncDrawCircle(int ( *pfDrawCircle)(int x0 , int y0 , int r ));
Parameters
Parameter | Description |
pfDrawCircle | Function pointer to a function for drawing a circle. |
Parameters of pfDrawCircle()
Data type | Parameter | Description |
int | x0 | x position of the center of the circle. |
int | y0 | y position of the center of the circle. |
int | r | Radius of the circle. |
GUI_AA_SetFuncDrawLine()
Description
This function sets a function pointer which gets called to draw an anti aliased line.
Prototype
void GUI_AA_SetFuncDrawLine
(int ( *pfDrawLine)(int x0 , int y0 , int x1 , int y1 ));
Parameters
Parameter | Description |
pfDrawLine | Function pointer to a function for drawing a line. |
Parameters of pfDrawLine()
Data type | Parameter | Description |
int | x0 | Start x position of the line. |
int | y0 | Start y position of the line. |
int | x1 | End x position of the line. |
int | y1 | End y position of the line. |
GUI_AA_SetFuncDrawPolyOutline()
Description
This function sets a function pointer which gets called to draw an anti aliased polygon.
Prototype
void GUI_AA_SetFuncDrawPolyOutline
(int ( *pfDrawPolyOutline)(const GUI_POINT * pSrc , int NumPoints , int Thickness , int x , int y ));
Parameters
Parameter | Description |
pfDrawPolyOutline | Function pointer to a function for drawing a polygon. |
Parameters of pfDrawPolyOutline()
Data type | Parameter | Description |
GUI_POINT * | pPoints | Pointer to a list of points. |
int | NumPoints | Number of elements of pPoints. |
int | Thickness | The thickness of the poly outline. |
int | x0 | x position of the start of the polygon. |
int | y0 | y position of the start of the polygon. |
GUI_AA_SetFuncDrawArc()
Description
This function sets a function pointer which gets called to draw an anti aliased arc.
Prototype
void GUI_AA_SetFuncDrawArc
(int ( *pfDrawArc)(int x0 , int y0 , int rx , int ry , I32 a0 , I32 a1 ));
Parameters
Parameter | Description |
pfDrawArc | Function pointer to a function for drawing an arc. |
Parameters of pfDrawArc()
Data type | Parameter | Description |
int | x0 | Center x position of the arc. |
int | y0 | Center y position of the arc. |
int | rx | Radius in x direction. |
int | ry | Radius in y direction. |
int | a0 | Start of the arc in degrees. |
int | a1 | End of the arc in degrees. |
Bitmap scaling
GUI_SetFuncDrawBitmapEx()
Description
Sets a custom function pointer for GUI_DrawBitmapEx().
Prototype
void GUI_SetFuncDrawBitmapEx
(int ( *pfDrawBitmapEx)(const GUI_BITMAP * pBitmap , int x0 , int y0 , int xMag , int yMag ));
Parameters
Parameter | Description |
pfDrawBitmapEx | Function to be set. |
Additional information
pfDrawBitmapEx should return 1 on error and 0 on success.
Note that the parameters x0 and y0 of pFunc already observe the
center position and magnification. This means x0/y0 is always the
upper left position of where the scaled bitmap is drawn on the display.
Parameters of pfDrawBitmapEx()
Data type | Parameter | Description |
const GUI_BITMAP * | pBitmap | Pointer to a GUI_BITMAP structure. |
int | x0 | Top-left X position of where the scaled result should be drawn. |
int | y0 | Top-left Y position of where the scaled result should be drawn. |
int | xMag | Scaling factor for X axis in promille (100% = 1000). Negative values means the axis is flipped. |
int | yMag | Scaling factor for Y axis in promille (100% = 1000). Negative values means the axis is flipped. |
Memory device manipulation
GUI_MEMDEV_SetRotateFuncLR()
GUI_MEMDEV_SetRotateFuncHR()
Description
Sets a custom routine that rotates and scales a memory device by the given parameters.
The LR routine receives low resolution coordinates as parameters while the HR routine receives high resolution
coordinates (display coordinates multiplied by 8).
Prototypes
void GUI_MEMDEV_SetRotateFuncLR(int ( * pfRotate)(GUI_MEMDEV_Handle hSrc,
GUI_MEMDEV_Handle hDst,
int dx,
int dy,
int a1000,
int Mag));
void GUI_MEMDEV_SetRotateFuncHR(int ( * pfRotate)(GUI_MEMDEV_Handle hSrc,
GUI_MEMDEV_Handle hDst,
int dx,
int dy,
int a1000,
int Mag));
Parameters
Parameter | Description |
pFunc | Pointer to the function to be used. |
Parameters of pFunc()
Data type | Parameter | Description |
GUI_MEMDEV_Handle | hSrc | Source memory device. |
GUI_MEMDEV_Handle | hDst | Destination memory device. |
int | dx | Offset to the X position. |
int | dy | Offset to the Y position. |
int | a1000 | Rotation angle in 1000ths of degrees (1° = 1000). |
int | Mag | Scaling factor in promille (100% = 1000). |
GUI_MEMDEV_SetBlendFunc()
Description
Sets a custom routine for blending a color into a memory device.
Prototype
void GUI_MEMDEV_SetBlendFunc
(int ( *pfBlend)(GUI_MEMDEV_Handle hMem , GUI_COLOR Color , U8 BlendIntens ));
Parameters
Parameter | Description |
pFunc | Pointer to the function to be used. |
Parameters of pFunc()
Data type | Parameter | Description |
GUI_MEMDEV_Handle | hMem | Memory device to be blended. |
GUI_COLOR | Color | Blend color to be used. |
U8 | BlendIntens | Blending intensity for Color. |
JPEG decoding
If the used MCU is capable of decoding JPEG files, emWin offers an interface to
reroute the decoding and drawing operations to hardware routines.
This offers a huge performance boost when displaying JPEG files compared to a
software only solution. Especially if a movie file should be displayed (.emf or .avi) it
makes sense to use the hardware decoder of a MCU.
The interface between emWin and the hardware decoder was developed on a
STM32F769 MCU but can be configured to work on other MCUs which come with a
hardware JPEG decoder.
Using hardware JPEG decoding
Every emWin shipment comes with a sample configuration file which is located under
Sample\JPEGConf\STM32F769. It requires embOS and the hardware abstraction
layer provided by ST because it was made to be used on a STM32F769.
Using the hardware decoding functionality is basically achieved by setting a function
pointer. This function will manage the process of decoding and drawing. Every time
one of the functions GUI_JPEG_Draw() or GUI_JPEG_DrawEx() are used the set
function pointer gets called.
If the function gets called, it is necessary to call the GetData function to receive as
many bytes as required to start the JPEG decoding process. After receiving the data
they get passed to the hardware routines and the decoding process starts.
If required the GetData function has to be called multiple times until the decoding
process has been finished.
After the process of hardware decoding the data needs to be converted from YCbCr
format into RGB data. Unfortunately the STM32F769 offers no function to do that
conversion per hardware. The JPEGConf.c mentioned before is an example on how to
do this.
Once the data is completely converted into RGB data it is shown on the display
(depending on the currently selected device).
GUI_JPEG_SetpfDrawEx()
Description
This function sets a function pointer to be used to decode and draw a JPEG file.
Prototype
void GUI_JPEG_SetpfDrawEx
(int ( *pfDrawEx)(GUI_JPEG_GET_DATA_FUNC * pfGetData , void * p , int x0 , int y0 ));
Parameters
Parameter | Description |
pfDrawEx | Pointer to the function to be used. |
Additional information
If set, the function pointer gets called if GUI_JPEG_Draw() or
GUI_JPEG_DrawEx() gets called. The MOVIE module of emWin makes also use of this function.
The function pointer is described below.
pfDrawEx()
Description
This function pointer gets called every time a JPEG should be displayed. Within this
function data needs to be received by the GetData function, the decoding process has
to be performed as well as the drawing of the completely decoded JPEG on the display.
Prototype
int ( * pfDrawEx)(GUI_GET_DATA_FUNC * pfGetData,
void * p,
int x0,
int y0);
Parameters
Parameter | Description |
pfGetData | Function pointer to a GetData function |
p | Data pointer which is passed to the GetData function. |
x0 | x position the JPEG file should be displayed. |
y0 | y position the JPEG file should be displayed. |
Return value
0 | on success. |
1 | on error. |
Additional information
An example of the GetData function can be found under Getting data with the …Ex() functions.
If this function returns 1 the default JPEG drawing routine of emWin gets called.
Memory management
emWin comes with its own memory management system which means the user does not have
to allocate and free memory themself. Because emWin manages the memory itself,
it is also easily possible to calculate the memory requirements of an emWin application.
Usage
With the function GUI_ALLOC_AssignMemory() the user assigns emWin a single, contiguous block of
memory which can reside in either internal or external memory. Once this memory block has been
assigned to emWin, the user does not have to perform anymore manual memory management regarding
emWin routines.
emWin now uses this given memory area for all dynamic memory allocations. Dynamic allocations
are used in many places of the emWin API, e.g. Memory Devices, cache for indirect drivers, decompressing image
data (e.g. JPEG, PNG) and many more operations.
One important exception is the GUIDRV_Lin driver which requires a memory block for the frame buffer
provided by the user. emWin does not allocate the memory for the frame buffer.
The assigned memory block is entirely managed by emWin and should not be accessed by the user
directly. Otherwise this might lead to unexpected behavior.
Block management
Memory in emWin is allocated in blocks. To manage these blocks, a few additional bytes are required
for each block. This block overhead is located in its own memory block.
Initially, this block is quite small since it only manages a few
memory blocks. But this block will increase in size, e.g. when memory for a window application is
required.
This overhead memory gets reused when blocks are getting deleted and created again,
but it will not get freed by emWin. So this should not be mistaken as a memory leak, this is
normal behavior.
Available API functions
The following functions allow control of memory usage at runtime. They can be used
to e.g. prevent waste of memory.
GUI_ALLOC_GetMaxUsedBytes()
Description
This function returns the number of the maximum number of used bytes. This
function is used to get the peak of used bytes.
Prototype
GUI_ALLOC_DATATYPE GUI_ALLOC_GetMaxUsedBytes(void);
Return value
Maximum number of used bytes.
GUI_ALLOC_GetNumFreeBytes()
Description
This function returns the number of bytes which can be used for emWin functions.
Prototype
GUI_ALLOC_DATATYPE GUI_ALLOC_GetNumFreeBytes(void);
Return value
Number of free bytes.
GUI_ALLOC_GetMemInfo()
Description
This function fills the given info structure with information about the memory usage.
Prototype
void GUI_ALLOC_GetMemInfo(GUI_ALLOC_INFO * pInfo);
Parameters
Elements of structure GUI_ALLOC_INFO
Data type | Element | Description |
U32 | TotalBytes | Total amount of bytes available. |
U32 | FreeBytes | Number of free bytes. |
U32 | UsedBytes | Number used bytes. |
U32 | AllocSize | Number of bytes available for memory management. |
U32 | NumFixed | Number of fixed bytes. |
U32 | MaxUsedBytes | The peak of used bytes. |
GUI_ALLOC_GetNumUsedBytes()
Description
This function returns the number of bytes which are already used by emWin functions.
Prototype
GUI_ALLOC_DATATYPE GUI_ALLOC_GetNumUsedBytes(void);
Return value
Number of used bytes.
Hook functions
emWin allows to set hook functions for various purposes, e.g. initialization or
management of cache buffers.
Routine | Description |
GUI_SetAfterExitHook() | Sets an optional function to be called during the process of deinitialization. |
GUI_SetAfterInitHook() | Sets an optional function to be called during the process of initialization. |
GUI_SetControlHook() | Sets a function which is called immediately before a display driver cache operation should be executed. |
GUI_SetRefreshHook() | Sets a callback function which waits until the vertical non display period has been reached before updating the screen. |
GUI_SetAfterExitHook()
Description
Sets an optional function to be called during the process of deinitialization. It may be
used for example to free memory the user has allocated.
Prototype
void GUI_SetAfterExitHook(void ( *pFunc)());
Parameters
Parameter | Description |
pFunc | Pointer to a function called before GUI_Exit() returns. |
GUI_SetAfterInitHook()
Description
Sets an optional function to be called during the process of initialization. It may be
used for example for putting a PID into operation after the GUI has been initialized.
Prototype
void GUI_SetAfterInitHook(void ( *pFunc)());
Parameters
Parameter | Description |
pFunc | Pointer to a function called immediately before GUI_Init() returns. |
Additional information
This function should be called before GUI_Init() is called.
GUI_SetControlHook()
Description
Under certain circumstances it could make sense to have a function which is called
immediately before a display driver cache operation should be executed. It could be
used for example if GUIDRV_Lin is used for managing the content of a layer and a
custom function should be used for transferring it to the display.
Prototype
void GUI_SetControlHook(void ( *pFunc)(int LayerIndex , int Cmd ));
Parameters
Parameter | Description |
pFunc | Callback function to be called before a driver cache operation should be executed. |
Additional information
That function is called independently of the existence of a cache in the driver.
GUI_SetRefreshHook()
Description
Sets a callback function which waits until the vertical non display period has been reached
before updating the screen.
Tearing effects could occur if the content of the frame buffer changes during the display
controller is not in the vertical non display period and currently updating the
screen. A detailed description of tearing effects can be found in the chapter Multiple Buffering.
If tearing effects should not occur and the following assumptions are fulfilled that function
can be used to avoid those effects:
- Display uses an indirect interface
- Display provides a tearing signal (TE)
- Display communication is fast enough for updating the frame buffer within the
vertical non display period.
The function sets a callback function which is called immediately before sending any
content to the display controller. That gives the application the chance to wait until
the display controller is within the vertical non display period. That can be achieved
by polling the TE-pin of the display (if available). The function should return
immediately after reaching the non display period. After that the driver sends its
(dirty) content to the display controller.
Prototype
void GUI_SetRefreshHook(void ( *pFunc)());
Parameters
Parameter | Description |
pFunc | Callback function to be called before a driver cache operation should be executed. |
Additional information
When using this function it is important to avoid writing to the display controller for
each drawing operation. This can be achieved by the cache locking mechanism.
Details can be found in the section Cache group.
Simulation
The PC simulation of emWin allows you to compile the same C source on your Windows
PC using a native (typically Microsoft) compiler and create an executable for
your own application. Doing so allows the following:
- Design of the user interface on your PC (no hardware required!).
- Debugging of the user interface program.
- Creation of demos of your application, which can be used to discuss the user interface.
The resulting executable can be sent easily via e-mail.
Using the simulation
The emWin simulation requires Microsoft Visual C++ (version 6.00 or higher) and the
integrated development environment (IDE) which comes with it. You will see a simulation
of your LCD on your PC screen, which has the same resolution in X and Y and
can display the exact same colors as your LCD once it has been properly configured.
The entire graphic library API and Window Manager API of the simulation are identical
to those on your target system; all functions will behave in the very same way as
on the target hardware since the simulation uses the same C source code as the target
system. The difference lies only in the lower level of the software: the display
driver. Instead of using the actual display driver, the PC simulation uses a simulation
driver which writes into a bitmap. The bitmap is then displayed on your screen using
a second thread of the simulation. This second thread is invisible to the application;
it behaves just as if the LCD routines were writing directly to the display.
Rotating and mirroring the screen
emWin supports rotating and/or mirroring of the screen. Please note that these features
do not affect the simulation screen.
Using the simulation with the trial version of emWin
The trial version of emWin contains a full library which allows you to evaluate all
available features of emWin. It also includes the emWin viewer (used for debugging
applications), as well as demo versions of the Font Converter and the Bitmap Converter.
Keep in mind that, being a trial version, you will not be able to view the
source code of emWin or the simulation, but you will still be able to become familiar
with what emWin can do.
Directory structure
The directory structure of the simulation in the trial version is
shown below. The table below explains the contents of the folders:
Directory | Content |
Application | Source of the demo program. |
Config | Configuration files used to build the library. Note that
changes at the header files do not have any effect on the precompiled library! |
Doc | Document folder, contains emWin manual. |
Exe | Ready-to-use demo program. |
GUI | Library files and include files need to use the library. |
Sample | Simulation examples. |
Simulation | Files needed for the simulation. |
Tool | Contains all emWin tools, such as the emWin viewer, a demo version of the Bitmap and Font
Converter and more. |
Visual C++ workspace
The root directory shown above includes the Microsoft Visual C++
solution (SimulationTrial.sln) and the rest of the project files.
The workspace allows you to modify an application program and debug it before compiling it on your target
system. Double-click the solution file to open the Microsoft Visual Studio IDE.
The directory structure of the Visual C++ workspace will look like the one
shown below.
Compiling the demo program
The source files for the demo program are located in the Application directory as a
ready-to-go simulation, meaning that you only need to rebuild and start it. Note that
to rebuild the executable, you will need to have Microsoft Visual C++ (version 6.00
or later) installed.
- Step 1: Open the Visual C++ workspace by double-clicking on SimulationTrial.sln.
- Step 2: Rebuild the project by choosing Build → Rebuild All from the menu (or
by pressing F7).
- Step 3: Start the simulation by choosing Build → Start Debug → Go from the menu
(or by pressing F5).
The demo project will begin to run and may be closed at any time by right-clicking on
it and selecting Exit.
Compiling the samples
The Sample directory contains ready-to-go examples that demonstrate different features
of emWin and provide examples of some of their typical uses. In order to build
any of these executables, their C source must be ’activated’ in the project.
This is easily done with the following procedure:
- Step 1: Exclude the content of the Application folder from the build process by expanding the Application
folder, selecting all files within it, right-clicking the marked files and setting Properties → General → Exclude from build to yes.
- Step 2: Add the desired example to the solution. Either add the example files by drag’n’drop to the solution
or by right-clicking a folder in the solution (e.g. Application) and selecting Add → Existin Item…. Now navigate to the example files and add it to the soultion.
- Step 3: If the example contains its own configuration files (LCDConf.c and/or
SIMConf.c) the default configuration files located in the config folder need to be
excluded from the build process (refer to step 1).
- Step 4: Rebuild the example by choosing Build → Rebuild All from the menu
(or by pressing F7).
- Step 5: Start the simulation by choosing Build → Start Debug → Go from the menu
(or by pressing F5). The result of the example selected above is pictured below:
Using the simulation with the emWin source
Directory structure
The root directory of the simulation can be anywhere on your PC, for
example C:\Work\emWinSim. The directory structure will appear as
shown below. This structure is very similar to that which we recommend
for your target application (see Getting Started for more information).
The following table shows the contents of the folders:
Directory | Content |
Doc | Contains the emWin documentation. |
Sample | Code examples, described later in this documentation. |
Start | All you need to create a new project with emWin. |
Tool | Tools shipped with emWin. |
A new project can be started by making a copy of the Start-folder.
It contains all required files for a new project. Subdirectories containing
the emWin sources are in the Start\GUI folder and should
contain the exact same files as the directories of the same names
which are used for your target (cross) compiler. The files of the
GUI subdirectories should not be changed, as this would make
updating to a newer version of emWin more difficult.
The Start\Config directory contains configuration files which need
to be modified in order to reflect your target hardware settings
(mainly LCD-size and colors which can be displayed).
Visual C++ workspace
The root directory shown above includes the Microsoft
Visual C++ workspace (Simulation.dsw) and project
files (Simulation.dsp). The workspace allows you to
modify an application program and debug it before
compiling it on your target system.
The directory structure of the Visual C++ workspace
will appear similar to that shown to the right. Here,
the GUI folder is open to display the emWin subdirectories.
Note that your GUI directory may not look
exactly like the one pictured, depending on which
additional features of emWin you have. The folders
Core, Font and DisplayDriver are part of the basic
emWin package and will always appear in the workspace directory.
Compiling the application
The simulation contains one or more application C files (located in the Application
directory), which can be modified or removed and additional files can be added to the
project. You should then rebuild the program within the Visual C++ workspace in
order to test/debug it. Once you have reached a point where you are satisfied with
the result and want to use the program in your application, you should be able to
compile these same files on your target system and get the same result on the target
display. The general procedure for using the simulation would be as follows:
- Step 1: Open the Visual C++ workspace by double-clicking on Simulation.dsw.
- Step 2: Compile the project by choosing Build → Rebuild All from the menu (or
by pressing F7).
- Step 3: Run the simulation by choosing Build → Start Debug → Go from the menu
(or by pressing F5).
- Step 4: Replace the bitmap with your own logo or image.
- Step 5: Make further modifications to the application program as you wish, by
editing the source code or adding/deleting files.
- Step 6: Compile and run the application program within Visual C++ to test the
results. Continue to modify and debug as needed.
- Step 7: Compile and run the application program on your target system.
Advanced features of the simulation
Clicking the right mouse button shows a context
menu with several advanced functions:
Pause and Resume
These menu items allows to pause and to resume
the application currently running in the simulation.
The same can be done by pressing <F4> or <F5>.
Trying to pause an already paused application or
trying to resume an already running application
causes an error message.
View system info
This menu item opens a further window with information
of the memory currently used by the application. The window
continuously shows the current status of memory consumption by showing
the free and used bytes and the free and used number of memory blocks.
Copy to clipboard
This menu item copies the current contents of the display into the clipboard. This
makes it easy to use it for documentation purpose with other applications.
Device simulation
The device simulation supports 3 views:
- Generated frame view
- Custom bitmap view
- Window view
The table below shows the different views:
Generated frame view | Custom bitmap view |
| |
The following will explain in detail how each option can be used.
Generated frame view
The simulation shows the display inside an automatically
generated frame surrounding the display. The frame contains
a small button which per default closes the application.
This is the default behavior of the simulation for
single layer systems. ’Single layer system’ means that
only the first layer is initialized.
Custom bitmap view
The simulation can show the simulated display in a bitmap of your choice, typically
your target device. The bitmap can be used to simulate the behavior of the entire
target device. In order to simulate the appearance of the device, bitmaps are
required.
Device bitmap
The first bitmap is usually a photo (top view)
of the device, and needs to be named
Device.bmp. It may be a separate file (in the
same directory as the executable), or it may
be included as a resource in the application.
How to do this is explained later in this chapter.
The file should provide an area for the simulated display of the same size
in pixels as the physical display resolution.
If there are any hardkeys to be simulated the
bitmap should also show all of them in unpressed state.

Transparent areas need to be colored with
exact the same color as defined with the function SIM_GUI_SetTransColor(), typically
red (0xFF0000). These areas do not have to be rectangular; they can
have an arbitrary shape (up to a certain complexity which is limited by your operating
system, but is normally sufficient). Red is the default color for transparent
areas, mainly because it is not usually contained in most bitmaps. To use a bitmap
with red, the default transparency color may be changed with the function
SIM_GUI_SetTransColor().
Hardkey bitmap
The second bitmap file is required for defining the hardkeys and must be named
Device1.bmp. It contains the buttons in pressed state.
The non hardkey area has to be filled with the transparent color.
This is only a short description. For more details
about how to simulate hardkeys, see Hardkey simulation.
Using separate files
When starting the simulation, it checks if the directory of the
executable contains the bitmap files Device.bmp and Device1.bmp. If
these files are available, they are used automatically and the resource bitmaps are
ignored. Note that this is only valid with single layer systems.
Adding the bitmap to the application resources
The resource file of the simulation can be found under
System\Simulation\Res\Simulation.rc.
It contains the following section:
/////////////////////////////////////////////////////////////////////////////
//
// Customizable bitmaps
//
IDB_DEVICE BITMAP DISCARDABLE "Device.bmp"
IDB_DEVICE1 BITMAP DISCARDABLE "Device1.bmp"
This section can be used to set custom device files. More information can be found in
the Win32 documentation.
Window view
Default for simulating a multiple layer system is showing each layer in a separate
window without using bitmaps or a generated frames.
Device simulation API
All of the device simulation API functions should be called in the setup phase. The
calls should be done from within the routine SIM_X_Config(), which is located in the
file SIMConf.c in the configuration folder. The example below calls SIM_SetLCDPos()
in the setup:
#include "LCD_SIM.h"
void SIM_X_Config() {
SIM_GUI_SetLCDPos(50, 20); // Define the position of the LCD in the bitmap}
}
Functions
Data structures
Structure | Description |
SIM_GUI_INFO | Contains the window handles of the simulation. |
Defines
Functions
SIM_GUI_Delay()
Description
Stops execution of simulation thread for the given period.
Prototype
void SIM_GUI_Delay(int ms);
Parameters
Parameter | Description |
ms | Period to be used. |
SIM_GUI_EnableModifierKey()
Description
This function let modifier keys (ALT, CTRL) through to emWin.
Prototype
void SIM_GUI_EnableModifierKey(int OnOff);
Parameters
Parameter | Description |
OnOff | Turn modifier keys on or off. |
SIM_GUI_ExecIdle()
Description
Called by the simulation on idle time.
Prototype
void SIM_GUI_ExecIdle(void);
SIM_GUI_GetCompositeTouch()
Description
Returns the layer index to be passed to emWin if the composite view is
touched by the PID.
Prototype
int SIM_GUI_GetCompositeTouch(void);
Return value
Layer index passed to emWin if the composite view is touched.
SIM_GUI_GetTime()
Description
Returns the period of time in ms elapsed since starting the simulation.
Prototype
int SIM_GUI_GetTime(void);
Return value
Period of time in ms elapsed since starting the simulation.
SIM_GUI_IsModifierKeyEnabled()
Description
This function indicates if modifier keys are turned on or not.
Prototype
int SIM_GUI_IsModifierKeyEnabled(void);
Return value
0 | Modifier keys are disabled |
1 | Modifier keys are enabled |
SIM_GUI_SaveBMP()
Description
Saves a BMP file containing the current layer.
Prototype
int SIM_GUI_SaveBMP(const char * sFileName);
Parameters
Parameter | Description |
sFileName | Filename to be used. |
Return value
SIM_GUI_SaveBMPEx()
Description
Saves a BMP file containing the given section of the current layer.
Prototype
int SIM_GUI_SaveBMPEx(const char * sFileName,
int x0,
int y0,
int xSize,
int ySize);
Parameters
Parameter | Description |
sFileName | Filename to be used. |
x0 | Left coordinate of the first pixels to be saved. |
y0 | Top coordinate of the first pixels to be saved. |
xSize | X-size in pixels of the section to be saved. |
ySize | Y-size in pixels of the section to be saved. |
Return value
SIM_GUI_SaveCompositeBMP()
Description
Saves a BMP file containing the current content of the composite view.
Prototype
int SIM_GUI_SaveCompositeBMP(const char * sFileName);
Parameters
Parameter | Description |
sFileName | Filename to be used. |
Return value
SIM_GUI_SetCallback()
Description
If it is required to simulate more than the display window or hardkeys, you can set a
callback function to receive the window handles of the simulation. This opens up the
possibility e.g. to add additional controls outside of the display window like leds or
sliders. Please note that the emWin functions can not be used there.
Prototype
void SIM_GUI_SetCallback(int ( *pfCallback)(SIM_GUI_INFO * pInfo ));
Parameters
Parameter | Description |
pfInfoCallback | Pointer to the callback function. The function has to expect a pointer to a SIM_GUI_INFO structure as a parameter. |
Elements of structure SIM_GUI_INFO
Data type | Element | Description |
HWND | hWndMain | Handle to the main window. |
HWND | ahWndLCD[16] | Array of handles to the display layers. |
HWND | ahWndColor[16] | Array of handles to the palette layers. |
SIM_GUI_SetCompositeColor()
Description
When simulating a multiple layer system each layer can be shown in its own window.
However, the physical display has only one area. It shows the result of the blended
layers. The simulation shows the result in the composite window which can have its
own size independent of the layers. Each layer can have its own position and its own
size within the composite window. This means that not necessarily the complete area
is covered by the layers. For this case (and also for transparency effects) this function
sets the default background color of the composite window.
Prototype
void SIM_GUI_SetCompositeColor(U32 Color);
Parameters
Parameter | Description |
Color | Background color to be used. |
Additional information
This function does not have an effect when using SoftLayers.
SIM_GUI_SetCompositeSize()
Note
This function also enables the composite window mode. It is used in SIM_X_Config().
Description
As described above under SIM_GUI_SetCompositeColor() the size of the composite
window is independent of the size of the layers. This function is used to set the size
of the composite window, as well as enable the composite window mode.
Prototype
void SIM_GUI_SetCompositeSize(int xSize,
int ySize);
Parameters
Parameter | Description |
xSize | Horizontal size in pixels. |
ySize | Vertical size in pixels. |
Example
This example screenshot shows the enabled composite window mode.
The two layers are shown on the right and on the left is the composite window,
which shows the two layers merged.
SIM_GUI_SetCompositeTouch()
Description
Sets the layer index to be passed to emWin if the composite view is touched by the PID.
Prototype
void SIM_GUI_SetCompositeTouch(int LayerIndex);
Parameters
Parameter | Description |
LayerIndex | Layer index to be used for touch events on the composite view. |
SIM_GUI_SetLCDColorBlack()
SIM_GUI_SetLCDColorWhite()
Description
Set the colors to be used as black or white, respectively, on color monochrome displays.
Prototypes
int SIM_GUI_SetLCDColorBlack(int DisplayIndex,
int Color);
int SIM_GUI_SetLCDColorWhite(int DisplayIndex,
int Color);
Parameters
Parameter | Description |
DisplayIndex | Reserved for future use; must be 0. |
Color | RGB value of the color. |
Additional information
These functions can be used to simulate the true background color of your display.
The default color values are black and white, or 0x000000 and 0xFFFFFF.
Refer to SIM_GUI_SetLCDColorBlack() for an example.
Example using default settings
void SIM_X_Config() {
SIM_GUI_SetLCDPos(14,84); // Define the position of the LCD
// in the bitmap
SIM_GUI_SetLCDColorBlack (0, 0x000000); // Define the color used as black
SIM_GUI_SetLCDColorWhite (0, 0xFFFFFF); // Define the color used as white
(used for colored monochrome displays)
}
Example using yellow instead of white
void SIM_X_Config() {
SIM_GUI_SetLCDPos(14,84); // Define the position of the LCD
// in the bitmap
SIM_GUI_SetLCDColorBlack (0, 0x000000); // Define the color used as black
SIM_GUI_SetLCDColorWhite (0, 0x00FFFF); // Define the color used as white
(used for colored monochrome displays)
}
SIM_GUI_SetLCDPos()
Description
Sets the position for the simulated LCD within the target device bitmap.
Prototype
void SIM_GUI_SetLCDPos(int xPos,
int yPos);
Parameters
Parameter | Description |
xPos | X-position of the upper left corner for the simulated LCD (in pixels). |
yPos | Y-position of the upper left corner for the simulated LCD (in pixels). |
Additional information
The X- and Y-positions are relative to the target device bitmap, therefore position
(0,0) refers to the upper left corner (origin) of the bitmap and not your actual LCD.
Only the origin of the simulated screen needs to be specified; the resolution of your
display should already be reflected in the configuration files in the Config directory.
The use of this function enables the use of the bitmaps Device.bmp and
Device1.bmp . Note that the values need to be ≥ 0 for enabling the use of the bitmaps.
If the use of the device bitmaps should be disabled, omit the call of this function in SIM_X_Init().
SIM_GUI_SetMag()
Description
Sets magnification factors for X and/or Y axis.
Prototype
void SIM_GUI_SetMag(int MagX,
int MagY);
Parameters
Parameter | Description |
MagX | Magnification factor for X axis. |
MagY | Magnification factor for Y axis. |
Additional information
Per default the simulation uses one pixel on the PC for each pixel of the simulated
display. The use of this function makes sense for small displays. If using a device bit-
map together with a magnification > 1 the device bitmap needs to be adapted to the
magnification. The device bitmap is not magnified automatically.
SIM_GUI_SetTransColor()
Description
Sets the color to be used for transparent areas of device or hardkey bitmaps.
Prototype
int SIM_GUI_SetTransColor(int Color);
Parameters
Parameter | Description |
Color | RGB value of the color in the format 00000000RRRRRRRRGGGGGGGGBBBBBBBB. |
Additional information
The default setting for transparency is bright red (0xFF0000).
You would typically only need to change this setting if your bitmap contains the same
shade of red.
SIM_GUI_SetTransMode()
Description
Sets the transparency mode for the given layer.
Prototype
void SIM_GUI_SetTransMode(int LayerIndex,
int TransMode);
Parameters
Parameter | Description |
LayerIndex | Index of the layer for which the transparency mode should be set. |
TransMode | Permitted values are listed under Transparency modes. |
SIM_GUI_ShowDevice()
Description
When using multiple layers, this function can be used to show the device
bitmap. By default each layer and the composite view are displayed in separate
windows.
Prototype
void SIM_GUI_ShowDevice(int OnOff);
Parameters
Parameter | Description |
OnOff | 1 for showing the bitmap, 0 for hiding it. |
Additional information
If using a multi-layer configuration and showing the device bitmap, only the composite
view is shown. Because of this, the routine SIM_GUI_SetCompositeSize() also needs to
be called in SIM_X_Config().
SIM_GUI_UseCustomBitmaps()
Description
As described earlier in this chapter it is possible to use device bitmaps from the
application resources. This function tells the simulation to use the device- and hardkey
bitmaps from the application resources and not to generate the default frame bitmap.
Prototype
void SIM_GUI_UseCustomBitmaps(void);
Additional information
The emWin shipment contains per default 2 bitmaps, Device.bmp and Device1.bmp,
located in Start\System\Simulation\Res which can be used as a starting point for
your own bitmaps.
Data structures
SIM_GUI_INFO
Description
Contains the window handles of the simulation. This structure
is required for SIM_GUI_SetCallback().
Type definition
typedef struct {
HWND hWndMain;
HWND ahWndLCD[];
HWND ahWndColor[];
} SIM_GUI_INFO;
Structure members
Member | Description |
hWndMain | Handle to the main window. |
ahWndLCD | Array of handles to the display layers. |
ahWndColor | Array of handles to the palette layers. |
Defines
Transparency modes
Description
Available transparency modes for layers.
Definition
#define GUI_TRANSMODE_PIXELALPHA 0
#define GUI_TRANSMODE_ZERO 2
Symbols
Definition | Description |
GUI_TRANSMODE_PIXELALPHA | The alpha value is taken from the pixel data in order to mix colors with the according background. |
GUI_TRANSMODE_ZERO | In this mode pixels are fully transparent if the pixel data equals 0. |
Hardkey simulation
The hardkey simulation can only be used in the custom bitmap view. Hardkeys may
also be simulated as part of the device, and may be selected with the mouse pointer.
The idea is to be able to distinguish whether a key or button on the simulated device
is pressed or unpressed. A hardkey is considered “pressed” as long as the mouse
button is held down; releasing the mouse button or moving the pointer off of the
hardkey releases the key. A toggle behavior between pressed and unpressed may
also be specified with the routine SIM_HARDKEY_SetMode().
In order to simulate hardkeys, you need a second bitmap of the device which is
transparent except for the keys themselves (in their pressed state). As described
earlier in this chapter, this bitmap can be in a separate file in the directory, or
included as a resource in the executable. Hardkeys may be any shape, as long as
they are exactly the same size in pixels in both Device.bmp and Device1.bmp. The
following example illustrates this:
Device bitmap: unpressed hardkey state (Device.bmp) | Device hardkey bitmap: pressed hardkey state (Device1.bmp) |
|