Set up GUIDRV Lin
The GUIDRV_Lin driver is likely the simplest emWin driver, yet it is used across a wide range of devices. It can be utilized on any device with a built-in display controller and direct (memory-mapped) access to a frame buffer. Despite its simplicity, the driver can be configured to support hardware acceleration available on certain devices, such as the Dave2D drawing engine or ST's Chrome Art Accelerator.
Objective of this tutorial
This tutorial demonstrates the basic configuration of the GUIDRV_Lin driver. Configuring hardware acceleration is more specialized, so we recommend contacting us for examples on this topic.
Requirements
The GUIDRV_Lin driver primarily manages the content of a memory block, typically used as a frame buffer shared with an on-chip display controller. Initializing a display controller is not part of the GUIDRV_Lin driver and must be performed by the user. Most silicon vendors provide low-level drivers for on-chip display controllers.
Since the GUIDRV_Lin driver can also be used without a display controller, no special hardware is required. It can manage the content of any memory block, making it quite flexible. This flexibility allows it to fill not only a frame buffer but any buffer containing pixel data.
An external RAM is recommend as frame buffer can easily require multiple MB. The size of the frame buffer is calculated as show below:
(XSIZE * YSIZE * bpp + 7) / 8
For example, a frame buffer with 32 bpp and a size of 480 x 272 pixels requires the following amount of bytes:
(480 x 272 x 32 + 7) / 8 = 522240 bytes
If you want to add the multi buffering feature to this configuration please refer to the Multi-Buffering example.
Display controller initialization
Although the GUIDRV_Lin driver doesn't require a display controller, users can still use the driver callback function to initialize one. In the LCD_X_DisplayDriver() function, simply respond to the LCD_X_INITCONTROLLER command and perform the initialization sequence for your display controller.
This might look like this:
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
int r;
GUI_USE_PARA(LayerIndex);
GUI_USE_PARA(pData);
r = 0;
switch (Cmd) {
case LCD_X_INITCONTROLLER:
//
// Call init sequence
//
_InitController();
break;
default:
r = -1;
break;
}
return r;
}
Display driver initialization
The initialization of the GUIDRV_Lin driver is straightforward and requires only a few lines of code. Below is a very basic driver initialization, which consists of:
- Creating a driver device
- Configuring the screen size
- Setting the frame buffer address
void LCD_X_Config(void) {
//
// Set display driver and color conversion for 1st layer
//
GUI_DEVICE_CreateAndLink(GUIDRV_LIN_32, GUICC_M8888I, 0, 0);
//
// Display driver configuration
//
if (LCD_GetSwapXY()) {
LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
LCD_SetVSizeEx(0, YSIZE_PHYS, XSIZE_PHYS);
} else {
LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS);
}
LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR);
}
Creating a driver device
The first step in initializing any emWin driver is creating a driver device. This is accomplished by calling the function GUI_DEVICE_CreateAndLink(). This function binds the driver to a layer and selects the color format.
The parameters for a 32 bpp configuration are:
- Desired driver: GUIDRV_LIN_32
- Desired color format: GUICC_M8888I
- Flags: Should be zero
- LayerIndex: Typically 0
Please refer to the emWin user manual for further GUIDRV_Lin variants (e.g. 16 and 8 bpp) and other color formats.
Ensure that the color format and the chosen GUIDRV_Lin driver variant using the same color depth.
GUI_DEVICE_CreateAndLink(GUIDRV_LIN_32, GUICC_M8888I, 0, 0);
Configuring the screen size
emWin needs to know the size of the screen. To set the display size, use the following functions. The virtual size should be set to the same size as the real size. Depending on whether the x and y axes are swapped, pass the sizes to emWin accordingly.
if (LCD_GetSwapXY()) {
LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
LCD_SetVSizeEx(0, YSIZE_PHYS, XSIZE_PHYS);
} else {
LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS);
}
Setting the frame buffer address
The final step is to pass the frame buffer address to emWin. The frame buffer is typically shared with a display controller, which generates the appropriate display signals based on the frame buffer content.
LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR);
Example LCDConf.c
Below is a very basic example configuration for the GUIDRV_Lin driver. It does not include any controller initialization but should give the user an idea on how to configure the GUIDRV_Lin driver.
#include "GUI.h"
#include "GUIDRV_Lin.h"
/*********************************************************************
*
* Layer configuration (to be modified)
*
**********************************************************************
*/
//
// Physical display size
//
#define XSIZE_PHYS 480
#define YSIZE_PHYS 272
//
// Color conversion
//
#define COLOR_CONVERSION GUICC_M8888I
//
// Display driver
//
#define DISPLAY_DRIVER GUIDRV_LIN_32
/*********************************************************************
*
* Configuration checking
*
**********************************************************************
*/
#ifndef VRAM_ADDR
#define VRAM_ADDR (&_aVRAM[0])
#endif
#ifndef XSIZE_PHYS
#error Physical X size of display is not defined!
#endif
#ifndef YSIZE_PHYS
#error Physical Y size of display is not defined!
#endif
#ifndef COLOR_CONVERSION
#error Color conversion not defined!
#endif
#ifndef DISPLAY_DRIVER
#error No display driver defined!
#endif
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
static U32 _aVRAM[XSIZE_PHYS * YSIZE_PHYS];
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _InitController
*
* Purpose:
* Should initialize the display controller
*/
static void _InitController(void) {
// TBD by customer
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* LCD_X_Config
*
* Purpose:
* Called during the initialization process in order to set up the
* display driver configuration.
*
*/
void LCD_X_Config(void) {
//
// Set display driver and color conversion for 1st layer
//
GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0);
//
// Display driver configuration
//
if (LCD_GetSwapXY()) {
LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
LCD_SetVSizeEx(0, YSIZE_PHYS, XSIZE_PHYS);
} else {
LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS);
}
LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR);
}
/*********************************************************************
*
* LCD_X_DisplayDriver
*
* Purpose:
* This function is called by the display driver for several purposes.
* To support the according task the routine needs to be adapted to
* the display controller. Please note that the commands marked with
* 'optional' are not cogently required and should only be adapted if
* the display controller supports these features.
*
* Parameter:
* LayerIndex - Index of layer to be configured
* Cmd - Please refer to the details in the switch statement below
* pData - Pointer to a LCD_X_DATA structure
*
* Return Value:
* < -1 - Error
* -1 - Command not handled
* 0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
int r;
switch (Cmd) {
//
// Required
//
case LCD_X_INITCONTROLLER: {
_InitController();
return 0;
}
default:
r = -1;
}
return r;
}
/*************************** End of file ****************************/