📄 IoT Toolkit User Guide & Reference Manual
📄 SEGGER Assembler User Guide & Reference Manual
📄 SEGGER Compiler User Guide & Reference Manual
📄 SEGGER Linker User Guide & Reference Manual
📄 SEGGER SystemView User Guide
📄 SEGGER Online Documentation
📄 AppWizard User Guide & Reference Manual
📄 embOS Real-Time Operating System User Guide & Reference Manual for embOS-Base and embOS-MPU
📄 embOS-Ultra Real-Time Operating System User Guide & Reference Manual for embOS-Ultra and embOS-Ultra-MPU
📄 emCompress-Embed User Guide & Reference Manual
📄 emCompress-LZMA User Guide & Reference Manual
📄 emCompress-ToGo User Guide & Reference Manual
📄 emCrypt User Guide & Reference Manual
📄 emDropbox User Guide & Reference Manual
📄 emFile User Guide & Reference Manual
📄 emFloat User Guide & Reference Manual
📄 emNet User Guide & Reference Manual
📄 emRun User Guide & Reference Manual
📄 emSecure-ECDSA User Guide & Reference Manual
📄 emSecure-RSA User Guide & Reference Manual
📄 emSSH User Guide & Reference Manual
📄 emSSL User Guide & Reference Manual
📄 emUSB-Device User Guide & Reference Manual
📄 emUSB-Host User Guide & Reference Manual
📄 emVNC User Guide & Reference Manual
📄 emWeb User Guide & Reference Manual
📄 emWin User Guide & Reference Manual

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:

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:

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)

Big systems (including Window Manager and widgets)

* 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:

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

Graphic library

Fonts

String/value output routines

Window Manager (WM)

Widgets for PC-like or smartphone-like look and feel

Touch-screen & mouse support

PC tools

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.

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
Additional modules
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
Third-party modules (not included in shipments)
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):

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:

Additional software packages

If you plan to use additional, optional modules you must also include their C files:

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

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:

The following chapter explains the configuration of emWin in detail.

What needs to be configured?

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():

Routine Description
GUI_ALLOC_AssignMemory() The function assigns the one and only memory block to emWin which is used by the internal memory management system.
GUI_RegisterAfterInitHook() Registers a hook function which gets called after the GUI has been initialized.
GUI_SetOnErrorFunc() Sets the hook function which is called from GUI_ErrorOut().
GUI_SetOnLogFunc() Sets the hook function which is called from GUI_Log().
GUI_SetOnWarnFunc() Sets the hook function which is called from GUI_Warn().
GUITASK_GetMaxTask() Returns the maximum number of possible tasks when multitasking is enabled.
GUITASK_SetMaxTask() Sets the maximum number of tasks from which emWin can be accessed when multitasking is enabled.
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():

Routine Description
GUI_DEVICE_CreateAndLink() Creates a display driver device and associates the color conversion routines to be used.
GUI_TOUCH_SetOrientation() The function configures the touch screen orientation.
GUI_TOUCH_Calibrate() Changes the calibration at runtime.
LCD_SetLUTEx() Sets the look-up table for the given layer.
LCD_SetSizeEx() Sets the physical size of the visible area of the given display/layer.
LCD_SetVRAMAddrEx() Sets the address of the video RAM.
LCD_SetVSizeEx() Sets the size of the virtual display area.

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.

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.

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:

Routine Description
GUI_SetpfMemcpy() Sets a custom function for memcpy operations.
GUI_SetpfMemset() Sets a custom function for memset operations.
GUI_SetpfStrcmp() Sets a custom function for string compare operations.
GUI_SetpfStrcpy() Sets a custom function for string copy operations.
GUI_SetpfStrlen() Sets a custom function for getting the length of a string.
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)

Note

Please refer to GUI_SetpfMemcpy.

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)

Note

Please refer to GUI_SetpfMemset.

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

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:

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.

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

0 on success
1 on error.

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

0 on success
1 on error.

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

0 on success
1 on error.

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:

Routine Description
GUI_DCACHE_Clear() Calls the hook function set with GUI_DCACHE_SetClearCacheHook().
GUI_DCACHE_SetClearCacheHook() Sets up a function for clearing the cache of the given layer.
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
  • Clipping
  • Drawing of anti-aliased primitives
  • Drawing of bitmaps (8-, 16- and 32 bpp)
  • Filling operations
  • Rectangle filling with alpha blending
  • Drawing of anti-aliased text
STM32 ChromART Accelerator
  • Color conversion
  • Drawing of bitmaps (8-, 16- and 32bpp)
  • Filling operations
  • 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
  • Color conversion
  • Drawing of 16 bpp and 32 bpp bitmaps and memory devices
  • Rectangle filling with alpha blending
  • Bulk color mixing
  • 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)
  • Rendering of SVGs
  • Clipping
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)
  • Rendering of SVGs
  • Clipping

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:

Routine Description
Color conversion
GUICC_M1555I_SetCustColorConv()
GUICC_M565_SetCustColorConv()
GUICC_M4444I_SetCustColorConv()
GUICC_M888_SetCustColorConv()
GUICC_M8888I_SetCustColorConv()
Setting up custom color conversion routines for the according fixed palette modes.
Filling, copy operations and bitmap drawing
LCD_SetDevFunc() The function sets additional and / or user defined functions of the display driver.
GUI_SetFuncDrawM565() Sets two custom routines for drawing M565 images.
Alpha blending
GUI_AlphaEnableFillRectHW() Enables filling a rectangle with a semi-transparent color.
GUI_SetFuncAlphaBlending() Setting up a custom defined function for doing alpha blending operations.
GUI_SetFuncDrawAlpha() Sets two custom routines for drawing memory devices with alpha value into another memory device and for drawing a bitmap with alpha value.
GUI_SetFuncDrawA8() Sets two custom routines for drawing A8 images.
Mixing colors
GUI_SetFuncMixColors() Setting up a custom defined function for blending a single background color value with the given color using the given intensity.
GUI_SetFuncMixColorsBulk() Setting up a custom defined function for bulk blending operations.
Alpha text drawing
GUI_AA_SetpfDrawCharAA4() Sets up a custom defined function for drawing alpha blending characters with 4 bits per pixel.
Palette conversion
GUI_SetFuncGetpPalConvTable() Sets a function pointer to a custom function, which converts an array of colors into an array of index values.
Drawing bitmaps within memory devices
GUI_MEMDEV_SetDrawMemdev16bppFunc() Sets a custom function for drawing 16bpp bitmaps within 16bpp memory devices.
Drawing shapes
GUI_SetFuncFillCircle() This function sets a function pointer which gets called to fill a circle.
GUI_SetFuncDrawCircle() This function sets a function pointer which gets called to draw a circle.
GUI_SetFuncFillRoundedRect() Sets a function pointer to fill a rounded rectangle by hardware.
GUI_SetFuncDrawRoundedRect() Sets a function pointer to draw a rounded rectangle by hardware.
GUI_SetFuncDrawLine() This function sets a function pointer which gets called to draw a line.
Drawing anti-aliased shapes
GUI_AA_SetFuncFillCircle() This function sets a function pointer which gets called to fill an anti aliased circle.
GUI_AA_SetFuncFillPolygon() This function sets a function pointer which gets called to fill an anti aliased polygon.
GUI_AA_SetFuncDrawCircle() This function sets a function pointer which gets called to draw an anti aliased circle.
GUI_AA_SetFuncDrawLine() This function sets a function pointer which gets called to draw an anti aliased line.
GUI_AA_SetFuncDrawPolyOutline() This function sets a function pointer which gets called to draw an anti aliased polygon.
GUI_AA_SetFuncDrawArc() This function sets a function pointer which gets called to draw an anti aliased arc.
Bitmap scaling
GUI_SetFuncDrawBitmapEx() Sets a custom function pointer for GUI_DrawBitmapEx().
Memory device manipulation
GUI_MEMDEV_SetRotateFuncLR()
GUI_MEMDEV_SetRotateFuncHR()
Setting up a custom routine for rotating and scaling a memory device.
GUI_MEMDEV_SetBlendFunc() Sets a custom routine for blending a color into a memory device.
JPEG decoding
GUI_JPEG_SetpfDrawEx() This function sets a function pointer to be used to decode and draw a JPEG file.
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.

Routine Description
GUI_ALLOC_GetMaxUsedBytes() This function returns the number of the maximum number of used bytes.
GUI_ALLOC_GetNumFreeBytes() This function returns the number of bytes which can be used for emWin functions.
GUI_ALLOC_GetMemInfo() This function fills the given info structure with information about the memory usage.
GUI_ALLOC_GetNumUsedBytes() This function returns the number of bytes which are already used by emWin functions.
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

Parameter Description
pInfo Pointer to to a GUI_ALLOC_INFO structure.

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:

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:

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.

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:

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:

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:

The table below shows the different views:

Generated frame view Custom bitmap view
Window 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

Routine Description
SIM_GUI_Delay() Stops execution of simulation thread for the given period.
SIM_GUI_EnableModifierKey() This function let modifier keys (ALT, CTRL) through to emWin.
SIM_GUI_ExecIdle() Called by the simulation on idle time.
SIM_GUI_GetCompositeTouch() Returns the layer index to be passed to emWin if the composite view is touched by the PID.
SIM_GUI_GetTime() Returns the period of time in ms elapsed since starting the simulation.
SIM_GUI_IsModifierKeyEnabled() This function indicates if modifier keys are turned on or not.
SIM_GUI_SaveBMP() Saves a BMP file containing the current layer.
SIM_GUI_SaveBMPEx() Saves a BMP file containing the given section of the current layer.
SIM_GUI_SaveCompositeBMP() Saves a BMP file containing the current content of the composite view.
SIM_GUI_SetCallback() Sets a callback function for receiving the handles of the simulation windows.
SIM_GUI_SetCompositeColor() Sets the background color of the composite window. (Only used with MultiLayer support)
SIM_GUI_SetCompositeSize() Enables composite window mode and sets the size of the composite window. (Only used with MultiLayer support)
SIM_GUI_SetCompositeTouch() Sets the layer index to be used for touch events on the composite view.
SIM_GUI_SetLCDColorBlack() Set the colors to be used as black on color monochrome displays.
SIM_GUI_SetLCDColorWhite() Set the colors to be used as white on color monochrome displays.
SIM_GUI_SetLCDPos() Sets the position for the simulated LCD within the target device bitmap.
SIM_GUI_SetMag() Sets magnification factors for X and/or Y axis.
SIM_GUI_SetTransColor() Sets the color to be used for transparent areas of device or hardkey bitmaps.
SIM_GUI_SetTransMode() Sets the transparency mode for the given layer.
SIM_GUI_ShowDevice() When using multiple layers, this function can be used to show the device bitmap.
SIM_GUI_UseCustomBitmaps() Tells the simulation to use the custom bitmaps from the application resource file.

Data structures

Structure Description
SIM_GUI_INFO Contains the window handles of the simulation.

Defines

Group of defines Description
Transparency modes Available transparency modes for layers.

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

0 on success
1 on error.
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

0 on success
1 on error.
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

0 on success
1 on error.
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()
Before After

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)